elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Introducción a Git (Primera Parte)


+  Foro de elhacker.net
|-+  Seguridad Informática
| |-+  Análisis y Diseño de Malware (Moderador: fary)
| | |-+  [C++] Inyección de código en memoria- Aplicación crashea
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] 2 Ir Abajo Respuesta Imprimir
Autor Tema: [C++] Inyección de código en memoria- Aplicación crashea  (Leído 8,107 veces)
Kaxperday


Desconectado Desconectado

Mensajes: 702


The man in the Middle


Ver Perfil WWW
[C++] Inyección de código en memoria- Aplicación crashea
« en: 6 Abril 2016, 18:58 pm »

Hola buenas, hace pocos días estuve leyendo sobre el API hooking y de allí salté a la inyección de DLL, y más adelante pasé a la inyección de código, y ayudándome con un código que encontré en rohitab fuí dando forma a mi código y puse control de errores. Este es el link por si a alguien le interesa, me fue muy útil:

http://www.rohitab.com/discuss/topic/39357-code-cave-injection-tutorial-c/

El programa inyecta un MessageBox en la aplicación objetivo, tras salir el MessageBox y pulsar aceptar se cierra la aplicación objetivo. Desconozco el porqué, os dejo el código a ver si me podéis ayudar a saber:

Código
  1. #pragma once
  2. #include <windows.h>
  3. #include <shlobj.h>
  4. #include <wininet.h>
  5. #include <tlhelp32.h>
  6. #include <shlwapi.h>
  7.  
  8. typedef int (WINAPI* MsgBoxParam)(HWND, LPCSTR, LPCSTR, UINT);
  9. using namespace std;
  10.  
  11. struct PARAMETERS{
  12. DWORD MessageBoxInj;
  13. char text[50];
  14. char caption[25];
  15. int buttons;
  16. //HWND handle;
  17. };
  18.  
  19. DWORD GetPIDFromProcName(LPCWSTR procName);
  20. DWORD MyFunc(PARAMETERS * myparam);
  21. DWORD Useless();
  22. bool Injecter();
  23.  
  24. DWORD GetPIDFromProcName(LPCWSTR procName)
  25. {
  26. PROCESSENTRY32 pe;
  27. HANDLE thSnapShot;
  28. BOOL retval;
  29.  
  30. thSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  31.  
  32. if (thSnapShot == INVALID_HANDLE_VALUE)
  33. {
  34. return 0;
  35. }
  36.  
  37. pe.dwSize = sizeof(PROCESSENTRY32);
  38.  
  39. retval = Process32First(thSnapShot, &pe);
  40.  
  41. while (retval)
  42. {
  43. if (!lstrcmp(pe.szExeFile, procName))
  44. {
  45. return pe.th32ProcessID;
  46. }
  47. retval = Process32Next(thSnapShot, &pe);
  48. }
  49.  
  50. return 0;
  51. }
  52.  
  53. static DWORD MyFunc(PARAMETERS * myparam){
  54. MsgBoxParam MsgBox = (MsgBoxParam)myparam->MessageBoxInj;
  55. int result = MsgBox(0, myparam->text, myparam->caption, myparam->buttons);
  56. switch (result){
  57. case IDOK:
  58.                //code
  59. break;
  60. case IDCANCEL:
  61. //code
  62. break;
  63. }
  64. return 0;
  65. }
  66.  
  67. static DWORD useless(){
  68. return 0;
  69. }
  70.  
  71. //debe ser static para que el compilador las ponga juntas y calcule bien el tamaño :)
  72. bool Injecter()
  73. {
  74.  
  75. HANDLE proc = NULL;
  76. DWORD pID = NULL;
  77.  
  78. if ((pID = GetPIDFromProcName(L"chrome.exe")) == NULL)// no GetTargetThreadIDFromProcName ^^
  79. {
  80. return false;
  81. }
  82.  
  83. if ((proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID)) == NULL)
  84. {
  85. return false;
  86. }
  87.  
  88. char * mytext = "Hello by CodeCave!";
  89. char * mycaption = "Injection result";
  90.  
  91. PARAMETERS data;   //let's fill in a PARAMETERS struct
  92.  
  93. HINSTANCE hUserModule = LoadLibraryA("user32.dll");
  94.  
  95. if (hUserModule == NULL)
  96. {
  97. CloseHandle(proc);
  98. return false;
  99. }
  100.  
  101. data.MessageBoxInj = (DWORD)GetProcAddress(hUserModule, "MessageBoxA");
  102. strcpy(data.text, mytext);
  103. strcpy(data.caption, mycaption);
  104. data.buttons = MB_OKCANCEL | MB_ICONQUESTION;
  105.  
  106. DWORD_PTR size_myFunc = (DWORD_PTR)((LPBYTE)useless - (LPBYTE)MyFunc);
  107.  
  108. LPVOID MyFuncAddress = NULL;
  109.  
  110. if ((MyFuncAddress = VirtualAllocEx(proc, NULL, size_myFunc, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE)) == NULL)
  111. {
  112. CloseHandle(proc);
  113. return false;
  114. }
  115.  
  116. if (WriteProcessMemory(proc, MyFuncAddress, (LPVOID)MyFunc, size_myFunc, NULL) == NULL)
  117. {
  118. VirtualFree(MyFuncAddress, 0, MEM_RELEASE);
  119. CloseHandle(proc);
  120. return false;
  121. }
  122.  
  123. LPVOID DataAddress = NULL;
  124.  
  125. if ((DataAddress = VirtualAllocEx(proc, NULL, sizeof(PARAMETERS), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE)) == NULL)
  126. {
  127. CloseHandle(proc);
  128. return false;
  129. }
  130.  
  131. if (WriteProcessMemory(proc, DataAddress, (LPVOID)&data, sizeof(PARAMETERS), NULL) == NULL)
  132. {
  133. VirtualFree(MyFuncAddress, 0, MEM_RELEASE);
  134. VirtualFree(DataAddress, 0, MEM_RELEASE);
  135. CloseHandle(proc);
  136. return false;
  137. }
  138.  
  139. HANDLE thread = NULL;
  140.  
  141. if ((thread = CreateRemoteThread(proc, NULL, 0, (LPTHREAD_START_ROUTINE)MyFuncAddress, DataAddress, 0, NULL)) == NULL)
  142. {
  143. VirtualFree(MyFuncAddress, 0, MEM_RELEASE);
  144. VirtualFree(DataAddress, 0, MEM_RELEASE);
  145. CloseHandle(proc);
  146. return false;
  147. }
  148.  
  149. WaitForSingleObject(thread, INFINITE);
  150. VirtualFree(MyFuncAddress, 0, MEM_RELEASE);
  151. VirtualFree(DataAddress, 0, MEM_RELEASE);
  152. CloseHandle(thread);
  153. CloseHandle(proc);
  154. cout << "Injection completed!" << endl;
  155.  
  156. return true;
  157. }
  158.  
  159.  

