A long time ago (June 2004), I stumbled upon a most ridiculous deficiency in the Cisco IDS probe that allowed me to evade HTTP string based signatures. This was based on 2004 Cisco IDS technology. So let me fill you in…
The evasion tactic takes advantage of the Cisco IDS probe not knowing if a packet reaches the intended destination or not. The probe reassembles any traffic it sees before passing it on to the signature detection mechanisms. The theory is simple:
- Send GET /cgi-bin/gobbler/p to the destination web server
- Send d with a TTL sufficient so that it passes the IDS but does not reach the web server
- Send hf HTTP/1.0 to the destination web server
The web server correctly receives the string GET /cgi-bin/gobbler/phf HTTP/1.0 and processes it accordingly. The IDS sees the string GET /cgi-bin/gobbler/pdhf HTTP/1.0 which does not match the Cisco IDS regex phf[? \r\n\t] of the signature.
We have evaded the IDS.
The details are of course a little more complicated. The following diagram describes the testbed network environment.
The Attacker is running some sort of Linux distro, with the application sendip installed. (Great little tool for sending custom IP packets with every option settable)
The test was conducted against Cisco IDS v4.1-4-S95
The webserver was running a default IIS installation under Win2k.
Ethereal was running on both the Attacker PC (attacker.sniff) and the web server (webserver.sniff).
The following PERL code was used to fabricate the packets from #1 and #3 above:
The SendIP string used to fabricate our custom packet:
- -it 2 : TTL of 2
- -ts s_port: source port
- -tn seq#: sequence number
- -ta ack#: acknowledgement number
The handshake (from the PERL code)
Send the first part of the HTTP Request (GET /cgi-bin/gobbler/p) (from the PERL code)
Details of the GET packet
Details of the response
Send the character ‘d’ with a TTL of 2 so that the packet passes the IDS probe but does not reach the web server. The following SendIP command performs this function:
Note that the SEQ# (-tn 23) equals the ACK# from Frame 5 above. And the ACK# (-ta 1) equals the SEQ# from Frame 5 above.
Details of the SendIP packet
Send a TCP Keepalive packet to the web server. This forces an increment in the SEQ/ACK numbers for the current sessions. We can complete the HTTP request with the web server without taking this step, however the IDS probe issues an alert, correctly I might add, called “TCP Segment Overwrite”.
The keepalive packet has no effect on the TCP session with the web server other than to increment SEQ/ACK numbers for the web server. The importance here is that the TCP reassembly functions of the Cisco IDS probe are kept happy.
The keepalive packet is sent using SendIP with a high enough TTL to ensure it reaches the web server.
Details of the SendIP Keepalive Packet
Send the remainder of the HTTP request (using the PERL code)
Details of that packet.
The following entry from the webserver logfile shows that the request was received as we intended:
The wireshark function “Follow TCP Stream” from the attacker.sniff file
The wireshark function “Follow TCP Stream” from the webserver.sniff file
And that’s how to defeat the simple HTTP request signatures of an IDS.