You are on page 1of 23

Miguel Tarascó

Andrés Tarascó
• Rootkits
– Que son y su funcionamiento

• Implementaciones de Rootkits
– Que hacen
– Como lo hacen
– Ejemplos prácticos

• Soluciones Genéricas
– Rootkits incompletas (duplicidad de información)
– Análisis de las estructuras del kernel

• Nuevos enfoques
– Deficiencias en los modelos actuales
– Atajando el problema de raiz
• ¿ Que son ?
– Backdoors de nueva generación
– Origenes
– Primeras Rootkits
– Que entendemos realmente por Rootkit
• Ocultación
• Acceso anónimo ilimitado
• ¿ Que hacen ?
– Ocultación
• Procesos
• Ficheros y espacio en disco
• Conexiones
• Claves de registro
– Garantiza su ejecución
– Ofrece acceso remoto
• ¿ Como lo hacen ?
– Hooks
• ¿ Que es un hook ?
• Tipos de hooks
– System Hooks
– IAT Patching
» Que es una API
– API Patching
– DLL Inyection
– Code Inyection
HHOOK SetWindowsHookEx( int idHook,
HOOKPROC lpfn,
HINSTANCE hMod,
DWORD dwThreadId );

BOOL UnhookWindowsHookEx( HHOOK hhk );

– Formas de realizarlo
• Con la tradicional DLL
• Exportando las funciones en el ejecutable
__declspec(dllexport) DWORD WINAPI MyTTYPrint(int ttyDST,
char *buffer, int size) { .. }

HINSTANCE hExe = GetModuleHandle(NULL);


TTYPrint= (TTYPRINT)GetProcAddress((HINSTANCE)hExe,"MyTTYPrint");
if (TTYPrint==NULL) {
printf("[-] Critical Error. Unable To Load TTYPrint()\n");
exit(-1);
}
– Que es la IAT
– Como se localiza
• Encabezados de un ejecutable
• Como llegar a la IAT
• Analizar la IAT

typedef PVOID (WINAPI *IMAGEDIRECOTRYENTRYTODATA)(


LPVOID Base,
BOOLEAN MappedAsImage,
USHORT DirectoryEntry,
PULONG Size
);