Al ejecutar el programa ejecuta todo sin errore y muestra "Injection completed!", pero al cerrar el MessageBox que invoco el la aplicación a la que inyecto esta se me cierra también.

Creo que se debe al calculo del tamaño de la función a inyectar, quizás dependiendo de un compilador pueda variar el resultado.

Saludos y gracias.
« Última modificación: 7 Abril 2016, 12:58 pm por Kaxperday » En línea

Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.
fary
Moderador
***
Desconectado Desconectado

Mensajes: 1.076



Ver Perfil WWW
Re: [C++] Inyección de código en memoria- Aplicación crashea
« Respuesta #1 en: 7 Abril 2016, 11:15 am »

¿GetTargetThreadIDFromProcName?

¿Podrías poner el código completo e indicar que compilador estas usando?

saludos.
« Última modificación: 7 Abril 2016, 11:21 am por fary » En línea

Un byte a la izquierda.
Kaxperday


Desconectado Desconectado

Mensajes: 702


The man in the Middle


Ver Perfil WWW
Re: [C++] Inyección de código en memoria- Aplicación crashea
« Respuesta #2 en: 7 Abril 2016, 12:39 pm »

¿GetTargetThreadIDFromProcName?

¿Podrías poner el código completo e indicar que compilador estas usando?

saludos.

