Jump to content
Nytro

Locating Stateless Firewalls

Recommended Posts

[==============================================================================]

[------------------------[Locating Stateless Firewalls]------------------------]

[==============================================================================]

By: ithilgore - ithilgore.ryu.L@gmail.com

sock-raw.org / sock-raw.homeunix.org

October 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 defines

stateless firewalls and how ambiguous configurations can lead to security holes

in one's network.

[ ii. Stateless vs Stateful ]

=============================

Nowadays, nearly everyone is moving to stateful firewalls, both for their

completeness 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 Windows

2003 Server built-in firewall or simple firewalls in home networking devices

using embedded technology.

What makes a stateless firewall different from a stateful? It is its inability

to make decisions about whether to allow a packet or not based on the packets

it has previously received and their relation to the one at hand. It does not

keep any state of the connections already taking place, and thus cannot discern

if the packet which just arrived, actually belongs to one of these sessions.

Every packet is examined independently of any other. The only thing that a

stateless firewall does, is to look up at its rule table, see if the nature of

the 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't

always induce good results.

Let us examine what the actual "reactions" of both a stateful and a stateless

firewall in some usual (SYN) and unusual (ACK) cases are. It is implied

here, that the ACK packet is not part of a three-way handshake or any other

existing 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 | DROP

The only way that actually lets you differentiate between a stateful and

a 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 a

malicious packet coming from an attacker wanting to map the network ;).

Consequently, it will allow it to pass. On the other hand, a stateful firewall

is 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 and

expected packet, it will just drop it. [1]

As far as blocked ports are concerned, it goes without saying that both kinds

of firewalls will drop everything directed to them, be it a SYN, ACK or

whatever magical hand-crafted packet you can imagine.

It is crucial in order to avoid confusion, to note down that when we write that

a port is "unblocked", we mean, that according to the firewall rules, it is not

blocked explicitly. Why did we choose this notation instead of saying it is

filtered? The following definitions will help in comprehension:

1) blocked port: is the one that is disallowed ANY traffic to reach it - the

firewall will DROP everything

2) 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

B) unblocked - the firewall will let through traffic that is allowed by the

filtering rule e.g allow everything that has src port 53

As a result, a filtered port can appear as both "open" and "filtered" according

to 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 firewall

ruleset, will appear as unblocked. The same port being queried by an address

that 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 which

is behind PF/ipfilter but its ruleset explicitly says to allow passing traffic

to it and also keeps a state entry. It is obvious that the responses you will

get in each case will vary. The port is unblocked in both cases, but in the

second 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-initiating

packets which don't already belong to an existing connection (like isolated ACK

packets). The nature of "filtered = blocked" will reveal itself when you hit

the 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 only

hit 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 implies

that our probes weren't replied, thus the port revealed its

"filtered -> blocked" nature. If, for another kind of probe, the port replies

indicating that it is open, the port will appear as just "open", ignoring

the fact that it is actually protected by a firewall filter, and meaning we were

lucky enough to get through the firewall. This is the notation that Nmap and

nearly all network-security tools use. [2]

Time to (partially) leave theory behind and witness an actual example. We are

going to scan a Windows 2003 Server host which has the following

characteristics:

1) IP address: 10.0.0.45

2) Built-in firewall is enabled and blocks everything apart from ports:

21, 80, 139, 445, 3389

3) 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 --reason

Starting Nmap 4.76 ( Nmap - Free Security Scanner For Network Exploration & Security Audits. ) at 2008-09-21 21:03 EEST

Interesting ports on 10.0.0.45:

Not shown: 95 filtered ports

Reason: 95 no-responses

PORT STATE SERVICE REASON

21/tcp closed ftp reset

80/tcp closed http reset

139/tcp open netbios-ssn syn-ack

445/tcp open microsoft-ds syn-ack

3389/tcp open ms-term-serv syn-ack

Let'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 EEST

Interesting ports on 10.0.0.45:

Not shown: 95 filtered ports

Reason: 95 no-responses

PORT STATE SERVICE REASON

21/tcp unfiltered ftp reset

80/tcp unfiltered http reset

139/tcp unfiltered netbios-ssn reset

445/tcp unfiltered microsoft-ds reset

3389/tcp unfiltered ms-term-serv reset

Observed 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 the

venerable stateful firewall PF.

Filtered ports: all except 14926, 61438 (both listening)

root@openbsd /# cat /etc/pf.conf

tcp_services = "{ 14926, 61438 }"

block all

pass in proto tcp from any to any port $tcp_services

pass out all

Note down that starting with OpenBSD 4.1, all filter rules automatically keep a

state 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 --reason

Starting Nmap 4.76 ( Nmap - Free Security Scanner For Network Exploration & Security Audits. ) at 2008-09-21 22:56 EEST

Interesting ports on 10.0.0.32:

PORT STATE SERVICE REASON

14926/tcp open unknown syn-ack

61438/tcp open unknown syn-ack

# nmap -sA 10.0.0.32 -p14926,61438 -n -PN --reason

Starting Nmap 4.76 ( Nmap - Free Security Scanner For Network Exploration & Security Audits. ) at 2008-09-21 22:57 EEST

Interesting ports on 10.0.0.32:

PORT STATE SERVICE REASON

14926/tcp filtered unknown no-response

61438/tcp filtered unknown no-response

PF 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 subset

