Manually Adding Shellcode to Windows Executables

Here is a short and simple proof-of-concept tutorial on how you can manually add shellcode to common Windows executables, without using msfconsole or the backdoor-factory scripts to generate the binaries. In this example, we will be using putty.exe, downloaded from: here.

Firstly, add a new code section to the executable using a PE editor such as LordPE. Remember to allocate enough space. In the example below, a size of 1000 bytes is allocated to the .NewSec section. Save the modified binary and try running it. You should get an error and the application crashes.

create_sections_lordpe

Next, open the modified binary in a hex editor and allocate the ‘1000’ byte value at the end of the file. Save the binary, and you should notice that the application now runs as per normal.

adding_space_via_hex_editor

The binary is now ready for ‘backdoor code insertion’. Open the binary in a debugger such as OllyDBG or Immunity, whichever is your preference. Notice the first 5 instructions in the application:

original_starting_instructions

Copy and paste the instructions somewhere, as we will need to refer to this later.

In the debugger, open the ‘memory view’ to view the address of ‘.NewSec’, which we added in the earlier steps. In this case the starting address to the section we created earlier is @ memory address ‘00484000’. We want the code execution of the binary to jump to this address, as this is where we will be placing our shellcode.

memory_sections

Now that we got the starting address of our new code section, we can proceed to modify the instructions. Modify the first instruction of the application to ‘JMP 00484000’.

edit_first_instruction_to_jmp_code_cave

Double-click the newly modified instruction to move to the ‘.NewSec’ section. You should see a lot of ‘free’ space.

blank_code_cave

Next, we proceed to add 2 instructions, PUSHAD, PUSHFD to ‘preserve’ the current registers and flags.

pushfd_pushad_code_cave_to_save_regs

Now that we have push the current registers to the stack, we can start adding the shellcode from address ‘00484002’ onwards. The shellcode can be generated using msfpayload. Paste the shellcode as ‘binary paste’ in the debugger from address ‘00484002’ and you are all set. Note the ESP address when the binary execution is at address ‘00484002’. In the below case, it is pointing to ‘0012FF68’. We will need this address to re-align the ESP register to its original position later.

paste_shellcode_here_msf

The addresses will vary depending on what shellcode you decided to use. Next, you have to manually step through the pasted code to see which line actually spawns the shell. Opening a netcat listener will greatly help to determine this, and it is usually at a ‘CALL’ instruction. In the below case, the shell is spawned after the ‘CALL EBP’ instruction at the memory address ‘0048411B’. Note the ESP register value at ‘0048411D’ when the binary is executed. In this case, it is pointing to ‘0012FD70’. To re-align the ESP register to its original position, we will have to find the difference, which is ‘0012FF68’ – ‘0012FD70’ and that gives us a value of ‘1F8’. Edit the instruction after ‘CALL EBP’ to ‘ADD ESP,1F8’ in order to align the ESP register. Now that the ESP register is aligned, we can also restore the other registers and flags with the ‘POPFD’ and ‘POPAD’ instruction as shown below. Now to enable the application to function as intended, we need to replace the instructions that were removed at the beginning of the binary. Proceed to do that as shown below.

shellcode_executes_res_regs_call_init

Save the changes and attempt to run the executable, remembering to setup a netcat listener. You should receive your shell.

shell_established_2

In my case, the application did not run as intended although the shell is spawned. After debugging, I realized that the shellcode that was generated by metasploit passed an argument of value ‘-1’ to the ‘WaitForSingleObject’ method which caused the putty program to not run until the shell is terminated. Changing the value of ‘-1’ to ‘0’ does the trick. In my case, replacing 1 instruction in the shell code fixed the issue.

Now you have a putty.exe binary that has a ‘backdoor’ shellcode that still functions as intended. Most AVs will detect this though, so it really depends on how you try to ‘obfuscate’ the shellcode, as the ones generated by metasploit are detected by most AV software out there.

Summarized Application Flow

Application flow
----------------
[Original Code]
[Original Code]
....
[Original Code]
[Code Cave with PUSHAD; PUSHFD]
[Start of MSFVenom code] // Set a break-point here and note the value of ESP. 0012FD70 in this example.
[End of MSFVenom code; ending will CALL EBP]
[Address to align the offset of ESP]
// Set a break-point, hit it and note the ESP register, example 0012FF68. So, 0012FF68–0012FD70 and that gives us an offset of 1F8. So for this example you will change this instruction to ADD ESP, 1F8.
[POPFD]
[POPAD]
[Restored instructions that were overwritten at entry point]
Advertisements

5 thoughts on “Manually Adding Shellcode to Windows Executables

    1. v00d00sec Post author

      Hi there, sorry for the late reply. You can do a backtrace in ollydbg. I cannot recall fully how I did it, but its simply changing 1 of the instruction to NOP.

      Like

      Reply
  1. Pingback: Part x03 – Backdooring PE / Antivirus Evasion | Baseline Security

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s