diff --git a/README.md b/README.md index 5559c43..c1995a6 100644 --- a/README.md +++ b/README.md @@ -17,12 +17,20 @@ it less detected. Features: * Encrypt payload * Execution guardrails, so payload is only decrypted on target +* Anti emulation, against AV emulators +* EDR deconditioner, against EDR memory scan * Keep all original properties of the executable (imports etc.) * Very small carrier loader -* Code execution either through Entry Point modification, or ASM function hijacking -* Patches carrier shellcode so it re-uses the original IAT (IAT-reuse, no peb-walk) +* Code execution with main function hijacking +* No PEB walk, reuses IAT to execute windows api functions +* Inject data into .rdata for the carrier shellcode * Patch IAT for missing functions for the carrier +References: +* [Slides](https://docs.google.com/presentation/d/1_gwd0M49ObHZO5JtrkZl1NPwRKXWVRm_zHTDdGqRl3Q/edit?usp=sharing) HITB2024 BKK "My first and last shellcode loader" +* [Blog Supermega Loader](https://blog.deeb.ch/posts/supermega/) +* [Blog Cordyceps File injection techniques](https://blog.deeb.ch/posts/exe-injection/) + ## Usage @@ -30,44 +38,10 @@ Features: > ./web.py ``` -## Examples +Browse to `http://localhost:5001". -Inject `messagebox.bin` shellcode into `procexp64.exe` executable: - -``` -(project.py ) Copy data/source/carrier/iat_reuse/template.c to projects/default/ -(payload.py ) --( Load payload: data/binary/shellcodes/messagebox.bin -(exehost.py ) --[ Analyzing: data/binary/exes/procexp64.exe -(exehost.py ) ---[ Injectable: Chosen code section: .text at 0x1000 size: 1159374 -(supermega.py) --I FunctionInvokeStyle: iat_reuse Inject Mode: hijack branching instruction in entrypoint DecoderStyle: xor_1 -(templater.py) --[ Create C from template -(compiler.py ) --[ Compile C to ASM: projects/Verify_1/main.c -> projects/Verify_1/main.asm -(helper.py ) --[ Run process: C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.37.32822\bin\Hostx64\x64\cl.exe /c /FA /GS- /Faprojects/Verify_1/ projects/Verify_1/main.c -(assembler.py) --[ Assemble to exe: projects/Verify_1/main.asm -> projects/Verify_1/main.exe -> projects/Verify_1/main.bin -(helper.py ) --[ Run process: C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.37.32822\bin\Hostx64\x64\ml64.exe projects/Verify_1/main.asm /link /OUT:projects/Verify_1/main.exe /entry:AlignRSP -(assembler.py) --[ Merge stager with payload -> projects/Verify_1/main.bin -(assembler.py) ---[ XOR payload with key 0x31 -(assembler.py) ---[ Size: Stager: 554 and Payload: 433 Sum: 987 -(injector.py ) --[ Injecting: data/binary/shellcodes/messagebox.bin into data/binary/exes/procexp64.exe -> projects/Verify_1/procexp64.infected.exe -(injector.py ) --( Inject: Shellcode rva:0x8E679 (from offset:0x8DA79) -(injector.py ) ---( Rewire: EXE -(injector.py ) --( Inject EXE: Patch from entrypoint (0xE1D78) -(derbackdoorer.py) Backdooring function at 0xE1D78 (to shellcode 0x8E679) -(derbackdoorer.py) find suitable instr to hijack: off: from 0xE1D78 len:256 depthopt:DEPTH_OPTIONS.LEVEL1 -(derbackdoorer.py) [000e1d78] 48 83 ec 28 sub rsp, 0x28 -(derbackdoorer.py) [000e1d7c] e8 2f 04 00 00 call 0xe21b0 -(derbackdoorer.py) --[ Backdoor 0xE1D7C: MOV RDX, 0x14008E679 ; CALL RDX -(superpe.py ) Adding 1 relocations for Page RVA 0xE1000 - size of block: 0xA -(superpe.py ) Reloc0 for addr 0xE1D7E: 0xAD7E - 0xD7E - type: 10 -(injector.py ) Replace 139cafc9f30d at VA 0x14008E73A with call to IAT at VA 0x14011D848 -(injector.py ) Replace 9a16256e76f8 at VA 0x14008E785 with call to IAT at VA 0x14011D958 -(injector.py ) Replace 0c2c5edbf8b5 at VA 0x14008E800 with call to IAT at VA 0x14011DBE8 -(injector.py ) Add data to .rdata at 0x1401204A9 (off: 1174185): USERPROFILE -(injector.py ) Add data to .rdata at 0x1401206A9 (off: 1174697): C:\Users\hacker -(injector.py ) Replace 46c4ab596ed89c at VA 0x14008E6FD with LEA rcx .rdata 0x1401204A9 -(injector.py ) Replace 2c305aac9e56ab at VA 0x14008E716 with LEA rcx .rdata 0x1401206A9 -``` +Alternatively, use `./supermega.py --help`, but its not well supported. ## Directories @@ -80,45 +54,39 @@ Inject `messagebox.bin` shellcode into `procexp64.exe` executable: ## Installation -### Paths +VS2022 compilers. -Configure `config.yaml` with: -* Path to Visual Studio 2022 compiler and assembler -* Path to mash_shc and runshc: https://github.com/hasherezade/masm_shc. +Required: +* `ml64.exe` +* `cl.exe` -`config.yaml`: -```yaml -path_cl: 'C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.37.32822\bin\Hostx64\x64\cl.exe' -path_ml64: 'C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.37.32822\bin\Hostx64\x64\ml64.exe' +Optional: +* `r2.exe` -path_masmshc: 'C:\Users\hacker\Source\Repos\masm_shc\out\build\x64-Debug\masm_shc\masm_shc.exe' -path_runshc: 'C:\Users\hacker\Source\Repos\masm_shc\out\build\x64-Debug\runshc\runshc.exe' +And the python packages: +``` +> pip.exe install -r requirements.txt ``` -Make sure its the `Hostx64/x64/` one exe. Make sure to compile -msmshc and runshc as 64bit. You can also replace runshc with -your own shellcode loader. +### How to get the right paths -### Environment Variables - -It needs all the Microsoft Visual Studio specific paths as environment -variables. Either start the "visual studio developer console", or if you are sane, -use the following commandline to get all the damn env right. +Either start the "visual studio developer console", or +use the following commandline to get all the env right. Use this when `Cannot find Windows.h`. ``` cmd.exe /c "`"C:\Program Files (x86)\Microsoft Visual Studio\\\Common7\Tools\VsDevCmd.bat`" && powershell" ``` -Also make sure radare2 is in path: +Also make sure radare2 is in path if you wanna use it: ``` $Env:PATH += ";C:\Tools\radare2-5.8.8-w64\bin" ``` -### Alternative +### Alternative Path Setup -Use +Try using: ``` "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat" ``` diff --git a/config.yaml b/config.yaml index 80c8ad4..44994ba 100644 --- a/config.yaml +++ b/config.yaml @@ -1,17 +1,15 @@ +# filename now. no need to change. path_cl: 'cl.exe' path_ml64: 'ml64.exe' -path_masmshc: 'C:\Users\hacker\Source\Repos\masm_shc\out\build\x64-Debug\masm_shc\masm_shc.exe' -path_runshc: 'C:\Users\hacker\Source\Repos\masm_shc\out\build\x64-Debug\runshc\runshc.exe' -#- path_shexec = r'C:\Research\hasherezade\exec_fiber\sh-exec-fiber.exe' - -path_sgn: 'C:\tools\sgn2.1\sgn.exe' - -#avred_server: "http://192.168.88.65:8001" +# optional. for payload verification. leave empty if none. avred_server: "" -# leave empty for random on each build +# optional. leave empty for random key on each build xor_key: "" xor_key2: "" #xor_key: "\x42" #xor_key2: "\x13\x37" + +# optional, to test shellcode +path_runshc: 'C:\tools\runshc.exe' diff --git a/phases/templater.py b/phases/templater.py index 5ee6945..b2ebe1a 100644 --- a/phases/templater.py +++ b/phases/templater.py @@ -62,7 +62,6 @@ def create_c_from_template(settings: Settings, payload_len: int): with open(filepath_antiemulation, "r", encoding='utf-8') as file: sir_iteration_count = settings.sir_iteration_count sir_alloc_count = settings.sir_alloc_count - # sir_alloc_count = int((int(config.get("sir_target_mem")) / payload_len))+1 max_alloc_count = 256 if sir_alloc_count > max_alloc_count: # if too large, compiler will add a __checkstk dependency