Hola fary, gracias por la respuesta.

GetTargetThreadIDFromProcName es GetPIDFromProcName que lo cambié el nombre para que fuera más sencillo, eso ha sido un fallo de edición, es simplemente una función que devuelve el PID de un proceso que le pasas como argumento. Es GetPIDFromProcName vamos XD.

El caso es el compilador y que no se como usar el debugger para pillar las direcciones de las funciones y en qué puede ayudarme a pesar de que he estado buscando sobre ello.

Uso visual studio 2013 (v120). El compilador es derivado de g++ es propio de VS.  Calculo el tamaño de la función con delimitandola con otra función static, pero ese método inestable para calcular el tamaño de la función dependiendo del compilador. Es probable que el mismo código funcione en codeblocks sin problemas. Pero en caso de ser eso lo que falle, ¿como puedo arreglarlo?, ¿dónde debería de inspeccionar?.

Seguiré probando más adelante con la versión release y otros compiladores, pero tengo que hacerlo con el de VS.

Un saludo.

Edito: Buenas acabo de probar el código en codeblocks y funciona sin problemas, codeblocks usa g++ y para C gcc si no mal recuerdo.  Luego no es problema del código, es del compilador.
« Última modificación: 7 Abril 2016, 13:00 pm por Kaxperday » En línea

Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.
fary
Moderador
***
Desconectado Desconectado

Mensajes: 1.076



Ver Perfil WWW
Re: [C++] Inyección de código en memoria- Aplicación crashea
« Respuesta #3 en: 7 Abril 2016, 13:40 pm »

Me alegro de que hallas podido solucionar el problema.

En este caso podrías haber mirado lo que sucedia abriendo el ejecutable en cuestion en el que se va a inyectar el código con OllyDbg y poniendo en BP en la API MessageBoxA. Al inyectar el código se te pararía el programa y podrías ver donde esta el error.

saludos.
En línea

Un byte a la izquierda.
Kaxperday


Desconectado Desconectado

Mensajes: 702


The man in the Middle


Ver Perfil WWW
Re: [C++] Inyección de código en memoria- Aplicación crashea
« Respuesta #4 en: 7 Abril 2016, 17:26 pm »

Bueno solucionado todavía no está, aunque si he confirmado que el problema tiene que ver con el compilador como suponía, luego el código está bien.

Ahora, creo que se puede solucionar de las siguientes maneras:

- Cargando el código a inyectar ya compilado en una variable e inyectar desde ella (no  me acaba de gustar, pero ahí esta).

- Cambiando de compilador, el compilador de visual studio creo que ofusca el código y es por eso que falla, con otro funcionaría. Pero aún así no se podrian usar crypters ni nada por el estilo con el ejecutable, ya que al acceder al código a inyectar si esta ofuscado no funcionaría (aunque dependería del crypter algunos si), y eso es buena **.

- Como tú dices abriendo el ejecutable con el ollydbg, pero si por cada vez que lo vuelvo a compilar o cada cambio que añado tengo que estar haciendo eso para que funcione y buscando las direcciones de memoria y tal, tampoco me parece un buen método, pero es lo que más me convence aunque ahora mismo no sabría como hacerlo.

El problema de la inyección de código es: ¿es compatible con crypters?.

Luego me pondré a mirar como va eso del ollydbg a ver si encuentro algo X"D

Saludos!.
En línea

Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.
fary
Moderador
***
Desconectado Desconectado

Mensajes: 1.076



Ver Perfil WWW
Re: [C++] Inyección de código en memoria- Aplicación crashea
« Respuesta #5 en: 7 Abril 2016, 21:12 pm »

Aqui tienes un código de ejemplo en C funcional.