pImportDesc =(PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(
hInstance,TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT,&ulSize);
if ((hFichero= CreateFile(VProcesos->Selected->SubItems->Strings[0].c_str(), GENERIC_READ, FILE_SHARE_READ
| FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0)) != INVALID_HANDLE_VALUE) {
if ((hMapping = CreateFileMapping(hFichero, 0, PAGE_READONLY | SEC_COMMIT, 0, 0, 0))) {
if ((pBase = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0))) {
(IMAGE_DOS_HEADER*) CabeceraDos = (IMAGE_DOS_HEADER*) pBase;
if (CabeceraDos->e_magic == IMAGE_DOS_SIGNATURE) { // Encontrado el MZ
(_HEADER*) CabeceraPE = (_HEADER *)((char *)CabeceraDos + CabeceraDos->e_lfanew);
if (CabeceraPE->signature == IMAGE_NT_SIGNATURE) { // Encontrado PE00
ImageBase=CabeceraPE->opt_head.ImageBase;
return(ImageBase );

if (ReadProcessMemory(pHandle,(void*) ImageBase,(void*) &le,sizeof(WORD),&leido)!=0) {


if (le==IMAGE_DOS_SIGNATURE) { // Encontrado MZ
Donde=ImageBase+0x3c; // e_lfanew
if (ReadProcessMemory(pHandle,(void*) Donde,(void*) &le,sizeof(WORD),&leido)!=0) {
PEOffset=ImageBase+le;
if (ReadProcessMemory(pHandle,(void*) PEOffset,(void*) &le,sizeof(WORD),&leido)!=0) {
if (le==IMAGE_NT_SIGNATURE) { // Encontrado PE00
Donde=PEOffset+0x80;
if (ReadProcessMemory(pHandle,(void*) Donde,(void*) &lee,sizeof(DWORD),&leido)!=0) {
IATOffset=ImageBase+lee;

typedef struct _IMAGE_IMPORT_DESCRIPTOR {


typedef struct _IMAGE_THUNK_DATA { union {
union { PBYTE ForwarderString; DWORD Characteristics;
PDWORD Function; PIMAGE_THUNK_DATA OriginalFirstThunk;
DWORD Ordinal; } ;
PIMAGE_IMPORT_BY_NAME AddressOfData; DWORD TimeDateStamp;
} ; DWORD ForwarderChain;
} DWORD Name;
PIMAGE_THUNK_DATA FirstThunk;
}
Diferencias con IAT Patching
• Ventajas
• Inconvenientes

while (pImportDesc->Name) {
import_entry = (IMAGE_THUNK_DATA*) (pImportDesc->FirstThunk + (DWORD)hInstance);

while (import_entry->u1.Function) { // Recorro la lista de funciones


importadas
DWORD direccion = ((DWORD)mapped_entry->u1.Function );
if (direccion==DireccionACambiar) { // direccion de la funcion a modificar
.
.
}
import_entry++; BOOL VirtualProtect(
} LPVOID lpAddress,
pImportDesc++; DWORD dwSize,
}
DWORD flNewProtect,
PDWORD lpflOldProtect
);
– En que consisten
– Diferencias
– Ventajas
– Inconvenientes
proceso = OpenProcess(PROCESS_ALL_ACCESS, FALSE,PID );
ruta=VirtualAllocEx(proceso, NULL,sizeof("c:\\midll.DLL"), MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(proceso,ruta,"c:\\midll.DLL",sizeof("c:\\midll.DLL"),escritos);
Thread = CreateRemoteThread(proceso, NULL, 0,(DWORD (__stdcall *)( void *))
GetProcAddress(GetModuleHandle("KERNEL32.DLL"), "LoadLibraryA"), ruta, 0, ThreadId);

BOOL WINAPI DllMain(HMODULE hMod, DWORD reason, LPVOID lpvReserved) {


switch( reason ) {
case DLL_PROCESS_ATTACH:
MessageBox(0, "Hola, soy la DLL ejecutando un MessageBox", "Información", 0);
break;
}
}
– Porque se pueden aplicar soluciones
genéricas
• Fallos en la programación
• Ocultación Incompleta (duplicidad)
– Enfoques actuales
• Partir de un estado “seguro”
• Análisis de la IAT (RKDetector - vice)
• Estructuras del kernel (Klister)
• Instrucciones de CPU (PatchFinder2)
• Análisis de resultados (RKDetector)
• Bugs (RKDetector)
– Fallos de programación
• Ventajas (pueden ser comunes)
• Inconvenientes (específico de la aplicación)
– Ejemplos

- Ocultación Incorrecta:

Fallo en el Hook: Ntdll.NtOpenProcess

int i=GetCurrentProcessId()+1;
if ((rkHandle =OpenProcess( PROCESS_ALL_ACCESS,
TRUE,i))==NULL){
// Rootkit...
}
– Atacando la ocultación Incompleta de la
rootkit
• Ocultación incompleta de HANDLES
SnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
ProcessList.dwSize=sizeof(PROCESSENTRY32);
while(1) { if(Process32Next(SnapShot, &ProcessList) != FALSE) { ... } }

for (int pid=0;pid<65535;pid+4 ) {


if ( (handle=OpenProcess(pid))!=NULL) && NotListed(pid) )
printf(“Rootkit Process Found with Pid %i\n,pid);
}

• Atacando servicios
– Consultar HKLM\SYSTEM\CurrentControlSet
– Utilizar WMI (RKDetect)
– Conectar por registro remoto y enumerar las claves
– Módulos cargados
• Análisis de la IAT (DLL Inyection)
• Módulos de programas externos (Eternity)
• Monitorizar la propia aplicación (trusted dlls)

MODULO C:\WINDOWS\system32\ADVAPI32.dll cargado


MODULO C:\WINDOWS\system32\RPCRT4.dll cargado
MODULO C:\WINDOWS\System32\CRTDLL.DLL cargado
MODULO C:\WINDOWS\System32\PSAPI.DLL cargado

• Tráfico de red
– Port scanning Vs pAllocateAndGetTcpExTableFromStack()
– Respuesta ante determinados paquetes (hxdef)
unsigned char masterkey082[] = { //masterkey for hxdef 080 and 081
0x01, 0x1e, 0x3c, 0x6c, 0x6a, 0xff, 0x99, 0xa8,
0x34, 0x83, 0x38, 0x24, 0xa1, 0xa4, 0xf2, 0x11,
0x5a, 0xd3, 0x18, 0x8d, 0xbc, 0xc4, 0x3e, 0x40,
0x07, 0xa4, 0x28, 0xd4, 0x18, 0x48, 0xfe, 0x00 };
– Espacio libre en disco
• Primer Enfoque: Duplicidad de información
GetDiskFreeSpace (unidad,&a,&b,&c,&d);
GetVolumeInformation(unidad,volume,MAX_PATH - 1,&dwSerialNumber,
&dwMaxNameLength,&dwFileSystemFlags,tipo,MAX_PATH -1);

• Segundo enfoque: Dependiente del FileSystem


unsigned long* FAT; //Estructura de la FAT
void read_fat(HANDLE hDevice) {
WORD bytesread;
unsigned long *p;
unsigned int leidos;
FAT = (unsigned long*) malloc(boot.BPB_FATSz32*boot.BPB_BytsPerSec);
SetFilePointer(hDevice, boot.BPB_BytsPerSec * boot.BPB_ResvdSecCnt, NULL, FILE_BEGIN);
for(leidos=0;leidos < (boot.BPB_FATSz32); leidos++) {
p=((char*)FAT)+(leidos*boot.BPB_BytsPerSec);
if (ReadFile (hDevice, p , boot.BPB_BytsPerSec, &bytesread, NULL)==0) {
Fatal( "FATAL: Error reading FAT", "Error", GetLastError()); exit(1);
} else {
if (bytesread!=boot.BPB_BytsPerSec) {
Fatal( "FATAL: Error reading FAT", "Error", GetLastError()); exit(1);
}
}
}
– Deficiencias en los modelos actuales
• AV, IDS, integridad, firewalls
– Volvamos a lo básico en una Rootkit
• Ocultación
– Procesos
– Conexiones
– Ficheros
– ¿ Porque esto no es fiable ?
• Procesos: Driver
• Conexiones: Tráfico confiable
• Ficheros: Windows me engaña

– ¿ Como se soluciona esto ?


• Análisis forense
– Ignoremos las API del sistema

– Reprogramemos nuestras funciones


• Información fiable

– Centrémonos en el almacenamiento
• Acceso a la información

– Acceso a bajo nivel: Almacenamiento


• Driver del sistema de archivos
– Acceso a la Información
– Que podemos obtener
• Lectura fiable del árbol de directorios
– Detección de ficheros ocultos
– Escáner de ADS
– Acceso total: No afectan las ACLs
• Lectura fiable del registro de Windows
– Servicios
– Ejecución automática
• Enumeración de usuarios (SAM)
• Recuperación de datos
• Eliminación de rootkits
– Borrado seguro
¿ Preguntas ?

You might also like