-
Notifications
You must be signed in to change notification settings - Fork 90
Description
The server fails to invalidate or reset the Data Connection parameters (data_ip / data_port) when a subsequent PORT command fails parsing or returns an error (e.g., 501 Syntax error). Logic Flow:
User sends PORT A (Valid). Server updates state to A.
User sends PORT B (Malformed/Invalid). Server returns 501, but state remains A.
User sends LIST. Server connects to A.
This behavior violates the "Fail-Safe" principle. It allows an attacker to "prime" the server with a malicious IP and then mask their intent by sending garbage commands, potentially confusing security audits or WAFs, while the server still executes the dangerous connection upon the next data command.
Code analysis:
PORT command verification fails and does not reset the status(367:405:LightFTP/src/ftpserv.c)
ssize_t ftpPORT(pftp_context context, const char *params)
{
int c;
in_addr_t data_ipv4 = 0, data_port = 0;
char *p = (char *)params;
// ...
if ( data_ipv4 != context->client_ipv4 )
return sendstring(context, error501);// Authentication fails but does not reset data_ipv4/data_port
context->data_ipv4 = data_ipv4;// Only update after verification
context->data_port = (in_port_t)data_port;
context->mode = MODE_NORMAL;
return sendstring(context, success200);
}
Problem: When the PORT command verification fails (such as IP mismatch), the function returns an error, but data_ipv4 and data_port will not be updated or reset. These values may retain the previous state (may be a valid value or an invalid value)
POC:
1)
Login.
Send valid PORT to an unreachable port on client IP (e.g., 127.0.0.1:65535).
Send LIST/RETR/STOR → server blocks on connect(), data commands denied for duration.
2)
Login.
Send invalid PORT with mismatched IP (gets 501).
Send LIST/RETR/STOR →gets 451 Requested action aborted. Local error in processing.
3)
Login.
Send valid PORT to an unreachable port on client IP (e.g., 127.0.0.1:65535).
Send invalid PORT with mismatched IP (gets 501, but stale DataIP/Port kept).
Send LIST/RETR/STOR → server blocks on connect(), data commands denied for duration,the same behavior as test1.