Firewall against firewall – bypassing an IPS
In this post we are going to explain how we used
_iptables_ to bypass an Intrusion Prevention System during a recent penetration test.
During the first phase of a penetration test on a /24 network, we started performing routinary network port scan to identify available services listening for connections. During the network port scan we identified that the target network was protected by an IDS, as
_nmap_ reported that every port was open, which was obviously not the case. Clearly, the IDS was replying with SYN/ACK packets and
_nmap_ interpreted that as open ports:
A close examination of the traffic returned by the target host revealed that there was a difference between the responses received from an open port and the responses received from the IDS.
_hping3_ was used to verify the packets from each port. The following is an example of the traffic returned by an open port listening on the target host:
root@sec:/home/xxx# hping3 -S -p 443 XXX.XXX.XXX.XXX HPING XXX.XXX.XXX.XXX (enp0s25 XXX.XXX.XXX.XXX): S set, 40 headers + 0 data bytes len=46 ip=XXX.XXX.XXX.XXX ttl=111 id=1176 sport=443 flags=SA seq=0 win=64240 rtt=123.7 ms len=46 ip=XXX.XXX.XXX.XXX ttl=111 id=1747 sport=443 flags=SA seq=1 win=64240 rtt=119.7 ms len=46 ip=XXX.XXX.XXX.XXX ttl=111 id=2252 sport=443 flags=SA seq=2 win=64240 rtt=135.5 ms len=46 ip=XXX.XXX.XXX.XXX ttl=111 id=2583 sport=443 flags=SA seq=3 win=64240 rtt=131.3 ms len=46 ip=XXX.XXX.XXX.XXX ttl=111 id=3109 sport=443 flags=SA seq=4 win=64240 rtt=123.2 ms --- XXX.XXX.XXX.XXX hping statistic --- 5 packets transmitted, 5 packets received, 0% packet loss round-trip min/avg/max = 119.7/1008.1/3767.7 ms
There is, of course, nothing special about the output shown above. However, when we ran
_hping3_ against port 444 (presumably not open) the output generated was as follows:
root@sec:/home/xxx# hping3 -S -p 444 XXX.XXX.XXX.XXX HPING XXX.XXX.XXX.XXX (enp0s25 XXX.XXX.XXX.XXX): S set, 40 headers + 0 data bytes len=46 ip=XXX.XXX.XXX.XXX ttl=36 id=19320 sport=444 flags=SA seq=0 win=0 rtt=203.7 ms len=46 ip=XXX.XXX.XXX.XXX ttl=39 id=52785 sport=444 flags=SA seq=1 win=0 rtt=127.6 ms len=46 ip=XXX.XXX.XXX.XXX ttl=39 id=17311 sport=444 flags=SA seq=2 win=0 rtt=115.4 ms len=46 ip=XXX.XXX.XXX.XXX ttl=39 id=18788 sport=444 flags=SA seq=3 win=0 rtt=131.3 ms len=46 ip=XXX.XXX.XXX.XXX ttl=39 id=55615 sport=444 flags=SA seq=4 win=0 rtt=115.2 ms len=46 ip=XXX.XXX.XXX.XXX ttl=36 id=12274 sport=444 flags=SA seq=5 win=0 rtt=207.0 ms --- XXX.XXX.XXX.XXX hping statistic --- 6 packets transmitted, 6 packets received, 0% packet loss<br /> round-trip min/avg/max = 115.2/150.0/207.0 ms
The TCP window size is zero, and the TTL values are 36 or 39.
In theory, a TCP window size of zero indicates that the target host can not cope with the current network workload, and therefore network clients should decrease the throughout. This is a well known defensive technique called Tarpit which is used in an attempt to delay network port scans.
This difference in the
_TCP window_ values would be enough for an attacker to bypass the IDS. The attacker would just need to discard network traffic with TTL values of 36 and 39 or TCP window size of zero.
The following command will do the job for this particular scan:
iptables -A INPUT -p tcp -m ttl --ttl-lt 40 -j DROP
The next thing left to do is to rerun the scan. Importantly,
_nmap_ uses raw sockets when performing the scan as
_root_, and therefore would actually have access to the network traffic before
_iptables_ drops the packets. For that reason, the network scan should be then ran from a non-privileged account.
As you can see, we used a firewall (iptables) against a firewall (the IPS)