Stateless Firewalls


Stateless firewalls, although straightforward in design, have some fundamental problems that surface when you use them on real-world networks.

TCP

Stateless firewalls don't maintain any state information about TCP connections, so they must use a simple set of rules to filter TCP packets. In general, stateless firewalls look for packets containing connection initiation requestspackets with the SYN flag set. In many cases, they apply network policy rules to those SYN packets and more or less let most other TCP packets go by without blocking them. This method actually works out well enough in many cases, but it can have some major security implications.

Consider a sample configuration of a stateless firewall using the older Linux ipchains firewall. Say you want to allow yourself to connect out to anywhere but not allow anyone to connect in to any of your services. The following configuration should do the trick:

ipchains -A input -p TCP ! -y -j ACCEPT ipchains -P input DENY


The first line tells the firewall to allow all inbound TCP packets that don't have the SYN flag set (indicated by ! -y). The second line tells the firewall to simply drop everything else that's inbound. The code that determines whether the packet passes the -y test is quite simple, and it's based on the contents of the tcpsyn variable. The following code sets the value of tcpsyn based on the packet's TCP header:

     /* Connection initilisation can only       * be made when the syn bit is set and       * neither of the ack or reset is       * set. */      if(tcp->syn && !(tcp->ack || tcp->rst))          tcpsyn=1;


If the tcpsyn variable is set to 1, the packet passes the -y test and the firewall treats the packet as a connection initiation packet. Therefore, any packet with the SYN flag set and the ACK and RST flags cleared is considered a connection packet.

Scanning

There are several techniques for gathering information from a host by sending TCP packets of varying degrees of sanity. One technique of note is FIN scanning, which is a method for port scanning documented by Uriel Maimon in Phrack 49, Article 15. For certain IP stacks, if you send a FIN packet to a closed port, the IP stack sends back an RST packet. If you send a FIN packet to an open port, the IP stack doesn't send anything back. Therefore, you can use FIN packets to scan a machine's ports to determine which ones are open and which are closed.

Because FIN and RST packets are more or less required for TCP's normal operation, a stateless firewall often has to let them through. If the firewall doesn't perform any outbound filtering, it can be a little more restrictive, but generally it passes these packets through to allow TCP responses. Therefore, FIN port-scanning commonly works through a stateless packet filter. Attackers can ascertain even more information about hosts behind a network, such as the OS type and version, by sending specially crafted packets.

Ambiguity with TCP SYNs

Stateless firewalls need to enforce rules on TCP connection initiation. This enforcing is normally done via a handshake involving a TCP packet with the SYN flag set, which is fairly simple to intercept and process. However, certain IP stacks accept different permutations of the SYN flag when setting up TCP connections, and these permutations might lead to exposures in stateless packet filters.

Many TCP/IP stacks initiate a connection if a packet with SYN and FIN set is sent instead of a straightforward SYN packet. If a stateless packet filter doesn't interpret this packet as a connection initiation, it could give attackers an easy way to bypass the firewall. They can simply modify their traffic to send SYN-FIN instead of SYN, and the stateless firewall might pass it along unfiltered.

