Stateful Inspection Firewalls


Stateful inspection is a term CheckPoint coined to describe Firewall-1, but it has been assimilated into the general language as a way of describing a certain class of firewalls. It's the process of looking inside actual protocol data to enhance the firewall's functionality. It refers to peeking into layer 4, such as TCP and UDP data, and pulling out or modifying key snippets of application-layer data.

Why is stateful inspection necessary? Certain protocols are somewhat unwieldy to a firewall, particularly those that transmit information such as IP addresses and ports. For example, say you're talking to an FTP server in a corporation's demilitarized zone (DMZ). The exchange might look like this:

220 FTP server ready. USER ftp 331 Guest login ok, send your e-mail address as password. PASS jm@neohapsis.com 230 Welcome to jim's FTP server PASV 227 Entering Passive Mode (10,0,0,1,90,210) RETR test.txt


You've logged in to the FTP server and told it you want to make a passive mode connection. The server responded and told you to connect to it on IP address 10.0.0.1 and port 23250 (remember, 90 * 256 + 210). The firewall needs to solve two problems now. First, the IP address the FTP server gave you is an internal IP address and can't be reached from the Internet. Normally the firewall uses NAT so that the FTP server can be reached through an external IP, but the actual data inside the packet needs to be translated with NAT as well.

Figure 15-9 shows what goes wrong with the FTP session. The client machine, on the left, initiates an FTP connection, which the firewall permits. The FTP server tells the client to connect to it at 10.0.0.1 and port 23250. When the client does this, it ends up trying to connect to a machine that can't be reached or the wrong machine in its internal network.

Figure 15-9. Active FTP failure caused by NAT


So the firewall needs to look inside the FTP control channel and use NAT on IP addresses when appropriate. However, more processing still needs to occur for FTP to work correctly. In Figure 15-10, the connection proceeds much the same as before.

Figure 15-10. Active FTP failure caused by filtered data port


However, the firewall sees the directive to connect to the 10.0.0.1 address and rewrites it in place with the 5.6.7.8 address. The client computer knows to connect to the correct IP address. However, when the computer attempts this connection, you encounter the next obstacle. The firewall most likely doesn't allow the connection to the high TCP port, as it's a considerable security risk to allow these connections. To handle this correctly, the firewall must watch within the FTP session for the PASV response and temporarily open a hole in the firewall for the connection from the client.

Layering Issues

It's important to note that stateful inspection involves packet-oriented firewalls looking inside UDP and TCP packets for application-layer data. These firewalls aren't doing full TCP/UDP processing, so there's plenty of room for mistakes because they "peek" at a layer they don't quite understand.

FTP is a great case study for this kind of problem. Look at a class of problems related to stateful inspection of FTP. They were discovered by Thomas Lopatic and John McDonald and independently by Mikael Olsson of EnterNet Sweden AB.

What would a typical stateful inspection firewall do to detect a PASV command? It looks in each TCP segment traversing the firewall for a packet containing this string:

227 Entering Passive Mode (x,x,x,x,y,y)


After the firewall sees that string, it pulls out the IP address and port, translates it with NAT, rewrites it if necessary, checks it, and then opens a temporary hole. So you can see what this process looks like, review the following code from an old version of iptables:

    iph = skb->nh.iph;     th = (struct tcphdr *)&(((char *)iph)[iph->ihl*4]);     data = (char *)&th[1];     data_limit = skb->h.raw + skb->len;     while (data < data_limit && *data != ' ')         ++data;     while (data < data_limit && *data == ' ')         ++data;     data += 22;     if (data >= data_limit || *data != '(')         return 0;     p1 = simple_strtoul(data+1, &data, 10);     if (data >= data_limit || *data != ',')         return 0;     p2 = simple_strtoul(data+1, &data, 10);     if (data >= data_limit || *data != ',')         return 0;     p3 = simple_strtoul(data+1, &data, 10);     if (data >= data_limit || *data != ',')         return 0;     p4 = simple_strtoul(data+1, &data, 10);     if (data >= data_limit || *data != ',')         return 0;     p5 = simple_strtoul(data+1, &data, 10);     if (data >= data_limit || *data != ',')         return 0;     p6 = simple_strtoul(data+1, &data, 10);     if (data >= data_limit || *data != ')')         return 0;     to = (p1<<24) | (p2<<16) | (p3<<8) | p4;     port = (p5<<8) | p6;     /*      * Now update or create a masquerade entry for it      */     IP_MASQ_DEBUG(1-debug, "PASV response %lX:%X %X:%X detected\n", ntohl(ms->saddr), 0, to, port);


You can see that iptables uses a straightforward method of peeking into a TCP packet to look for the response string. Note that if the response is split across multiple segments or parts of the string are dropped or retransmitted, this method wouldn't work at all.

It's worse than unreliable, however; it can actually be exploited. Consider what the firewall would think of the following FTP session:

220 FTP server ready. USER 227 Entering Passive Mode (10,0,0,1,90,210) 331 Password require for 227 Entering Passive Mode (10,0,0,1,90,210).


If the 227 string is in the right place in a TCP packet, the firewall could easily be fooled into opening ports for an attacker. There are a few ways to pull off this attack. The most straightforward way is to change the maximum segment size of the TCP connection to an unusually small value. This can be done easily by setting the maximum transmission unit (MTU) on the interface to the small value. If the attacker does things right, he can create the following flow of TCP traffic (each line represents a different TCP packet):

Server packet 1: 220 FTP server ready.\r\n Client packet 1: USER AAAAAAAAAAAAAAAAA227 Entering Passive Client packet 2: Mode (10,0,0,1,90,210)\r\n Server packet 3: 331 Password required for AAAAAAAAAAAAAAAAA Server packet 4: 227 Entering Passive Mode (10,0,0,1,90,210).\r\n


You can see in this data flow that the TCP segment is split so that it looks like the 227 response is a legitimate response from the server, instead of being part of the error message. When the firewall sees this line in its own packet, it assumes the server needs to open an incoming port for a data connection.

Some firewalls sought to remedy this problem by ensuring that each packet ended in a CRLF. The attack shown in the preceding code doesn't work because the 331 response packet doesn't contain the requisite CRLF. One way around this is to create a file with a filename of 227 ... remotely in a writeable directory. Then you can enter STAT -1 in the control connection and get a directory listing, which could conceivably have CRLFs in the right place.

However, there's a more universal technique if you can write some low-level networking code. This technique a little more involved, but it can be implemented using libdnet and libpcap in a few hours. Basically, you need to acknowledge only part of the FTP server's response so that its TCP stack times out and retransmits the 227 string in its own packet. This way, both packets end in a CRLF. The flow of data would look like this:

220 FTP server ready.\r\n USER 227 Entering Passive Mode (10,0,0,1,90,210)\r\n 331 Password require for 227 Entering Passive Mode (10,0,0,1,90,210).\r\n


The client would acknowledge the TCP data right up to the 227 string in the server's response. Then the client has to wait a little while for the server to time out and retransmit the unacknowledged data. The server retransmits the data in a packet that should trick the firewall into opening up a port:

227 Entering Passive Mode (10,0,0,1,90,210).\r\n





The Art of Software Security Assessment. Identifying and Preventing Software Vulnerabilities
The Art of Software Security Assessment: Identifying and Preventing Software Vulnerabilities
ISBN: 0321444426
EAN: 2147483647
Year: 2004
Pages: 194

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net