I recently read an excellent article on PenTestGeek about “Ghost Writing”:
The article is extremely easy to follow, with some adjustments to running metasm under kali:
- The site_ruby folder is located under: /usr/local/lib/site_ruby/
- You dont need to copy the metasm files however, you can simply run gem install metasm
- The disassembler script is located under: /usr/share/metasploit-framework/lib/metasm/samples/disassemble.rb
In the article, we see how the author uses ghost writing to change the signature of the shellcode file he generated by inserting instructions that do not change the actual execution of the program. Some other techniques I found effective are:
- Find an xor eax, eax statement, and perform any operations you wish on EAX, such as mov eax, 22 or add eax, 22 and so on. The XOR statement means the register is going to be zeroed out, so these statements will have no effect.
- Use of commands like add eax, 0 and sub eax, 0… not much explanation needed there…
- Use of inc eax and dec eax, making sure the eax register is not used in intervening code (inc = increment and dec = decrement)
- Use of jmp and labels to move the position of code within the file
Where I diverged from the PenTestGeek article is in the re-encoding stage. The author used the peencode.rb script (from the same sample directory the disassemble.rb script is found). This means the ghost written shellcode is compiled as a standalone executable. That’s fine, but we have some excellent frameworks like “The Backdoor Factory” which can inject shellcode into code caves within existing EXE files… meaning a better chance of the victim running an innocent or familiar looking exe that actually does something.
So how do we generate the raw binary shellcode from our ghost written assembly file? It turns out to be quite simple… Instead of using peencode.rb, we use exeencode.rb, whose default output is raw binary. We’d end up with something like so:
ruby /usr/share/metasploit-framework/lib/metasm/samples/exeencode.rb -o raw.o ./ghost_written.asm
And our raw shellcode is now in raw.o. This in turn allows us to use backdoor factory to inject our improved, ghost written shellcode, into an existing, familiar exe, say Putty….
backdoor.py -f /tmp/putty.exe -s user_supplied_shellcode -U /tmp/raw.o
Assuming you have putty.exe and raw.o in your tmp folder, backdoor factory will do it’s magic, inserting shellcode into code caves and all that goodness, and you end up with an improved, ghost written shellcode, backdoored, putty.exe
PS you really should see the presentation from SecretSquirrel on The Backdoor Factory, and his blog posts on using the factory along with mitmproxy to backdoor EXEs passing over the wire – he is awesome…