[Snort-sigs] Bug report - Telnet negotiation based FTP signature evasion

pratap pratap at ...3230...
Fri May 26 05:05:05 EDT 2006

Bug Report: Snort 2.4.4

We observed the evasion of a Snort signature in the ftp protocol using 
Telnet Subnegotiation based ASCII transformation on the attack vector. 
This evasion technique works only for FTP servers that support Telnet 
negotiation. Signatures like "FTP wu-ftp bad file completion attempt {" 
(SID: 1378 rev: 15)require the keywords like "~{" in the malicious ftp 
query for successful detection.

We attribute the bug to the implementation incompatibility of the
Telnet Negotiation protocol in Snort and WU-ftpd.

    +---+                 +---+
    + A +<-------+------->+ V +
    +---+        |        +---+
             + snort +
A - Attacker machine
V - victim machine.

Illustration of the bug

We use signature Snort sid: 1378 ("FTP wu-ftp bad file completion
attempt { ") to illustrate the problem.

Details of the signature:
$Id: ftp.rules,v 2005/07/22 19:19:54

alert tcp $EXTERNAL_NET any -> $HOME_NET 21 (msg:"FTP wu-ftp bad file 
completion attempt {"; flow:to_server,established; content:"~"; 
content:"{"; distance:0; reference:bugtraq,3581; reference:bugtraq,3707; 
reference:cve,2001-0550; reference:cve,2001-0886; classtype:misc-attack; 
sid:1378; rev:15;)

The steps needed to see effect of the bug are:
1. Establish a FTP connection between A and V (to victim ftp port).
2. Send CWD command with telnet command in between: "CWD ~\255\250{\r\n"
   (Here \255 is the IAC (Interpret As Command) or telnet escape
   character and \250 is the SB character)

Alert is not produced here. Alert is produced if and only if the
telnet command is removed between "~{". The ftp query is visible
only after correct normalization of the "Telnet negotiation
escape characters". In this example we obscured the pattern
"{" in attack packet using "Telnet Subnegotiation Begin" (SB) character.

This illustration was shown only on the "~{" pattern but can be used
anywhere in the packet and any keyword to evade any signature.

Code snippet:
The related code segment in 

      switch(* ((unsigned char *)(read_ptr + 1)))
             case TNC_NOP:
                 read_ptr += 2;
             case TNC_EAC:
                 read_ptr += 2;
                 /* wind it back a character */
                 if(write_ptr  > start)
             case TNC_EAL:
                 /* todo: wind write_ptr back a line? */
                 read_ptr += 2;
             case TNC_SE:
                 /* Uh, what the heck is a Subnegotiation-end
                  * doing here without a SB?.
                  * could generate an alert, or just normalize
                  * it out.
                 read_ptr += 2;
             /* These are two bytes long */
             case TNC_BRK:
             case TNC_DM:
             case TNC_IP:
             case TNC_AO:
             case TNC_AYT:
             case TNC_GA:
                 read_ptr += 2;
             /* IAC IAC -- means the IAC character (0xff) should be
              * in the data stream since it was escaped */
             case TNC_IAC:
                 read_ptr++; /* skip past the first IAC */
                 *write_ptr++ = *read_ptr++;
             default: /* WILL, WON'T, DO, DON'T */
                 /* move the read ptr up 3 bytes */
                 read_ptr += TNC_STD_LENGTH;

IDS: Snort 2.4.4
Attacker:  Linux version 2.6.11-1.1369_FC4smp
Victim:  Linux version 2.4.20-8
FTP server: WU-ftpd 2.6.1

Pratap Ramamurthy
Graduate Student
Computer Sciences
University of Wisconsin - Madison

More information about the Snort-sigs mailing list