Paul Starzetz posted an excellent write-up of this problem to the Bugtraq mailing list (archived at http://archives.neohapsis.com/archives/bugtraq/2002-10/0266.html), which is summarized briefly in the following list:

  • Linux Accepts any combination of TCP flags when SYN is set and ACK is clear.

  • Solaris SYN-FIN is accepted as equivalent to SYN.

  • FreeBSD Accepts combinations of SYN being set and RST and ACK being cleared.

  • Windows Accepts combinations of SYN being set and RST and ACK being cleared.

This vulnerability is rumored to have affected multiple firewalls over the years, including Cisco IOS and even early versions of Firewall-1. With this in mind, take another look at the ipchains code for recognizing connection initiation packets:

     /* Connection initilisation can only       * be made when the syn bit is set and       * neither of the ack or reset is       * set. */      if(tcp->syn && !(tcp->ack || tcp->rst))          tcpsyn=1;


You can see that a packet with SYN-FIN set would make it through the firewall. You can also see that, according to Startez's analysis, a SYN-FIN packet counts as a connection initiation packet for Linux hosts, which means someone could get through the ipchains firewall!

UDP

User Datagram Protocol (UDP) connections are a problem for stateless firewalls. In TCP, a particular packet represents a connection initiation: the SYN packet. In UDP, however, there's no such packet. This issue usually shows up when administrators try to punch the DNS protocol through the firewall.

Say you want to make a rule allowing a client computer on an internal network to talk to a DNS server outside the firewall. You would tell the firewall to allow UDP packets from that host, with source ports 1024 to 65535 destined to destination host 1.2.3.4 on destination port 53. This rule works fine, but what happens when the DNS server responds? To allow the response, you need a rule to allow UDP packets from source port 53 to destination ports 1024 to 65535.

The problem with allowing those UDP packets is that attackers could talk to any UDP service on a port between 1024 and 65535, as long as they use a source port of 53. There are some interesting UDP daemons on those high ports for most operating systems, with RPC functionality usually being the easiest target. This risk can be mitigated by host configuration and network design, but it's a fundamental limitation in stateless packet filtering technology. Figure 15-3 summarizes a sample attack of this nature.

Figure 15-3. UDP source port 53 attack for stateless firewalls


Understanding FTP

File Transfer Protocol (FTP) is a ubiquitous Internet protocol for transferring files between machines. It's an old protocol with some strange characteristics that make it particularly troublesome to firewalls. These idiosyncrasies have led to several security exposures, but before you dig into them, take a brief look at how FTP works.

FTP is a fairly straightforward line-based protocol that works over TCP. An FTP client makes a connection to port 21 of the FTP server, and this connection is known as the control connection. The user issues commands over this TCP connection, which include tasks such as logging in, listing files, and downloading and uploading files. Things get a little tricky when data is transferred over FTP, however. The actual files and directory listings aren't sent over the control connection. Instead, they are sent over a separate, new TCP connection known as the data connection. There are two main mechanisms for establishing this data connection: active FTP and passive FTP.

In active FTP, the client tells the server where to connect to transfer the data by using the PORT command. To see how it works, walk through a simple FTP transaction. Assume the client's IP address is 1.2.3.4. The code has been formatted for readability, with client traffic bolded to differentiate it from the server's data. Also, assume that each line ends in a carriage return/line feed (CLRF).

220 Welcome to the FTP server! USER ftp 331 Guest login ok, send ident as password. PASS bob@neohapsis.com 230 Guest login ok, access restrictions apply.


Up to this point, all communication has been over the control connection. Now the client wants to retrieve a file via active FTP. The first step is to specify where the server should connect:

PORT 1,2,3,4,128,10 200 PORT command successful. Consider using PASV.


This response tells the server that for the next data connection, it should connect to the client IP 1.2.3.4 on port 32778 (32778 is 128 * 256 + 10). Now the client initiates the transfer:

RETR file.txt 150 Opening BINARY mode data connection for file.txt (42 bytes).


The server then makes a TCP connection to the address and port it was given in the PORT command. This TCP connection has a special source port of 20. It sends the file's contents over this connection and then closes it. After the file transfer is completed, the server sends a transfer complete message over the control channel:

226 Transfer complete.


You can see that active FTP requires the server to be able to connect back to the client, which can be a problem in networks that use firewalls or network address translation (NAT). The passive model is a little easier to firewall, which is why it's usually enabled.

Now take a look at how the user would transfer a file using passive FTP. Instead of sending a PORT command, the client issues a PASV command. The server then tells the client where to connect for the data connection:

PASV 227 Entering Passive Mode (50,100,200,80,220,120)


The server is telling the client where to connect to perform the next data transfer. The server's IP address is 50.100.200.80, and the port that accepts the data connection is 56440 (220 * 256 + 120). The client then makes the TCP connection before sending this command on the control channel:

RETR file.txt 150 Opening ASCII mode data connection for directory listing.


The server sends the file over the data connection, and then sends the following message over the control channel when it's finished:

226 Transfer complete.


And there you have the nuts and bolts of FTP!


FTP

As you learned in the sidebar, "Understanding FTP," FTP presents a problem for most firewalls. This section focuses on an aspect of FTP that leads to a problem in stateless firewalls. Say you want to let your users use FTP to connect to machines on the Internet. You can do this easily with a stateless firewall by allowing outbound port 21 TCP connections. However, if users are using active FTP, they can initiate data transfers by telling the FTP server to connect to a port on their computer (via the PORT command). Then you see a TCP connection coming from source port 20 to your client host on a high port. A stateless firewall generally isn't going to allow arbitrary connections from the outside to the inside, which breaks active FTP (not passive FTP). It's possible to work around this problem by allowing connections with source port 20. However, allowing these connections causes a major security flaw because TCP connections with a source port of 20 are allowed through the firewall. Figure 15-4 demonstrates how this issue can be exploited to attack an XServer running on destination port 6000.

Figure 15-4. TCP source port 20 attack for stateless firewalls


Fragmentation

A stateless firewall can't keep track of fragments, so it has to deny them categorically or apply a simple set of rules to process them as they come in. Typically, these firewalls approach this by allowing any fragment that doesn't have upper-layer header information to go through. IP fragmentation was covered in Chapter 14, "Network Protocols," but you should look out for the following points:

  • Fragments with low IP offsets (1 or 2) should be dropped, as they contain pieces of information, such as TCP flags, that the firewall needs to examine.

  • Fragments with 0-offset should contain enough information to have a full protocol header; otherwise, they should be dropped. Again, the firewall needs to see the full header at once to make a decision, and a short packet can't be evaluated safely.

  • Fragments with high offsets can generally be permitted to pass.

A few classic attacks against packet-filtering firewalls, described in the following sections, are based on overlapped fragments. New implementations of packet filters are often vulnerable to these classic attacks, so inspect them carefully.

Are Fragmented Packets Handled?

The most straightforward attack is to simply fragment a packet so that the upper-layer (TCP or UDP) protocol header is split across multiple packets. Granted, only a firewall from the 1980s would be fooled by this method, but it sets the stage for more topical attacks. Figure 15-5 shows what the malicious packets would look like. A vulnerable firewall would allow both fragments through but be unable to check them because both are incomplete.

Figure 15-5. Straightforward fragment attack


How Are Offset 1 Fragments Handled?

This classic fragmentation attack involves rewriting TCP flags against a stateless packet filter. Figure 15-6 shows how this attack would unfold. It works by first sending a fragment that the firewall accepts, such as a lone FIN or RST TCP packet, to an otherwise filtered port. The second fragment has an offset of 1 and is passed by the firewall. Depending on the host's reassembly algorithm, the target machine actually honors the new data from the second fragment and changes the flags in the TCP header from FIN to SYN. In this way, the attacker has initiated a connection to an otherwise filtered port.

Figure 15-6. TCP flags rewrite fragment attack


How Are Multiple 0-Offset Fragments Handled?

Thomas Lopatic and John McDonald (one of this book's authors) came up with a similar fragmentation attack that worked against ipchains and Cisco IOS 11 routers, to a limited extent (archived at http://archives.neohapsis.com/archives/bugtraq/1999-q3/0236.html). This technique involves sending multiple 0-offset fragments. Essentially, an IP fragment with a 0-offset is sent to a firewall; the fragment contains a TCP or UDP header that matches an allow rule in the firewall's rule set. This fragment is followed by another 0-offset fragment that's much smaller, and it rewrites a few bytes of the TCP or UDP port fields. When these fragments are reassembled on the other side, a port that shouldn't be accessible can be reached. Figure 15-7 shows how this attack works. This advisory eventually spawned the creation of RFC 3128, describing the attack.

Figure 15-7. TCP ports rewrite fragment attack


The following is an excerpt of code from an old version of the ipchains stateless firewall. Review it with the points about fragments in mind:

     offset = ntohs(ip->frag_off) & IP_OFFSET;      /*       *    Don't allow a fragment of TCP 8 bytes in. Nobody       *    normal causes this. Its a cracker trying to break       *    in by doing a flag overwrite to pass the direction       *    checks.       */      if (offset == 1 && ip->protocol == IPPROTO_TCP)  {          if (!testing && net_ratelimit()) {              printk("Suspect TCP fragment.\n");              dump_packet(ip,rif,NULL,NULL,0,0);          }          return FW_BLOCK;      }


First, you can see that the firewall blocks IP fragments with an offset of 1 for TCP data. This is a good thing, and it prevents the TCP flags rewriting attack.

Now look at the following block of code. You can see that if the firewall is looking at the first fragment (an IP offset of 0), it tries to determine how much data it needs to see to make a decision about the packet. For TCP, it wants to see at least 16 bytes of TCP data.

      /* If we can't investigate ports, treat as fragment.       * It's a trucated whole packet, or a truncated first       * fragment, or a TCP first fragment of length 8-15,       * in which case the above rule stops reassembly.       */      if (offset == 0) {          unsigned int size_req;          switch (ip->protocol) {          case IPPROTO_TCP:              /* Don't care about things past flags word */              size_req = 16;              break;          case IPPROTO_UDP:          case IPPROTO_ICMP:              size_req = 8;              break;          default:              size_req = 0;          }          offset = (ntohs(ip->tot_len) < (ip->ihl<<2)+size_req);      }


If offset is 0, indicating it's a header fragment, the firewall proceeds to do a minimum size check on the packet. If there's enough data for a complete protocol header, offset is set to 0. If there isn't enough data, offset is set to 1. This means if you send a fragment with a 0-offset and a super-short length, it's treated as a non-first fragment and passed through the firewall!




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