https://foro.elhacker.net/net/inyeccion_dll_sin_dll_by_e0n_problema_edicion_de_memoria_convertir_a_c-t267355.0.html

Se puede inyectar código que tengas almacenado en una variable, sí, eso se llama Shellcode.

Con lo de los cripters te refieres si se puede cifrar el exe que inyecta?
En línea

Un byte a la izquierda.
pinkiepie

Desconectado Desconectado

Mensajes: 2


Ver Perfil
Re: [C++] Inyección de código en memoria- Aplicación crashea
« Respuesta #6 en: 8 Abril 2016, 00:38 am »

No se trata del compilador exactamente, sino de características del código compilado (el compilador añade cosas caprichosamente que se pueden desactivar/remover [?]).

Deberías revisar las instrucciones de la función a inyectar mediante IDA o algún debugger. Lo más probable es que encuentres al menos un CALL a una dirección de memoria, situado posteriormente al MessageBoxA, "perteneciente" al 'inyector' y no a chrome.exe.

La función a la que intenta llamar el thread corresponde a _RTC_CheckEsp (al menos en VS2015). Pertenece a un conjunto de funciones que agrega el compilador para reportar errores en run-time, y se encuentra dentro del mismo ejecutable compilado.

Te recomiendo visitar este enlace para que conozcas con más detalle sobre lo que es RTC (Run-Time Error Checking) y cómo desactivarlo: https://msdn.microsoft.com/en-us/library/8wtf2dfz.aspx
En línea

burbu_1

Desconectado Desconectado

Mensajes: 159


hamen gaoz


Ver Perfil
Re: [C++] Inyección de código en memoria- Aplicación crashea
« Respuesta #7 en: 8 Abril 2016, 18:08 pm »

Culpar al compilador de que tu código falle me parece muy chulito......


ésos son códigos.......


has probado a reservar memoria como hace él/ella????
En línea

fary
Moderador
***
Desconectado Desconectado

Mensajes: 1.076



Ver Perfil WWW
Re: [C++] Inyección de código en memoria- Aplicación crashea
« Respuesta #8 en: 8 Abril 2016, 19:21 pm »

Culpar al compilador de que tu código falle me parece muy chulito......

ésos son códigos.......


has probado a reservar memoria como hace él/ella????

 :huh: no entiendo tu post :s

Lo más fácil y mejor es que suba el ejecutable que genera y lo revisamos desde un debugger...

Saludos!!
En línea

Un byte a la izquierda.
pinkiepie

Desconectado Desconectado

Mensajes: 2


Ver Perfil
Re: [C++] Inyección de código en memoria- Aplicación crashea
« Respuesta #9 en: 8 Abril 2016, 19:53 pm »

Pues yo insisto en que el problema son las verificaciones run-time que agrega VS a las funciones.

Quité Run-Time Error Checking en las opciones del proyecto, compilé el programa (con VS2015), y no hubieron más crashes.

Función inyectada con RTC activado:

Código
  1. 023C0000   55               PUSH EBP
  2. 023C0001   8BEC             MOV EBP,ESP
  3. 023C0003   81EC DC000000    SUB ESP,0DC
  4. 023C0009   53               PUSH EBX
  5. 023C000A   56               PUSH ESI
  6. 023C000B   57               PUSH EDI
  7. 023C000C   8DBD 24FFFFFF    LEA EDI,DWORD PTR SS:[EBP-DC]
  8. 023C0012   B9 37000000      MOV ECX,37
  9. 023C0017   B8 CCCCCCCC      MOV EAX,CCCCCCCC
  10. 023C001C   F3:AB            REP STOS DWORD PTR ES:[EDI]
  11. 023C001E   8B45 08          MOV EAX,DWORD PTR SS:[EBP+8]
  12. 023C0021   8B08             MOV ECX,DWORD PTR DS:[EAX]
  13. 023C0023   894D F8          MOV DWORD PTR SS:[EBP-8],ECX
  14. 023C0026   8BF4             MOV ESI,ESP
  15. 023C0028   8B45 08          MOV EAX,DWORD PTR SS:[EBP+8]
  16. 023C002B   8B48 50          MOV ECX,DWORD PTR DS:[EAX+50]
  17. 023C002E   51               PUSH ECX
  18. 023C002F   8B55 08          MOV EDX,DWORD PTR SS:[EBP+8]
  19. 023C0032   83C2 36          ADD EDX,36
  20. 023C0035   52               PUSH EDX
  21. 023C0036   8B45 08          MOV EAX,DWORD PTR SS:[EBP+8]
  22. 023C0039   83C0 04          ADD EAX,4
  23. 023C003C   50               PUSH EAX
  24. 023C003D   6A 00            PUSH 0
  25. 023C003F   FF55 F8          CALL DWORD PTR SS:[EBP-8]
  26. 023C0042   3BF4             CMP ESI,ESP
  27. 023C0044   E8 09E6FFFF      CALL 023BE652                            ; _RTC_CheckEsp
  28. 023C0049   8945 EC          MOV DWORD PTR SS:[EBP-14],EAX
  29. 023C004C   8B45 EC          MOV EAX,DWORD PTR SS:[EBP-14]
  30. 023C004F   8985 24FFFFFF    MOV DWORD PTR SS:[EBP-DC],EAX
  31. 023C0055   33C0             XOR EAX,EAX
  32. 023C0057   5F               POP EDI
  33. 023C0058   5E               POP ESI
  34. 023C0059   5B               POP EBX
  35. 023C005A   81C4 DC000000    ADD ESP,0DC
  36. 023C0060   3BEC             CMP EBP,ESP
  37. 023C0062   E8 EBE5FFFF      CALL 023BE652                            ; _RTC_CheckEsp
  38. 023C0067   8BE5             MOV ESP,EBP
  39. 023C0069   5D               POP EBP
  40. 023C006A   C3               RETN
  41.  

Función inyectada sin RTC:

Código
  1. 023A0000   55               PUSH EBP
  2. 023A0001   8BEC             MOV EBP,ESP
  3. 023A0003   83EC 4C          SUB ESP,4C
  4. 023A0006   53               PUSH EBX
  5. 023A0007   56               PUSH ESI
  6. 023A0008   57               PUSH EDI
  7. 023A0009   8B45 08          MOV EAX,DWORD PTR SS:[EBP+8]
  8. 023A000C   8B08             MOV ECX,DWORD PTR DS:[EAX]
  9. 023A000E   894D FC          MOV DWORD PTR SS:[EBP-4],ECX
  10. 023A0011   8B45 08          MOV EAX,DWORD PTR SS:[EBP+8]
  11. 023A0014   8B48 50          MOV ECX,DWORD PTR DS:[EAX+50]
  12. 023A0017   51               PUSH ECX
  13. 023A0018   8B55 08          MOV EDX,DWORD PTR SS:[EBP+8]
  14. 023A001B   83C2 36          ADD EDX,36
  15. 023A001E   52               PUSH EDX
  16. 023A001F   8B45 08          MOV EAX,DWORD PTR SS:[EBP+8]
  17. 023A0022   83C0 04          ADD EAX,4
  18. 023A0025   50               PUSH EAX
  19. 023A0026   6A 00            PUSH 0
  20. 023A0028   FF55 FC          CALL DWORD PTR SS:[EBP-4]
  21. 023A002B   8945 F8          MOV DWORD PTR SS:[EBP-8],EAX
  22. 023A002E   8B45 F8          MOV EAX,DWORD PTR SS:[EBP-8]
  23. 023A0031   8945 B4          MOV DWORD PTR SS:[EBP-4C],EAX
  24. 023A0034   33C0             XOR EAX,EAX
  25. 023A0036   5F               POP EDI
  26. 023A0037   5E               POP ESI
  27. 023A0038   5B               POP EBX
  28. 023A0039   8BE5             MOV ESP,EBP
  29. 023A003B   5D               POP EBP
  30. 023A003C   C3               RETN
  31.  
En línea

Páginas: [1] 2 Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines