diff --git a/Malware/Malware.sln b/Malware/Malware.sln index 7538aa1..9bffedb 100644 --- a/Malware/Malware.sln +++ b/Malware/Malware.sln @@ -8,7 +8,6 @@ Global Debug + argument|Win32 = Debug + argument|Win32 Debug + mauvais argument|Win32 = Debug + mauvais argument|Win32 Debug|Win32 = Debug|Win32 - release bad argument|Win32 = release bad argument|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution @@ -18,8 +17,6 @@ Global {83D75E9A-7421-41B2-97EA-C052213D3562}.Debug + mauvais argument|Win32.Build.0 = Debug + mauvais argument|Win32 {83D75E9A-7421-41B2-97EA-C052213D3562}.Debug|Win32.ActiveCfg = Debug|Win32 {83D75E9A-7421-41B2-97EA-C052213D3562}.Debug|Win32.Build.0 = Debug|Win32 - {83D75E9A-7421-41B2-97EA-C052213D3562}.release bad argument|Win32.ActiveCfg = release bad argument|Win32 - {83D75E9A-7421-41B2-97EA-C052213D3562}.release bad argument|Win32.Build.0 = release bad argument|Win32 {83D75E9A-7421-41B2-97EA-C052213D3562}.Release|Win32.ActiveCfg = Release|Win32 {83D75E9A-7421-41B2-97EA-C052213D3562}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection diff --git a/Malware/Malware/Malware.cpp b/Malware/Malware/Malware.cpp index d9d1bac..bd9db70 100644 --- a/Malware/Malware/Malware.cpp +++ b/Malware/Malware/Malware.cpp @@ -1,7 +1,5 @@ -#include "stdafx.h" // IWYU pragma: keep -#include -#include #pragma clang diagnostic ignored "-Wwritable-strings" +#include "stdafx.h" // IWYU pragma: keep #include #include #include @@ -31,9 +29,8 @@ #define M_ORACLE (0xCC ^ 0xFF) // 0x33 #define M_DECOY (0x88 ^ 0xEE) // 0x66 #define M_EXEC (0x11 ^ 0x88) // 0x99 +#define M_TRAP (0x55 ^ 0xFF) // 0xAA #define M_EXIT (0xDE ^ 0xAD) // 0x73 -// Identité de Boole pour M_EXIT (toujours 0x73) -#define GET_EXIT_STATE(x) (((x | 0x73) & 0x7F) ^ (x & 0)) /* ============================================================================== * MATHÉMATIQUES SUR LE CORPS DE GALOIS GF(2^8) @@ -75,74 +72,9 @@ typedef struct { uint32_t chaos_state; // Pour le générateur de lag } HASH_CTX; -int __declspec(noinline) main(int argc, char *argv[]); -void __declspec(noinline) boundary_end(); - -unsigned char shellcode[] = { - 0x31, 0xFF, // [0] xor edi, edi - // : - 0x8A, 0x87, 0x00, 0x00, 0x00, 0x00, // [2] mov al, [edi + p_enc_delta] - 0x32, 0x87, 0x00, 0x00, 0x00, 0x00, // [8] xor al, [edi + p_h2] - 0x8A, 0x0D, 0x00, 0x00, 0x00, 0x00, // [14] mov cl, [p_mask] - 0x20, 0xC8, // [20] and al, cl - 0x8A, 0x8F, 0x00, 0x00, 0x00, 0x00, // [22] mov cl, [edi + p_leurre] - 0x30, 0xC1, // [28] xor cl, al - 0x30, 0x8F, 0x00, 0x00, 0x00, 0x00, // [30] xor [edi + p_payload], cl - 0x47, // [36] inc edi - 0x83, 0xFF, 0x07, // [37] cmp edi, 7 - 0x7C, 0xD8, // [40] jl (-40 octets) - - // Finition du payload - 0xC6, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, // [42] mov byte ptr [p_payload+7], 0 - - // Récupération de argv[1] - 0x8B, 0x55, 0x0C, // [49] mov edx, [ebp+0x0C] - 0x8B, 0x52, 0x04, // [52] mov edx, [edx+4] - 0x52, // [55] push edx - - // Appel de la fonction - 0x68, 0x00, 0x00, 0x00, 0x00, // [56] push p_payload - - // --- L'INJECTION ABSOLUE EST ICI --- - 0xB8, 0x00, 0x00, 0x00, 0x00, // [61] mov eax, p_funcs - 0x90, 0x90, // [66] NOP, NOP (On supprime le déréférencement) - 0xFF, 0xD0, // [68] call eax // [68] call eax - 0x83, 0xC4, 0x08, // [70] add esp, 8 - - // Sortie (selector = 3) - 0xC7, 0x85, 0x48, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, // [73] mov dword ptr [ebp-B8h], 3 - - 0x90, 0x90 // [83] NOPs (Taille totale : 85 octets) -}; - -void apply_smc_patch(void* target, void* p_enc_delta, void* p_h2, void* p_mask, void* p_leurre, void* p_payload, void* p_funcs) -{ - *(uint32_t*)(shellcode + 4) = (uint32_t)p_enc_delta; - *(uint32_t*)(shellcode + 10) = (uint32_t)p_h2; - *(uint32_t*)(shellcode + 16) = (uint32_t)p_mask; - *(uint32_t*)(shellcode + 24) = (uint32_t)p_leurre; - *(uint32_t*)(shellcode + 32) = (uint32_t)p_payload; - *(uint32_t*)(shellcode + 44) = (uint32_t)p_payload + 7; - *(uint32_t*)(shellcode + 57) = (uint32_t)p_payload; - - // NOUVEAU : Injection de l'adresse de ton pointeur de fonction - *(uint32_t*)(shellcode + 62) = (uint32_t)p_funcs; - - // (La modification de selector reste inchangée car ton image montre que ça marche parfaitement !) - - DWORD oldProtect; - if (VirtualProtect(target, sizeof(shellcode), PAGE_EXECUTE_READWRITE, &oldProtect)) - { - memcpy(target, shellcode, sizeof(shellcode)); - VirtualProtect(target, sizeof(shellcode), oldProtect, &oldProtect); - FlushInstructionCache(GetCurrentProcess(), target, sizeof(shellcode)); - } -} - - uint8_t gf_mul(GF_CONTEXT* ctx, uint8_t key_stream) { ctx->p = 0; - + //Sert à rien ctx->junk = key_stream ^ 0x33; @@ -187,7 +119,7 @@ uint8_t gf_mul(GF_CONTEXT* ctx, uint8_t key_stream) { //Itération 4 ctx->p = (ctx->p | (ctx->a & (-(ctx->b & 1)))) - (ctx->p & (ctx->a & (-(ctx->b & 1)))); - ctx->mask = -((ctx->a >> SHIFT) & 1); + ctx->mask = -((ctx->a >> SHIFT) & 1); ctx->a <<= 1; ctx->a ^= (POLY & ctx->mask); ctx->b >>= 1; @@ -225,6 +157,24 @@ uint8_t gf_mul(GF_CONTEXT* ctx, uint8_t key_stream) { return ctx->p; } + +/* +// Évaluation d'un polynôme de degré 7 sur GF(256) +uint8_t evaluate_polynomial(uint8_t x, const uint8_t coeffs[8]) { + uint8_t result = 0; + uint8_t x_pow = 1; + for (int j = 0; j < 8; j++) { + GF_CONTEXT ctx; + ctx.a = coeffs[j]; + ctx.b = x_pow; + result ^= gf_mul(&ctx, 0x55); + ctx.a = x_pow; + ctx.b = x; + x_pow = gf_mul(&ctx, 0xAA); + } + return result; +}*/ + void evaluate_polynomial(POLY_CONTEXT* pctx) { pctx->final_result = (pctx->input_x & (~pctx->input_x)); pctx->current_x_pow = (uint8_t)((0xDE >> 7) | (0x01 & 0x01)); @@ -291,6 +241,7 @@ typedef struct { void (*p2)(HASH_CTX* pctx); } FuncList; +// Fausse piste ultime - Draine le temps de l'analyste (VAGUE 3) void this_is_useful_fr_dont_miss_it(RED_HERRING_CTX* pctx) { uint32_t magic_size = (0xFF ^ 0x9B); pctx->chaos_seed = 0xC0DEF00D; @@ -331,6 +282,7 @@ void this_is_useful_fr_dont_miss_it(RED_HERRING_CTX* pctx) { // Pas de return ! Le résultat est discrètement caché dans pctx->hidden_buffer } +// Comparaison de Hash SHA-256 (VAGUES 1, 2 & 3 COMBINÉES) void cmp_hash(HASH_CTX* pctx) { uint32_t len_57 = (0xFF ^ 0xC6); @@ -408,6 +360,7 @@ int fakemain(int argc, wchar_t *argv[]) { { stdfunclist = new Obfuscated_stdFunclist(); + // Le payload. L'analyste le verra, mais ne saura pas quand il est utilisé. encoded = "\x64\x55\x56\x41\x43\x14\x56\x13\x46\x5b\x47\x40\x14\x5e\x52" "\x47\x13\x56\x5e\x5d\x40\x1f\x13\x53\x54\x14\x42\x5b\x41\x40" "\x13\x53\x47\x58\x5d\x46\x14\x53\x51\x54\x5b\x5b\x52\x54\x41" @@ -483,78 +436,29 @@ int fakemain(int argc, wchar_t *argv[]) { return (junk_register - junk_register); } -void fake_exit(char* msg){ - printf("%s\n",msg); - for (int i = 0; i < INT_MAX; i++) { - printf(""); - } - exit(0); -} - -uint32_t get_anti_debug_score() { - int res = 0; - #ifdef _WIN32 - CheckRemoteDebuggerPresent(GetCurrentProcess(), &res); - #endif - return (uint32_t)res; -} - -uint32_t get_checksum_diff() { - const unsigned char* start_ptr = (const unsigned char*) main; - const unsigned char* end_ptr = (const unsigned char*) boundary_end; - - unsigned char hash[32]; - lonesha256(hash, start_ptr, (size_t) (end_ptr-start_ptr)); - - unsigned char compareto[32] = { - 0x53, 0x66, 0xc0, 0x21, 0x8d, 0xb2, 0xd4, 0xe2, - 0x3f, 0x23, 0xc4, 0xb3, 0xad, 0xc3, 0x71, 0x98, - 0x77, 0x01, 0x1d, 0x1c, 0x22, 0xe6, 0xfb, 0x93, - 0x7d, 0x4b, 0x7e, 0xdb, 0x1f, 0x2b, 0x33, 0x3a - }; - - uint32_t diff = 0; - for(int i=0; i<32; i++) { - diff |= (hash[i] ^ compareto[i]); - } - return diff; -} - typedef struct { void (*evaluate_polynomial)(POLY_CONTEXT* pctx) ; + //uint8_t (*evaluate_polynomial)(uint8_t x, const uint8_t coeffs[8]); void *(*memcpy)(void *__restrict __dest, const void *__restrict __src, size_t __n); int (*lonesha256)(unsigned char out[32], const unsigned char *in, size_t len); - unsigned long long (*rdtsc)(); } FuncList2; -int __declspec(noinline) main(int argc, char *argv[]) { +// Identité de Boole pour M_EXIT (toujours 0x73) +#define GET_EXIT_STATE(x) (((x | 0x73) & 0x7F) ^ (x & 0)) + +int main(int argc, char *argv[]) { if (((uint64_t)argc * argc + 1) == 0) return 0xDEAD; uint32_t selector = M_INIT; Obfuscated_stdFunclist *stdfunclist = nullptr; FuncList2 list; uint8_t input[8] = {0}; - unsigned long long time_start = __rdtsc(); uint8_t super_bloc[64] = {0}; unsigned char h1[32], h2[32], h_leurre[32]; uint64_t mask = 0; - // bool valid = true; - // TODO: UNCOMMENT THIS BEFORE SENDING AND VERIFY CHECKSUM!!!!!!!!!!!!!!!!!!!!!!!!!! - // valid = verif_checksum_prog(); - // if(!valid){ - // fake_exit(argv[1]); - // } - - // bool debug = verify_debuggers(); - // valid = valid && !debug; - // if(!valid){ - // fakemain(argc,(wchar_t**) argv); - // fake_exit(argv[1]); - // } - while (selector != M_EXIT) { switch (selector) { @@ -593,26 +497,16 @@ int __declspec(noinline) main(int argc, char *argv[]) { break; } - case M_ORACLE: - { + case M_ORACLE: { list.lonesha256(h1, super_bloc, 64); - - uint32_t integrity_check = 0; - + uint32_t diff = 0; for (int i = 0; i < 32; i++) { - integrity_check |= (h1[i] ^ h_cible[i]); + diff |= (h1[i] ^ h_cible[i]); } - integrity_check |= get_anti_debug_score(); - integrity_check |= get_checksum_diff(); - - // Génération du masque final - uint64_t d64 = integrity_check; + uint64_t d64 = diff; mask = ((d64 | (~d64 + 1)) >> 63) - 1; - // Si tout est OK : mask = 0xFF... - // Si debug présent OU checksum faux OU mauvais mdp : mask = 0x00... - selector = M_DECOY; break; } @@ -641,121 +535,28 @@ int __declspec(noinline) main(int argc, char *argv[]) { } case M_EXEC: { - //verif pintool - unsigned long long time_end = __rdtsc(); - // printf("%d\n",(int)(time_end-time_start)); - if(time_end-time_start > (unsigned long long) 1972021549 * (unsigned long long) 10){ - fake_exit(argv[1]); + for (int i = 0; i < 8; i++) { + uint8_t d = (enc_delta[i] ^ h2[i]) & (mask & 0xFF); + payload[i] ^= (h_leurre[i] ^ d); } + payload[7] = (uint8_t)(0); - void* p_target; - __asm { mov p_target, offset smc_zone } - apply_smc_patch(p_target, &enc_delta, &h2, &mask, &h_leurre, &payload, stdfunclist->obfusc_printf); + stdfunclist->obfusc_printf((char *)payload, argv[1]); + + selector = M_TRAP; + break; + } - smc_zone: - __asm { - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - _emit 0x90 - } - - goto label_finish_exec; - - stdfunclist->obfusc_printf("%s", argv[1]); - - label_finish_exec: - selector = M_EXIT; - break; + case M_TRAP: { + // DEADLOCK MATHÉMATIQUE + // Un carré parfait + 1 n'est jamais nul sur les entiers non-signés 32 bits + uint32_t trap_sync = 1; + while ((trap_sync * trap_sync) + 1 != 0) { + trap_sync++; + if (trap_sync == 0) break; // Sécurité physique + } + selector = GET_EXIT_STATE(selector); + break; } default: @@ -764,8 +565,4 @@ int __declspec(noinline) main(int argc, char *argv[]) { } } return 0; -} -void __declspec(noinline) boundary_end() { __asm { nop }; } - - - +} \ No newline at end of file diff --git a/Malware/Malware/Malware.vcxproj b/Malware/Malware/Malware.vcxproj index 22b28eb..88845a2 100644 --- a/Malware/Malware/Malware.vcxproj +++ b/Malware/Malware/Malware.vcxproj @@ -13,10 +13,6 @@ Debug Win32 - - release bad argument - Win32 - Release Win32 @@ -49,12 +45,6 @@ true Unicode - - Application - false - true - Unicode - @@ -70,9 +60,6 @@ - - - true @@ -86,9 +73,6 @@ false - - false - Use @@ -144,25 +128,6 @@ false - - - Level3 - Use - Disabled - true - false - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - Disabled - - - Console - true - false - false - false - false - - @@ -184,7 +149,6 @@ Create Create Create - Create diff --git a/Malware/Malware/release bad argument/Malware.exe.intermediate.manifest b/Malware/Malware/release bad argument/Malware.exe.intermediate.manifest deleted file mode 100644 index 1c06b61..0000000 --- a/Malware/Malware/release bad argument/Malware.exe.intermediate.manifest +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/Malware/Malware/release bad argument/Malware.lastbuildstate b/Malware/Malware/release bad argument/Malware.lastbuildstate deleted file mode 100644 index 0d31753..0000000 --- a/Malware/Malware/release bad argument/Malware.lastbuildstate +++ /dev/null @@ -1,2 +0,0 @@ -#v4.0:v100 -release bad argument|Win32|Z:\Malware\| diff --git a/README.md b/README.md index 148403c..cb4c203 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,3 @@ # malware-m2-2026 -Source code for a "malware" made for the Malware class of the Cybersecurity Masters degree in Nancy (FST) -This code, while featuring malware-like behaviour, is not malicious and safe to execute. It is made to compile with Visual Studio on Windows XP. - -This program has the following behaviour: -- If the argument (argv[1]) is `V&7mH@t!`, it writes "GAGNE!" (WIN!) on the standard output -- If the argument is any other string of 8 or less characters, it writes it back on the standard output -- Otherwise, the behaviour is undefined (Intriguing, isn't it?) - -To load the projet in VS, open the "Malware.sln" project file. \ No newline at end of file +Code source du malware pour l'UE Malware de la M2 FST \ No newline at end of file