Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - [Zero]

#541
Abril negro / Re: Proyecto Metamorph
30 Agosto 2009, 18:04 PM
Gracias karmany, luego de mucho intentarlo y de preguntas al gran Shaddy ( :xD) ya no tengo problemas, la v2 ya tiene para añadir secciones, añadir espacio a cualquier sección y más cosas sobre el PE. Me despistaron dos cosas, por eso no lo conseguía, uno lo que tu dices, que si no es la última sección tienes de límite el VirtualSize, ya que si agrandas más, la diferencia no se mapea en memoria. Lo otro fue que los compiladores suelen redondear alto el tamaño en disco de las secciones y luego ponen el VirtualSize más ajustando, quedando más pequeño que el SizeOfRawData, y eso me despistó bastante, pero ya por fin lo comprendí  ;D.

Ahora lo que más me quema es la IAT, tengo un código a medias para moverla, cambiar el orden de las entradas y reconstruírla con loader y sin loader, pero a medias, aún no conseguí terminarlo  :P.

Saludos y gracias
#542
TvuPlayer es una buena opción  :P.

Saludos
#543
Y debes usar el BBCode para que se vea la imagen:

[img]www.danasoft.com/sig/Sarai7.jpg[/img]

Saludos
#544
Puedes usarlo desde windows, linux o cualquier SO al que dé soporte al lenguaje, solo tienes que bajarte python y luego arrancas el script.

Saludos
#545
Supongo que su utilidad, mas que el espionaje es el control, por ejemplo en una empresa, de los empleados. Y aunque ese no lo tiene y no se si hay alguno que lo tenga, también se podría hacer que deshabilitara ciertas teclas y eso  :P.

Saludos
#546
Actualicé el post, ahora ejecuta cualquier archivo tenga o no Relocation Table (salvo ejecutables en VB  :¬¬).

Saludos
#547
Lo de reloc está solucionado virtualmente, falta el código jeje. Pronto actualizo con el código que soluciona ese problema y a ver si hago un crypter de muestra (el builder ya lo tengo de una vez asíque...  :xD).

Saludos y gracias por la chincheta  :xD

Edito: Bueno, lo intenté con ésto, pero al parecer no fue buena idea, pensaré en otra cosa  :-\.
#548
Ejecución de Archivos desde Memoria - Base Relocation

Bueno, hago éste texto para explicar un poco en que consiste el método y a la vez para que no haya gente que se limite a copiar el código sin más. Todo lo que voy a decir está basado en lo siguiente, el cual será necesario leer antes de éste texto para comprender bien el código.

http://www.joachim-bauch.de/tutorials/load_dll_memory.html

A la vez, para comprender todo lo que diré, será necesario tener conocimientos sobre el formato PE, y el único texto que encontré que habla un poco de la Base Relocation es el de microsoft:

http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/pecoff_v8.docx



El Problema

Vale, imaginémonos que estamos programando un crypter. El stub del crypter, al ser ejecutado, descifra el archivo en memoria, y llegamos al momento, en que tenemos el archivo que habíamos cifrado, descifrado y mapeado en memoria, pero no podemos ejecutarlo, puesto no está cargado en su ImageBase, y por lo tanto, todas las instrucciones relativas al ImageBase saltarán a un punto que vete tu a saber que hay. Entre éstas instrucciónes, están las llamadas a las API's (llamadas a punteros de la IAT), y al haberse mapeado y no cargado, la IAT no se cargó con las direcciones de las API's, otro problema  :-\.

El Loader de Windows

Para entender lo que vamos a hacer, vamos a ver antes que es lo que hace windows para ejecutar un archivo cuando nosotros se lo indicamos:

  • Lee el archivo y busca la cabecera DOS, la cabecera PE y las cabeceras de las secciones.
  • Intenta reservar espacio en memoria en la dirección del ImageBase, y si ya está en uso, la reserva en otra dirección. La cantidad de memoria que reserva está marcado por el SizeOfImage.
  • Mapea las distintas secciones de acuerdo con su VirtualOffset y VirtualSize y los Flags.
  • Si el archivo no está cargado en su ImageBase, hace una reubicación de la base del ejecutable.
  • Recorre la Import Table y carga las librerías que importa en ejecutable.
  • Rellena la IAT con las direcciones de las funciones que importa.
  • Crea el hilo inicial de ejecución y lanza el proceso.
La Solución

Si emulamos el Loader de Windows a base de código, podemos arrancar el ejecutable desde memoria sin necesidad de guardarlo en disco y ejecutarlo o tener que crear otro proceso para tener el ImageBase origianal libre.

