Nytro Posted August 6, 2009 Report Posted August 6, 2009 [==============================================================================][------------------------[Locating Stateless Firewalls]------------------------][==============================================================================]By: ithilgore - ithilgore.ryu.L@gmail.comsock-raw.org / sock-raw.homeunix.orgOctober 2008-------------[ Table of Contents ]------------- i. Preface ii. Stateless vs Stateful iii. Corner cases iv. Conclusion v. References[ i. Preface ]==============Firewalls. One of the main defense-mechanisms of every enterprise. The main network nodes from which nearly all traffic passes through. But these are well-worn facts and there is no point in delving into more details about how important firewalls are. This article instead, focuses on how to remotely discover characteristics which betray the actual nature of the firewall - stateless or stateful. The techniques shown use two main methods of port scanning (SYN & ACK), and unfold the thought process involved in interpreting the results. The other section demonstrates the natural weakness that definesstateless firewalls and how ambiguous configurations can lead to security holesin one's network.[ ii. Stateless vs Stateful ]=============================Nowadays, nearly everyone is moving to stateful firewalls, both for theircompleteness and their flexibility in implementing all sorts of arcane, but often needed, configurations. Nevertheless, there are are still cases where a stateless firewall might be in place - the most usual one is for host defense, where more lightweight and perhaps less "restrictive" solutions are preferred.Take for example, ipchains from Linux kernel 2.2, Windows XP SP2 and Windows2003 Server built-in firewall or simple firewalls in home networking devicesusing embedded technology.What makes a stateless firewall different from a stateful? It is its inabilityto make decisions about whether to allow a packet or not based on the packetsit has previously received and their relation to the one at hand. It does notkeep any state of the connections already taking place, and thus cannot discernif the packet which just arrived, actually belongs to one of these sessions.Every packet is examined independently of any other. The only thing that astateless firewall does, is to look up at its rule table, see if the nature ofthe packet falls into any of the categories described there and act accordingly- either blocking or allowing it to pass. As simple as that. The simplicity of its nature is what makes a stateless firewall vulnerable to the ACK scanning reconnaissance attack (and more). The KISS principle unfortunately doesn'talways induce good results.Let us examine what the actual "reactions" of both a stateful and a statelessfirewall in some usual (SYN) and unusual (ACK) cases are. It is impliedhere, that the ACK packet is not part of a three-way handshake or any otherexisting connection, but an isolated hand-crafted one. Both diagrams and tables for each kind are shown below:************ stateless firewall ************ unblocked / \ (blocked) (closed) (open) || | | |---------------->|| DROP | | | || | | | || | | | || | | | || | |SYN -|--------------------------------->| | | <======================== RST ===| | | || | | | || | | | || | | |------------------------------------------------->| <======================================== ACK ===| || | | || | | || | | unblocked / \ (blocked) (closed) (open) || | | |---------------->|| DROP | | | || | | | || | | | || | | | || | |ACK -|--------------------------------->| | | <======================== RST ===| | | || | | | || | | | || | | |------------------------------------------------->| <======================================== RST ===| || | | || | | || | |Table1:|| blocked | closed | open =======================================SYN || DROP | RST | ACK ACK || DROP | RST | RST ************ stateful firewall ************ unblocked / \ (blocked) (closed) (open) || | | |---------------->|| DROP | | | || | | | || | | | || | | | || | |SYN -|--------------------------------->| | | <======================== RST ===| | | || | | | || | | | || | | |------------------------------------------------->| <======================================== ACK ===| || | | || | | || | | unblocked / \ (blocked) (closed) (open) || | | |---------------->|| DROP | | | || | | | || | | | || | | | || | |ACK -|--------------------------------->| DROP | | || | | | || | | | || | | |------------------------------------------------->| DROP || | | || | | || | |Table2:|| blocked | closed | open ========================================SYN || DROP | RST | ACK ACK || DROP | DROP | DROPThe only way that actually lets you differentiate between a stateful anda stateless firewall is by sending an ACK packet to an *unblocked* port - either closed or open. A stateless firewall can't know if the packet is part of an already established connection on that particular port or if it is amalicious packet coming from an attacker wanting to map the network . Consequently, it will allow it to pass. On the other hand, a stateful firewallis going to look up at its state table, and if the ACK packet doesn't contain valid field values in the IP/TCP headers that indicate it is a legitimate andexpected packet, it will just drop it. [1]As far as blocked ports are concerned, it goes without saying that both kindsof firewalls will drop everything directed to them, be it a SYN, ACK orwhatever magical hand-crafted packet you can imagine.It is crucial in order to avoid confusion, to note down that when we write thata port is "unblocked", we mean, that according to the firewall rules, it is notblocked explicitly. Why did we choose this notation instead of saying it isfiltered? The following definitions will help in comprehension:1) blocked port: is the one that is disallowed ANY traffic to reach it - thefirewall will DROP everything2) filtered port: is the one that is protected by a firewall - this can expand into two things: a) blocked - the firewall will drop anything that is dictated by the filtering rule e.g drop everything that comes from host 1.2.3.4 unblocked - the firewall will let through traffic that is allowed by the filtering rule e.g allow everything that has src port 53As a result, a filtered port can appear as both "open" and "filtered" accordingto the nature of the packets that hit it. It is imperative that the above sentence is understood, since it sums up the gist of port filtering. The two following examples will try to clear things out.Example1:---------A port being queried by an address that is permitted according to the firewallruleset, will appear as unblocked. The same port being queried by an addressthat is not explicitly allowed will appear as blocked. The firewall "filters"the port by inspecting the source IP address.Example2:---------Suppose you have a port that is behind no firewall, and a port whichis behind PF/ipfilter but its ruleset explicitly says to allow passing trafficto it and also keeps a state entry. It is obvious that the responses you willget in each case will vary. The port is unblocked in both cases, but in thesecond case there is the additional protection of keeping state. Hence, it is possible to have an open port that is driven through a "filter" -a filter which doesn't DROP all packets, but will reject any non SYN-initiatingpackets which don't already belong to an existing connection (like isolated ACK packets). The nature of "filtered = blocked" will reveal itself when you hitthe above port with ACK packets, while the nature of "filtered -> unblocked"will reveal itself when you hit it with SYN packets. Of course, if you onlyhit the port with a SYN, you will never know (except if you use other techniques such as timing the rtts) that the port was behind a firewall.Keep in mind, that when performing a test scanning, a "filtered" port impliesthat our probes weren't replied, thus the port revealed its "filtered -> blocked" nature. If, for another kind of probe, the port repliesindicating that it is open, the port will appear as just "open", ignoringthe fact that it is actually protected by a firewall filter, and meaning we werelucky enough to get through the firewall. This is the notation that Nmap andnearly all network-security tools use. [2]Time to (partially) leave theory behind and witness an actual example. We aregoing to scan a Windows 2003 Server host which has the followingcharacteristics:1) IP address: 10.0.0.452) Built-in firewall is enabled and blocks everything apart from ports: 21, 80, 139, 445, 33893) Ports 21 and 80 have no listening daemon behind them, while the rest of the unfiltered ports do.We begin with a simple SYN scan - the default scanning method for Nmap:# nmap 10.0.0.45 -F -n -PN --reasonStarting Nmap 4.76 ( Nmap - Free Security Scanner For Network Exploration & Security Audits. ) at 2008-09-21 21:03 EESTInteresting ports on 10.0.0.45:Not shown: 95 filtered portsReason: 95 no-responsesPORT STATE SERVICE REASON21/tcp closed ftp reset80/tcp closed http reset139/tcp open netbios-ssn syn-ack445/tcp open microsoft-ds syn-ack3389/tcp open ms-term-serv syn-ackLet's perform the same scan, however injecting ACK packets this time, instead of SYN ones:# nmap -sA 10.0.0.45 -F -n -PN --reason Starting Nmap 4.76 ( Nmap - Free Security Scanner For Network Exploration & Security Audits. ) at 2008-09-21 21:05 EESTInteresting ports on 10.0.0.45:Not shown: 95 filtered portsReason: 95 no-responsesPORT STATE SERVICE REASON21/tcp unfiltered ftp reset80/tcp unfiltered http reset139/tcp unfiltered netbios-ssn reset445/tcp unfiltered microsoft-ds reset3389/tcp unfiltered ms-term-serv resetObserved a pattern here? While the SYN scanning showed the expected results,we can see in the second scanning that *all* unfiltered ports replied with an RST, meaning the firewall let the ACK packets pass.See what happens when we do the same at an OpenBSD host protected by thevenerable stateful firewall PF.Filtered ports: all except 14926, 61438 (both listening)root@openbsd /# cat /etc/pf.conftcp_services = "{ 14926, 61438 }"block allpass in proto tcp from any to any port $tcp_servicespass out allNote down that starting with OpenBSD 4.1, all filter rules automatically keep astate entry. Thus we omitted explicitly writing to "keep state" in the rules.On the attacker's side:# nmap 10.0.0.32 -p14926,61438 -n -PN --reasonStarting Nmap 4.76 ( Nmap - Free Security Scanner For Network Exploration & Security Audits. ) at 2008-09-21 22:56 EESTInteresting ports on 10.0.0.32:PORT STATE SERVICE REASON14926/tcp open unknown syn-ack61438/tcp open unknown syn-ack# nmap -sA 10.0.0.32 -p14926,61438 -n -PN --reasonStarting Nmap 4.76 ( Nmap - Free Security Scanner For Network Exploration & Security Audits. ) at 2008-09-21 22:57 EESTInteresting ports on 10.0.0.32:PORT STATE SERVICE REASON14926/tcp filtered unknown no-response61438/tcp filtered unknown no-responsePF tosses the ACK packets into the void, since the state entries for these two ports don't mention anything about actually expecting such a packet.We didn't finish exploring here yet though. There is also a third case. Stateful firewalls can be configured to act in a stateless manner for a subsetof their rules. As a result, the replies we'll then get, will vary according towhich port we hit. Consider a case with PF again. PF has the ability to emulate a stateless firewall behavior by writing a "no state" at the end of the ruleto which we wish to apply statelessness.root@openbsd /# cat /etc/pf.confblock allpass in proto tcp from any to any port 14926pass in proto tcp from any to any port 61438 no statepass out all# nmap 10.0.0.32 -p14926,61438 -n -PN --reasonStarting Nmap 4.76 ( Nmap - Free Security Scanner For Network Exploration & Security Audits. ) at 2008-09-21 22:58 EESTInteresting ports on 10.0.0.32:PORT STATE SERVICE REASON14926/tcp open unknown syn-ack61438/tcp open unknown syn-ack# nmap -sA 10.0.0.32 -p14926,61438 -n -PN --reasonStarting Nmap 4.76 ( Nmap - Free Security Scanner For Network Exploration & Security Audits. ) at 2008-09-21 22:58 EESTInteresting ports on 10.0.0.32:PORT STATE SERVICE REASON14926/tcp filtered unknown no-response61438/tcp unfiltered unknown resetWhile the above demonstrates a fairly simplified situation, we can see that allkinds of confusing (to the one that tries to deduce it rather than to the onewho actually implemented it) configurations might take place. Actually, theabove results might also give a hint that there may be more than meets the eye.Since, stateful inspection is used for nearly every big network nowadays, itis fairly infrequent for a firewall to be configured like that - partiallystateless and partially stateful. So what could the above results indicate?Suppose you were scanning an organization which hosts a decent number ofcomputers. The first thing that would come to mind is NAT. It means thatdifferent ports translate to different hosts and thus different personalfirewall configurations (or possibly complete lack of them). Example: suppose host 10.0.0.32 is actually a router performing NAT and has aglobally routed IP (1.2.3.4) on one of its two network interfaces. The attackerperforms the scan from outside the local network. The router forwards the portsaccording to the following rules:port 14926 --> HOST A:22port 61438 --> HOST B:3389HOST A runs Linux 2.6 with ipfilter statefully inspecting port 22 and havingdisabled access to all other ports.HOST B runs Windows Server 2003 and its firewall permits only 3389 to beaccessible.In our case, what is blocked from the two firewalls concerns only the localsegment of hosts. What influences the outside world is the fact that port 14926 is open statefully, while port 61438 statelessly.The results of our scanning the router from the outside will be almost likethe above: # nmap 1.2.3.4 -p- -n -PN --reasonStarting Nmap 4.76 ( Nmap - Free Security Scanner For Network Exploration & Security Audits. ) at 2008-09-21 22:59 EESTInteresting ports on 1.2.3.4:Not shown: 65533 filtered portsReason: 65533 no-responsesPORT STATE SERVICE REASON14926/tcp open unknown syn-ack61438/tcp open unknown syn-ack# nmap -sA 1.2.3.4 -p- -n -PN --reasonStarting Nmap 4.76 ( Nmap - Free Security Scanner For Network Exploration & Security Audits. ) at 2008-09-21 22:59 EESTInteresting ports on 1.2.3.4:Not shown: 65534 filtered portsReason: 65534 no-responsesPORT STATE SERVICE REASON61438/tcp unfiltered unknown resetNmap doesn't show port 14926 in the last case, since it is included on the biglist of filtered ports. However, we do know as attackers that this port is openaccording to the SYN scanning that took place before. Thus, we can be almostcertain that port 14926 belongs to a different host than port 61438.Of course, for the above to work, it is implied that the device performing NATuses a stateless or no firewall or else the router's firewall itself would notlet the ACK packets pass through, marking both ports as filtered and thusconfusing our inference.The following table summarizes the above.Table3:|| blocked | closed | open ================================================SYN || DROP | RST | ACK ACK || DROP | RST/DROP | RST/DROP [ iii. Corner cases ]=====================What we have seen until here assumes that the stateless firewall ruleset statesone or a combination of the following:a) Filter a range of N ports thus allowing the 65535-N ports as open. Of course differentiation between destination and source ports is possible. Filter a range of source/destination IPs, effectively blocking everything related to them.c) Use a combination of the above, resulting in allowing a specific range of IPs on a specific range of unfiltered ports.However, there is another capability that firewalls can offer:d) Filtering based on the actual header values of a network packet.Taking advantage of the additional functionality that this capability provides,can quickly result in pretty dangerous situations, where a firewall is easily penetrable. Why is that? It happens mainly, because it is often difficult toknow or at least predict the network stack behavior in certain corner cases.These extreme cases are the result of ambiguities in RFCs or a certain approachthat a vendor decided to take in implementing the kernel's network behaviorin order to support, for example, additional functionality or to solve some particular problem, always according to his own arbitrary judgment.An example is due here, since witnessing an actual real-world case will pointout the graveness of the issue. [3]Consider the case where you want to block everyone from accessing your services.However, you still want to be able to connect to anyone, thus you have to allowall egress traffic. It is fairly obvious that blocking ALL incoming traffic isnot a solution, since that would also block the packets that came as an answerto your own initiated connections to the outer world. What is left, is to perform some packet header filtering magic:- Allow everything that is NOT a SYN packet. This will allow you to receivereplies to your own outbound connections.- Block everything else.In ipchains the above would be written like this:ipchains -A input -p TCP ! -y -j ACCEPTipchains -P input DENYHow does the above sound? It may sound great, but it isn't. The problem stemsfrom the fact that there is an ambiguity on the part of "NOT a SYN packet".Actually, this might be interpreted a bit differently than you might expect. [4]Let's take a brief look into the function responsible for handling initiatingpackets. The snippet comes from /usr/src/linux-2.6.26.2/net/ipv4/tcp_input.c:static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, struct tcphdr *th, unsigned len){ struct tcp_sock *tp = tcp_sk(sk); struct inet_connection_sock *icsk = inet_csk(sk); int saved_clamp = tp->rx_opt.mss_clamp; tcp_parse_options(skb, &tp->rx_opt, 0); if (th->ack) { /* ... */ } /* No ACK in the segment */ if (th->rst) { /* rfc793: * "If the RST bit is set * * Otherwise (no ACK) drop the segment and return." */ goto discard_and_undo; } /* ... */ if (th->syn) { /* ... */ } /* ... */}What does the above tell us? Say a packet doesn't have the ACK or RST flag inthe tcp flags. In addition, suppose you hand-craft the packet so that it hasboth the SYN *and* the PSH flag on for example. According to the above, the packet will be considered a legitimate SYN packet, since the only thing that the kernel checks is if the SYN flag bit is on. It doesn't concern itself with the existence of any additional set flags. Packets containing any of the following combination of tcp flags will be seen as SYN initiating packets:Table4--------------------SYN, PSHSYN, URGSYN, FINSYN, PSH, URGSYN, PSH, FINSYN, URG, FINSYN, URG, PSH, FIN--------------------Try checking some of the above combinations of tcp-flags as scanflags againstany Linux host:#nmap -F 10.0.0.100 -n --scanflags SYNFIN -PN --reasonStarting Nmap 4.76 ( Nmap - Free Security Scanner For Network Exploration & Security Audits. ) at 2008-10-05 21:30 EESTInteresting ports on 10.0.0.100:Not shown: 98 closed portsReason: 98 resetsPORT STATE SERVICE REASON111/tcp open rpcbind syn-ack113/tcp open auth syn-ackNote that we stated that our probes will have both SYN and FIN flags on.tcpdump output on Linux host:IP 10.0.0.12.41448 > 10.0.0.100.auth: SF 3334668331:3334668331(0)IP 10.0.0.100.auth > 10.0.0.12.41448: S 975129621:975129621(0) ack 3334668332 IP 10.0.0.12.41448 > 10.0.0.100.auth: R 3334668332:3334668332(0)IP 10.0.0.12.41448 > 10.0.0.100.sunrpc: SF 3334668331:3334668331(0)IP 10.0.0.100.sunrpc > 10.0.0.12.41448: S 975740821:975740821(0) ack 3334668332 IP 10.0.0.12.41448 > 10.0.0.100.sunrpc: R 3334668332:3334668332(0) It is more clear now that a vague rule like "block all SYN packets" might givetrouble, since it might block packets that *only* have the SYN flag on, thus allowing any of Table4 flag-combination packets to pass unhindered. Note thatthe above attack works against BSD and Windows hosts as well. RFC 793 isambiguous on the matter, and most implementations, as we can see, choose toignore any additional flags combined with SYN and thus treat the correspondingpacket as a legitimate one. This ambiguity along with the nature of thestateless firewall and a possible misconfiguration could result in big securityholes.[ iv. Conclusion ]==================Summing up, using a combination of SYN and ACK scanning methods can help us determine if a firewall is stateless or not, thus providing the first step inmapping our network. The fact that a firewall may exhibit a "double" nature- partially stateless and partially stateful - is a possible indication thata NAT or other IP translation mechanism might be in place. Knowing that we haveto deal with a weak natured firewall such as a stateless one, we can try the SYN-<tcp-flag> combination technique to possibly bypass the restrictions imposed by the filtering ruleset.[ v. References ]=================[1]. Port Scanning Techniques[2]. Port Scanning Basics[3]. The Art of Software Security Assessment (Mark Dowd, John McDonald, JustinSchuh): Chapter 15 - Firewalls[4]. Ambiguities in TCP/IP - firewall bypassing:Bugtraq: Ambiguities in TCP/IP - firewall bypassing[5]. TCP/IP Illustrated Volumes 1,2[6]. Linux/BSD kernel sources + relevant man pages Quote