Texto sobre las shellcodes Win32 que va un paso mas alla de los trabajos de RaiSe de Netsearch.
Esta bastante interesante el texto, pero no hay scode de prueba, solo como hacerla (por eso es mas interesante).
Alguien se pone a hacer una usando este texto?
Weno, que lo disfruteis

PD: Lo pongo bajo las etiquetas CODE para que no salgan smileys
---------------------------------------------
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 <stdio.h>
#include <windows.h>
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 --.