of their rules. As a result, the replies we'll then get, will vary according to

which 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 rule

to which we wish to apply statelessness.

root@openbsd /# cat /etc/pf.conf

block all

pass in proto tcp from any to any port 14926

pass in proto tcp from any to any port 61438 no state

pass out all

# nmap 10.0.0.32 -p14926,61438 -n -PN --reason

Starting Nmap 4.76 ( Nmap - Free Security Scanner For Network Exploration & Security Audits. ) at 2008-09-21 22:58 EEST

Interesting ports on 10.0.0.32:

PORT STATE SERVICE REASON

14926/tcp open unknown syn-ack

61438/tcp open unknown syn-ack

# nmap -sA 10.0.0.32 -p14926,61438 -n -PN --reason

Starting Nmap 4.76 ( Nmap - Free Security Scanner For Network Exploration & Security Audits. ) at 2008-09-21 22:58 EEST

Interesting ports on 10.0.0.32:

PORT STATE SERVICE REASON

14926/tcp filtered unknown no-response

61438/tcp unfiltered unknown reset

While the above demonstrates a fairly simplified situation, we can see that all

kinds of confusing (to the one that tries to deduce it rather than to the one

who actually implemented it) configurations might take place. Actually, the

above 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, it

is fairly infrequent for a firewall to be configured like that - partially

stateless and partially stateful. So what could the above results indicate?

Suppose you were scanning an organization which hosts a decent number of

computers. The first thing that would come to mind is NAT. It means that

different ports translate to different hosts and thus different personal

firewall configurations (or possibly complete lack of them).

Example: suppose host 10.0.0.32 is actually a router performing NAT and has a

globally routed IP (1.2.3.4) on one of its two network interfaces. The attacker

performs the scan from outside the local network. The router forwards the ports

according to the following rules:

port 14926 --> HOST A:22

port 61438 --> HOST B:3389

HOST A runs Linux 2.6 with ipfilter statefully inspecting port 22 and having

disabled access to all other ports.

HOST B runs Windows Server 2003 and its firewall permits only 3389 to be

accessible.

In our case, what is blocked from the two firewalls concerns only the local

segment 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 like

the above:

# nmap 1.2.3.4 -p- -n -PN --reason

Starting Nmap 4.76 ( Nmap - Free Security Scanner For Network Exploration & Security Audits. ) at 2008-09-21 22:59 EEST

Interesting ports on 1.2.3.4:

Not shown: 65533 filtered ports

Reason: 65533 no-responses

PORT STATE SERVICE REASON

14926/tcp open unknown syn-ack

61438/tcp open unknown syn-ack

# nmap -sA 1.2.3.4 -p- -n -PN --reason

Starting Nmap 4.76 ( Nmap - Free Security Scanner For Network Exploration & Security Audits. ) at 2008-09-21 22:59 EEST

Interesting ports on 1.2.3.4:

Not shown: 65534 filtered ports

Reason: 65534 no-responses

PORT STATE SERVICE REASON

61438/tcp unfiltered unknown reset

Nmap doesn't show port 14926 in the last case, since it is included on the big

list of filtered ports. However, we do know as attackers that this port is open

according to the SYN scanning that took place before. Thus, we can be almost

certain 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 NAT

uses a stateless or no firewall or else the router's firewall itself would not

let the ACK packets pass through, marking both ports as filtered and thus

confusing 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 states

one 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.

B) 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 to

know 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 approach

that a vendor decided to take in implementing the kernel's network behavior

in 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 point

out 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 allow

all egress traffic. It is fairly obvious that blocking ALL incoming traffic is

not a solution, since that would also block the packets that came as an answer

to 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 receive

replies to your own outbound connections.

- Block everything else.

In ipchains the above would be written like this:

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

ipchains -P input DENY

How does the above sound? It may sound great, but it isn't. The problem stems

from 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 initiating

packets. 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 in

the tcp flags. In addition, suppose you hand-craft the packet so that it has

both 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, PSH

SYN, URG

SYN, FIN

SYN, PSH, URG

SYN, PSH, FIN

SYN, URG, FIN

SYN, URG, PSH, FIN

--------------------

Try checking some of the above combinations of tcp-flags as scanflags against

any Linux host:

#nmap -F 10.0.0.100 -n --scanflags SYNFIN -PN --reason

Starting Nmap 4.76 ( Nmap - Free Security Scanner For Network Exploration & Security Audits. ) at 2008-10-05 21:30 EEST

Interesting ports on 10.0.0.100:

Not shown: 98 closed ports

Reason: 98 resets

PORT STATE SERVICE REASON

111/tcp open rpcbind syn-ack

113/tcp open auth syn-ack

Note 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 give

trouble, since it might block packets that *only* have the SYN flag on, thus

allowing any of Table4 flag-combination packets to pass unhindered. Note that

the above attack works against BSD and Windows hosts as well. RFC 793 is

ambiguous on the matter, and most implementations, as we can see, choose to

ignore any additional flags combined with SYN and thus treat the corresponding

packet as a legitimate one. This ambiguity along with the nature of the

stateless firewall and a possible misconfiguration could result in big security

holes.

[ 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 in

mapping our network. The fact that a firewall may exhibit a "double" nature

- partially stateless and partially stateful - is a possible indication that

a NAT or other IP translation mechanism might be in place. Knowing that we have

to 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, Justin

Schuh): 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

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...