Security: Fix CVE-1999-0017 FTP bounce attack in net_ftp_server#131
Open
jmrplens wants to merge 1 commit intoARM-software:mainfrom
Open
Security: Fix CVE-1999-0017 FTP bounce attack in net_ftp_server#131jmrplens wants to merge 1 commit intoARM-software:mainfrom
jmrplens wants to merge 1 commit intoARM-software:mainfrom
Conversation
Add IP address validation to PORT and EPRT command handlers to prevent FTP bounce attacks. The server now verifies that the IP specified in the command matches the client's actual connection address before accepting it. The current implementation blindly accepts any IP in PORT/EPRT commands, allowing authenticated users to instruct the server to open data connections toward arbitrary third-party hosts. This is documented as CVE-1999-0017 and explicitly addressed in RFC 2577, Section 3. Changes in net_ftp_server.c: - Add ftp_parse_port_ip() to extract and validate IP from PORT arguments - Add ftp_parse_eprt_ip() to extract and validate IP from EPRT arguments - Add ftp_validate_port_ip() to compare parsed IP against client address - Add ftp_validate_port_range() to reject out-of-range port numbers - Modify PORT/EPRT handler to call validation before accepting the command Changes in net_ftp_server.h: - Add FTP_RESP_BADPARAM (501) for malformed command parameters - Add FTP_RESP_NOTIMPL (504) for rejected bounce attempts Legitimate clients that specify their own IP in PORT/EPRT are not affected. Clients using PASV or EPSV are not affected. References: - CVE-1999-0017 - RFC 2577 (FTP Security Considerations), Section 3 - RFC 959 (FTP), response codes 501, 504 - RFC 2428 (EPRT command format) - CWE-441 (Unintended Proxy or Intermediary)
Collaborator
|
Thank you for your contribution to improving the safety of our network middleware. I truly appreciate the effort you have put into this enhancement. I will review your pull request as soon as I have the opportunity and will proceed with merging it afterward. This is an important safety improvement for our FTP server, and your work is greatly valued. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The FTP server in MDK-Middleware does not validate whether the IP address provided in PORT and EPRT commands matches the IP of the connected client. This allows any authenticated user to instruct the server to open data connections toward arbitrary third-party hosts, which is a well-known attack vector documented as CVE-1999-0017.
This patch adds IP validation to the PORT/EPRT handler in
net_ftp_server.c, rejecting commands that specify an IP address different from the client's. It follows the recommendation in RFC 2577, Section 3.The problem
When a client sends a PORT command, the current implementation extracts only the port number via
ftp_scan_dport()and immediately responds200 Command okay, regardless of what IP address the command contains. The IP portion of the argument is never checked against the client's actual address.In practice, this means an attacker who is authenticated on the FTP server can do the following:
At this point the FTP server opens a TCP connection from its own address to 8.8.8.8 on port 80. The attacker never touches 8.8.8.8 directly -- the server does it on their behalf. This is the FTP bounce attack.
The same applies to EPRT:
The server would then connect to an internal machine at 10.0.0.5 on the SSH port.
This lets an attacker:
This class of vulnerability is catalogued as CWE-441: Unintended Proxy or Intermediary, which specifically lists CVE-1999-0017 as an observed example.
How to reproduce
You need an FTP client (or just a raw TCP socket) and access to a running MDK-Middleware FTP server. Python's
ftplibis enough:If the server responds with
200, it will attempt to open a data connection to 8.8.8.8:80 on the next transfer command. A fixed server should respond with504 Command not implemented for that parameter.Additional cases to test:
PORT 8,8,8,8,0,80PORT 127,0,0,1,0,22PORT 192,168,204,1,0,23EPRT |1|8.8.8.8|80|PORT <client_ip>,195,88What this patch does
Files changed:
Components/Network/Source/net_ftp_server.c(4 functions added, PORT/EPRT handler modified)Components/Network/Source/net_ftp_server.h(2 response codes added)The patch introduces four static helper functions before
ftp_listener():ftp_parse_port_ip()-- parses the IP address from PORT command arguments (h1,h2,h3,h4,p1,p2), using the existingnet_atoi()function. Validates that each octet is in the 0-255 range.ftp_parse_eprt_ip()-- parses the IP address from EPRT command arguments (|1|addr|port|), following the format specified in RFC 2428. Currently supports IPv4 only (address family 1).ftp_validate_port_ip()-- compares the parsed IP againstftp_s->Client.addrusingmemcmp(). Returns false and logs withERRORF()when there is a mismatch.ftp_validate_port_range()-- validates that the port number falls within the 1-65535 range.The PORT/EPRT handler in
ftp_listener()is modified to call these functions before accepting the command. If parsing fails, the server responds with501 Syntax error in parameters. If the IP does not match the client's address, it responds with504 Command not implemented for that parameter. Both codes are standard FTP response codes defined in RFC 959.Two new response code constants are added to the header:
FTP_RESP_BADPARAM(maps to 501)FTP_RESP_NOTIMPL(maps to 504)Backward compatibility
This change does not affect legitimate FTP clients. Any client that uses PORT or EPRT with its own IP address (which is the normal behavior) will continue to work exactly as before. Clients using PASV or EPSV are not affected at all.
The only traffic that gets rejected is PORT/EPRT commands where the specified IP does not match the client's connection -- something that only happens intentionally (i.e., an attack or proxy FTP). Proxy FTP through third-party PORT commands is explicitly discouraged by RFC 2577.
References
CVE-1999-0017 -- "FTP servers can allow an attacker to connect to arbitrary ports on machines other than the FTP client, aka FTP bounce."
https://www.cve.org/CVERecord?id=CVE-1999-0017
RFC 2577 -- FTP Security Considerations (Allman, Ostermann, May 1999). Section 3 describes the bounce attack and recommends that servers reject PORT commands specifying third-party addresses, using response code 504.
https://datatracker.ietf.org/doc/html/rfc2577
RFC 959 -- File Transfer Protocol (Postel, Reynolds, October 1985). Defines PORT command format and response codes 501 and 504.
https://datatracker.ietf.org/doc/html/rfc959
RFC 2428 -- FTP Extensions for IPv6 and NATs (Allman, Ostermann, Metz, September 1998). Defines the EPRT command format.
https://datatracker.ietf.org/doc/html/rfc2428
CWE-441 -- Unintended Proxy or Intermediary ('Confused Deputy'). Lists CVE-1999-0017 as an observed example of this weakness class.
https://cwe.mitre.org/data/definitions/441.html
CERT Advisory CA-97.27 -- FTP Bounce. Referenced in RFC 2577.
Implementation Status
fix/cve-1999-0017-ftp-bounce1ff81bf-- Security: Fix CVE-1999-0017 FTP bounce attack in net_ftp_server