Aquí pongo el código que hice, y subo el proyecto. El archivo lleva en el resource un ejecutable que emite un messagebox. Al arrancar el archivo, la sección de resource se mapea en memoria con todo el ejecutable, y emulando el loader de windows, carga el archivo reubicando la ImageBase y pasandole la ejecución a éste  ;-). Comenté mucho el código para que no haya problemas de comprensión, pero es necesario tener muy claro el formato PE  :P.


//-------------------------------------------------------------------------------------------
// PoC - [Base Relocation]
//
//Descripción: Ejecuta un archivo mapeado en memoria sin guardarlo en disco
//Autor: Hacker_Zero
//Fecha: 18-8-2009
//Basado en: http://www.joachim-bauch.de/tutorials/load_dll_memory.html
//-------------------------------------------------------------------------------------------

#pragma optimize("gsy", on)
#pragma comment(linker, "/ENTRY:main")

#include <windows.h>
#include "resource.h"

void main()
{
//Cargamos ejecutable del resource
HRSRC hResource=FindResourceA(NULL,(LPCSTR)MAKEINTRESOURCE(IDR_EXE1),"EXE");
HGLOBAL hGlob=LoadResource(NULL,hResource);
DWORD FileSize=SizeofResource(NULL,hResource);
LPSTR lpFileMaped=(LPSTR)LockResource(hGlob);

PIMAGE_DOS_HEADER IDH;
PIMAGE_NT_HEADERS INTH;
PIMAGE_SECTION_HEADER ISH;

//Obtenemos la cabecera DOS y PE en las estructuras
IDH=(PIMAGE_DOS_HEADER)&lpFileMaped[0];
INTH=(PIMAGE_NT_HEADERS)&lpFileMaped[IDH->e_lfanew];

//Creamos el buffer del tamaño del SizeOfImage en el que cargaremos el ejecutable
LPSTR ExeBuffer=(LPSTR)VirtualAlloc(NULL,INTH->OptionalHeader.SizeOfImage,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
//LPSTR ExeBuffer=(LPSTR)GlobalAlloc(GPTR,INTH->OptionalHeader.SizeOfImage);

//Copiamos la cabecera DOS y PE al buffer
CopyMemory(&ExeBuffer[0],&lpFileMaped[0],INTH->OptionalHeader.SizeOfHeaders);

//Copiamos las secciones en su VirtualOffset en el buffer
for(DWORD i=0;i<INTH->FileHeader.NumberOfSections;i++)
{
ISH=(PIMAGE_SECTION_HEADER)&lpFileMaped[IDH->e_lfanew+sizeof(IMAGE_NT_HEADERS)+sizeof(IMAGE_SECTION_HEADER)*i];
CopyMemory(&ExeBuffer[ISH->VirtualAddress],&lpFileMaped[ISH->PointerToRawData],ISH->SizeOfRawData);
}

//Calculamos el delta entre la dirección del buffer y el ImageBase
DWORD Delta=(((DWORD)ExeBuffer)-INTH->OptionalHeader.ImageBase);

//------------------------------------------------------------
/* -Reubicamos la dirección base del ejecutable :D- */
//------------------------------------------------------------

//Si no hay tabla de reubicación, salimos
if(INTH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size==0)
{
MessageBoxA(0,"No se ha encontrado Tabla de Reubicaciones\nImposible cargar el archivo",0,0);
ExitProcess(0);
}

//Obteemos el Image Base Relocation
PIMAGE_BASE_RELOCATION IBR=(PIMAGE_BASE_RELOCATION)(ExeBuffer+INTH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);

//Vamos recorriendo todas las etradas del bloque
for (;IBR->VirtualAddress>0; )
{
//Obtenemos el Bloque de reubicación
LPSTR RelocationBlock=(LPSTR)(ExeBuffer+IBR->VirtualAddress);

//Obtenemos la primera entrada del bloque
LPWORD RelocationEntry=(LPWORD)((LPSTR)IBR+sizeof(IMAGE_BASE_RELOCATION));

//Recorremos todas las entradas del bloque
for (DWORD i=0;i<((IBR->SizeOfBlock-sizeof(IMAGE_BASE_RELOCATION))/2);i++,RelocationEntry++)
{
//Obtenemos los 4 bits que definen el tipo de reubicación
DWORD type=*RelocationEntry>>12;

//Obtenemos los 12 bits que definen la dirección de la reubicación
DWORD offset=*RelocationEntry&0xfff;

//Si el tipo de reubicación es relativo a la dirección base, añadimso el delta
switch (type)
{
case IMAGE_REL_BASED_HIGHLOW:
//Añadimos a la dirección que depende del imagebase original
//el delta entre el imagebase y nuestra dirección base
LPDWORD newAddr=(LPDWORD)(RelocationBlock+offset);
*newAddr=Delta+(DWORD)*newAddr;
break;
}
}
//Vamos al siguiente bloque
IBR = (PIMAGE_BASE_RELOCATION)(((DWORD)IBR) + IBR->SizeOfBlock);
}


//---------------------------------------------------------------------
/* -Cargamos los valores de la IAT para poder llamar a las apis- */
//---------------------------------------------------------------------

PIMAGE_THUNK_DATA ITD;
PIMAGE_IMPORT_BY_NAME IIBN;

//Comprobamos si hay Import Data Descriptor
if (INTH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size>0)
{
//Si lo hay lo obtenemos en la estructura
PIMAGE_IMPORT_DESCRIPTOR IID=(PIMAGE_IMPORT_DESCRIPTOR)(ExeBuffer+INTH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);

//Vamos recorriendo todas las Dll's importadas por el ejecutable
for (;IID->Name;IID++)
{
//Cargamos la dll
HMODULE hLib=LoadLibraryA((LPCSTR)(ExeBuffer+IID->Name));

//Obtenemos la dirección al primer miembro del array Image Thunk Data's
ITD=(PIMAGE_THUNK_DATA)((DWORD)ExeBuffer+IID->FirstThunk);

//Vamos recorriendo las funciones importadas
for (;ITD->u1.Ordinal;ITD++)
{
//Cargamos el Image Import By Name para obtener el nombre
IIBN=(PIMAGE_IMPORT_BY_NAME)(ExeBuffer+ITD->u1.Function);
//Obtenemos la dirección de la función y la guardamos en la IAT
ITD->u1.Function=(DWORD)GetProcAddress(hLib,(LPCSTR)&IIBN->Name);
}
}
}

//Obteemos el EntryPoint de ejecutable que cargamos en el buffer
DWORD EntryPoint=((DWORD)ExeBuffer)+INTH->OptionalHeader.AddressOfEntryPoint;

//Llamamos al EntryPoint
__asm
{
mov eax,EntryPoint
call eax
}

ExitProcess(0);
}




# Cabe destacar que para que el archivo pueda ser ejecutado en un ImageBase distinto al original, es necesario que el archivo tenga tabla de reubicación, el VC++ 2008 la pone en los ejecutables por defecto, y en Fasm se puede añadir con la siguiente línea:

section '.reloc' fixups data discardable

En VB no se si se pude poner, al menos no lo hace por defecto  :P.





# Los antivirus suelen Hookear las API's de manejo de memoria en un proceso remoto, por eso, la mayoría de crypters que usan API's como WriteProcessMemory o CreateRemoteThread son detectados por las heurísticas. Con éste método se evita tener que llamar a esas API's, por lo que (no lo probé) debería de poder saltarse las heurísticas  ;-).





# Pronto actualizaré el post con un código que solucionará el problema de que el archivo deba tener tabla de reubicaciones  ;D.



Descargar proyecto de ejemplo







Ejecutar archivos sin Relocation Table

Bueno, pues terminé el código que ejecuta archivos desde memoria aunque éstos no tengan Relocation Table. Tiene un pequeño fallo, y es que con ejecutables en VB crashea debido a que hay algo raro en el import table, no sé muy bien aún a que se debe pero se puede solucionar.

Lo que hace el código es ejecutar un Loader que tiene Relocation Table desde una posición de memoria diferente a su ImageBase. El loader ejecuta el archivo que queremos inyectar desde memoria librerando memoria en el ImageBase original (00400000, desde donde habíamos llamado al loader) y carga ahí el ejecutable, por lo que no es necesario reubicar la ImageBase y funciona  ;D.


Descargar Código Fuente

Saludos


#549
Buenísimo, no se me habría ocurrido, bien pensado  ;-).

Saludos
#550
Hombre, si encriptas todo el server lo más probable es que si, salvo que pase algo raro con el PE.

Lo de cifrar la IAT tiene su complicación, estoy dudando si hacer el tuto de cómo hacerlo manualmente, puesto que si pongo el código de un loader que cargue las apis, los antivirus pondrían una firma ahí y no serviría de nada para el 90% de las personas  :-\. Estoy pensando una alternativa  ;D.

Saludos