LightFTP icon indicating copy to clipboard operation
LightFTP copied to clipboard

Active-mode blocking connect without timeout enables DoS by exhausting the allowed worker pool

Open yuyz-cyber opened this issue 2 months ago • 0 comments

Key code: create_datasocket uses a blocking connect() with no timeout; LIST/RETR threads call it immediately.

113:135:/LightFTP/src/ftpserv.c
case MODE_NORMAL:
    client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    ...
    if ( connect(client_socket, (const struct sockaddr *)&laddr, sizeof(laddr)) == -1 ) {
        close(client_socket);
        return INVALID_SOCKET;
    }
  • Behavior/impact: Point PORT to a blackholed/unreachable port, then issue LIST/RETR; the worker thread blocks until the TCP stack times out. Under concurrency, each blocked data command holds a worker. Attackers can open multiple sessions (up to the configured pool/maxusers) and consume all available workers, preventing new data commands/sessions from being served—resulting in DoS within the permitted concurrency limits.

  • Poc: Blackhole port 55555; USER anonymous / PASS testPORT 127,0,0,1,217,3LIST. Run multiple sessions in parallel ; observe workers stay blocked until kernel timeout, and new requests are delayed/denied once the pool is consumed.POC:

  • Fix: Add a connect timeout (non-blocking connect + deadline or SO_SNDTIMEO) for active-mode data sockets; optionally restrict/disable PORT (PASV-only) or apply per-IP/session rate limits to protect the worker pool.

yuyz-cyber avatar Dec 10 '25 12:12 yuyz-cyber