Win32Shellcodes --------------- Despues de un estudio no demasiado exaustivo sobre posibles alternativas a escanear la imagen del binario en memoria en busca de LoadLibraryA metodo utilizado por virus y utilizado por las Shellcodes de Raise, he sacado varias conclusiones: Como sabreis, en windows, el registro fs en intel esta apuntando siempre a Una estructura que se llama Thread Information Block(TIB), cuya estructura es algo asi: DWORD pvExcept; // 00h Head of exception record list // es un puntero a una estructura de dos miembros DWORD pvStackUserTop; // 04h Top of user stack DWORD pvStackUserBase; // 08h Base of user stack .... .... DWORD pTIB; // 18h puntero hacia el principio de la estrucutra TIB // que es donde apunta fs:[0] .... DWORD pPeb; // 30h puntero hacia el peb .... Mirando esta estructura llegamos a la conclusion de que si hacemos: mov eax, fs:[18h] add eax, 30h Esto ultimo es lo mismo que hacer: mov eax, fs:[30h] tendriamos la direccion donde esta el puntero hacia el Process Environment Block(PEB) en eax :). Esta direccion parece ser fija para win2k y winxp falta por confirmar nt y es: 7FFDF000. En el PEB hay un elemento que nos va a interesar bastante ya que es un puntero a una estructura de tipo tagMODULELISTHEADER. La estructura del PEB es la siguiente: typedef struct { ULONG AllocationSize; // 00h ULONG Unknown1; // 04h HINSTANCE ProcessHinstance; // 08h -> ahi aparece la // direccion base del // ejecutable PVOID ListDlls; 0ch // direccion bastante interesante // que buscamos!! PPROCESS_PARAMETERS ProcessParameters; ULONG Unknown2; HANDLE Heap; } PEB, *PPEB; Comentar que esta direccion tan interesante a la que apunta la variable ListDlls contiene un puntero a una estructura de tipo MODULELISTHEADER. typedef struct tagMODULELISTHEADER { ULONG HeaderSize; // 00h ULONG Unknown[2]; // 04h MODULELISTLINKS LoadOrder; // 0ch MODULELISTLINKS MemOrder; // 10h MODULELISTLINKS InitOrder; // 14h } MODULELISTHEADER, *PMODULELISTHEADER; De esta ultima hay que destacar las de tipo MODULELISTLINKS que contienen entre otras cosas informacion bastante revelante sobre las dll's: - Informacion sobre las dll's cargadas en memoria que son utilizadas por el proceso, a saber: - Imagen base de la dll (direccion base) // <- w0w buscabamos esto jejeje - Punto de entrada a la dll - Tamaño coupado por la libreria en memoria - Localizacion de la libreria ( path, se incluye el nombre de la dll ) - Nombre de la dll // <- encontramos kernel32.dll o ntdll.dll ... Bueno y ahora como no la estructura para poder movernos por esta ultima estructura: typedef struct tagMODULELISTLINKS { PMODULEITEM Next; PMODULEITEM Prev; } MODULELISTLINKS, *PMODULELISTLINKS; typedef struct tagMODULEITEM // offset { MODULELISTLINKS LoadOrder; // 0x00 MODULELISTLINKS MemOrder; // 0x08 MODULELISTLINKS InitOrder; // 0x10 ULONG ImageBase; // 0x18 ULONG EntryPoint; // 0x1C ULONG ImageSize; // 0x20 UNICODE_STRING PathFileName; // 0x24 UNICODE_STRING FileName; // 0x2C ULONG ModuleFlags; // 0x34 SHORT LoadCount; // 0x38 WORD Fill; // 0x3A ULONG Unknown1; // 0x3C ULONG Unknown2; // 0x40 ULONG TimeDateStamp; // 0x44 } MODULEITEM, *PMODULEITEM; // 0x48 bytes Esto se puede saltar y ver el codigo fuente que viene despues de esto.... Ahora para comprobar todo esto cogemos nuestro win2k, winxp y... (yo he utilizado el ollydgb) 1) Cogemos y atacheamos cualquier proceso y nos vamos al fs( con el el ollydbg solo hay que irte a view->memory, seleccionas el segmento de datos (del proceso o del thread) y a continuacion boton derecho y se selecciona dump o sino te vas a view->cpu ampliais la ventana y mirais el valor del fs). En mi caso obtengo los siguientes valores: El fs esta en 7ffde000 Y antes he dicho que se podia sacar asi: mov eax, fs:[18] 2) Ahora le sumamos 30h y ahi tenemos un puntero a la direccion donde esta el PEB. 7ffde030 -> 7ffdf000 // esta direccion a la que apunta 7ffde030 // suele ser fija para todos los windows de // la familia nt. ( solo falta por comprobar // winnt 4.0 ) 2) Nos vamos al PEB y le sumamos un offset de 0ch. 7ffdf00c -> 00131ea0 // en 00131ea0 tenemos una estrucutra del tipo // MODULELISTHEADER 3) Cojo y me voy a 0ch de 131ea0 por lo que estaria en: MODULELISTLINKS LoadOrder; // a 0ch de module listheader si me voy a la direccion q apunta LoadOrder ahora estaria en 131eac. 4) Ahora me voy a la siguiente estructura: PMODULEITEM Next; // offset 0 :) <- esto estaria en 131ea0 que Next // apuntaria a la siguiente.... 131eac -> 131ee0 // en 131ee0 tenemos una estructura de tipo PMODULEITEM 5) en esta primera estrucutra nos mostraria informacion sobre el proceso en cuestion. Nos vamos a la siguiente: 131ee0 -> 131f70 // 131f70 otra estructura de tipo PMODULEITEM Estariamos en la informacion referente a ntdll.dll Por lo que nos vamos a la siguiente. 131f70 -> 132198 // esto seria de user32.dll Nos vamos a la siguiente 132198 -> 132278 // en 132198 parece que hemos encontrado algo... wow es // la estructura PMODULEITEM de kernel32.dll --------------------------------- inicio ejemplo.cpp -------------------- // ESTO ES PARA VISUAL C++ #include #include void main(void){ DWORD ImagenKERNEL; __asm{ mov eax, fs:[30h] mov eax, [eax+0ch] add eax, 0ch // en eax tengo direccion correcta mov eax, [eax] bucle: mov ebx, [eax] // en ebx tengo direccion de next add eax, 30h // nombre de la dll en unicode mov ecx, 00320033h mov edx, [eax] cmp [edx+0ch], ecx jne bucle1 mov ecx, 0064002Eh cmp [edx+10h], ecx jne bucle1 sub eax, 30h add eax, 18h mov eax, [eax] jmp imagen bucle1: mov eax, ebx jmp bucle imagen: mov [ImagenKERNEL], eax } printf("La imagen base de kernel32.dll es: %8X", ImagenKERNEL); } ------------------------------- fin ejemplo.c-------------------------- Prueba de que funciona: ******************************************************************************** C:\DEVELO~1\pruebas>cl ejemplo.cpp Microsoft (R) 32-bit C/C++ Standard Compiler Version 12.00.8168 for 80x86 Copyright (C) Microsoft Corp 1984-1998. All rights reserved. ejemplo.cpp Microsoft (R) Incremental Linker Version 6.00.8168 Copyright (C) Microsoft Corp 1992-1998. All rights reserved. /out:ejemplo.exe ejemplo.obj C:\DEVELO~1\pruebas>ejemplo La imagen base de kernel32.dll es: 77E80000 ******************************************************************************** Bueno y muchos direis..... bufff cuanto nulo.... etc etc... ya se hara una shellcode en condiciones :). Todo tiene arreglo, ya me lo currare o se lo currará alguien... jeje Todo esto se puede optimizar bastante, yo hasta ahora lo que he hecho en vez de optimizar ha sido agrandar xDDD. ------ NOTA: ------ Una vez estaba en la direccion a la que apunta "FileName" de la estructura tagMODULEITEM, en win2k era el unicode en mayusculas hasta el ".dll", es decir, en win2k era asi: "KERNEL32.dll" y en xp era en minusculas: "kernel32.dll". Comento esto pq para buscar la direccion base de kernel32.dll he buscado la cadena "32.d", algunos direis y si hay alguna libreria que sea del tipo "??????32.d??" y yo os contesto que da igual pq kernel32.dll se cargara siempre antes que cualquier otra dll con esa mascara y como estamos buscando por el orden de carga... (MODULELISTLINKS LoadOrder). Ahora que tenemos la direccion de kernel32.dll buscamos getprocaddress. P.D: Si alguien ya conocia este metodo pq no lo ha utilizado es el que utilizan los debuggers para sacar las dlls cargadas en memoria por un proceso. P.D2: Dentro de poco shellcode xDDD. P.D3: que no corra la voz xD. Murcia, 29 Mayo 2002 -- KoX -- kekabron --.