Online Book Reader

Home Category

Linux Firewalls - Michael Rash [41]

By Root 393 0
contained the ACK bit (see ❷—the tcph pointer at this stage points to a writable copy of the original packet), then both the needs_ack flag and the acknowledgment value are set to zero (❸). If the original TCP packet did not contain the ACK bit, the needs_ack flag is set to one and the acknowledgment value is derived from the original packet, at ❹. Finally, at ❺, the ACK flag is set to zero or one depending on the value of the needs_ack flag. This logic in the REJECT target is copied from the code that implements the TCP stack; you can see this in the Linux kernel sources, around line 569 in the tcp_v4_send_reset() function in the net/ipv4/tcp_ipv4.c file. To see this in action, we'll now look at having iptables tear down an established TCP connection after it has gone into the established state and when the string tester is sent across from the client to the server. (We'll see more examples of this kind of transport layer response to application layer data in Chapter 10 and Chapter 11.)

❶ [iptablesfw]# iptables -I INPUT 1 -p tcp --dport 5001 -j ACCEPT❼

[iptablesfw]# iptables -I INPUT 1 -p tcp --dport 5001 -m string --string

"tester" --algo bm -j REJECT --reject-with tcp-reset

❷ [iptablesfw]# nc -l -p 5001 &

[1] 8135

[ext_scanner]$ echo "tester" | nc 71.157.X.X 5001

❸ [iptablesfw]# tcpdump -i eth0 -l -nn -s 0 -X port 5001

❹ 22:33:25.826122 IP 144.202.X.X.54922 > 71.157.X.X.5001: S 741951920:

741951920(0) win 5840

22:33:25.826161 IP 71.157.X.X.5001 > 144.202.X.X.54922: S 264203278:

264203278(0) ack 741951921 win 5792 842078832,nop,wscale 5>

22:33:25.826263 IP 144.202.X.X.54922 > 71.157.X.X.5001: . ack 1 win 92

22:33:25.826612 IP 144.202.X.X.54922 > 71.157.X.X.5001: P 1:8(7) ❺ack 1 win

92

0x0000: 4500 003b 53c2 4000 4006 1d94 0000 0000 E..;S.@.@...G..5

0x0010: 0000 0000 d68a 1389 2c39 49b1 0fbf 6c0f G..3....,9I...l.

0x0020: 8018 005c b82a 0000 0101 080a 3231 1a70 ...\.*......21.p

0x0030: 269f 4e67 7465 7374 6572 0a &.Ng❻tester.

22:33:25.826665 IP 71.157.X.X.5001 > 144.202.X.X.54922: ❼R

264203279:264203279(0) win 0

At ❶, we start by including a rule to ACCEPT connections to TCP port 5001, followed by a rule to terminate connections that contain the tester string. At ❷, a TCP server is bound to port 5001, and the next line shows the string sent across a TCP connection with port 5001 on the firewall. At ❸, tcpdump is invoked with the -s 0 argument to make sure all application layer data (some of which has been abbreviated) is captured, and with -X, to dump the application layer data to the display. You can see the TCP three-way handshake begin at ❹, and at ❺ you can see that the packet before the RST is sent has the ACK bit set and contains the string tester at ❻. Finally, at ❼, the RST is generated. (Note that there is a sequence number in bold, but that the ACK control bit is not set, because the previous packet contained the ACK bit.)

Intrusion Detection Systems and RST Generation

Even though RFC 793 is quite clear about the circumstances under which a RST packet contains an acknowledgment value and corresponding ACK control bit, many intrusion detection systems do not follow the RFC when generating RST packets to knock down TCP sessions. For example, in the Snort IDS, both the flexresp and flexresp2 detection plug-ins hard-code both the RST and ACK control bits on any RST packet they send in response to detecting an attack, and at least one commercial IDS product (which shall remain nameless) does the same thing. Conversely, the Snort react detection plug-in never sets the ACK control flag even though it includes nonzero acknowledgment numbers in the RST packets it sends. On average, because Snort rules usually contain application matching requirements and packets that contain data within TCP connections have the ACK bit set, the react detection plug-in implements a better strategy than the flexresp or flexresp2 plug-ins (at least

Return Main Page Previous Page Next Page

®Online Book Reader