ufw

block invalid combinations of TCP flags

Bug #323950 reported by Ryan Giobbi
10
Affects Status Importance Assigned to Milestone
ufw
Invalid
Wishlist
Unassigned
ufw (Ubuntu)
Invalid
Wishlist
Unassigned

Bug Description

UFW may want to DROP or REJECT packets with impossible combinations of TCP flags.

Following this man page information:
--tcp-flags [!] mask comp
              Match when the TCP flags are as specified. The first argument
              is the flags which we should examine, written as a comma-sepa‐
              rated list, and the second argument is a comma-separated list of
              flags which must be set. Flags are: SYN ACK FIN RST URG PSH ALL
              NONE. Hence the command
               iptables -A FORWARD -p tcp --tcp-flags SYN,ACK,FIN,RST SYN
              will only match packets with the SYN flag set, and the ACK, FIN
              and RST flags unset.

I've been using these rules with UFW and haven't noticed any problems:

-A ufw-before-input -p TCP --tcp-flags ALL FIN,URG,PSH -j DROP
-A ufw-before-input -p TCP --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
-A ufw-before-input -p TCP --tcp-flags SYN,RST SYN,RST -j DROP
-A ufw-before-input -p TCP --tcp-flags SYN,FIN SYN,FIN -j DROP
-A ufw-before-input -p TCP --tcp-flags SYN,ACK NONE -j DROP
-A ufw-before-input -p TCP --tcp-flags RST,FIN RST,FIN -j DROP
-A ufw-before-input -p TCP --tcp-flags SYN,URG SYN,URG -j DROP
-A ufw-before-input -p TCP --tcp-flags ALL SYN,PSH -j DROP
-A ufw-before-input -p TCP --tcp-flags ALL SYN,ACK,PSH -j DROP

Changed in ufw:
importance: Undecided → Wishlist
Changed in ufw:
status: New → Confirmed
Changed in ufw (Ubuntu):
status: New → Confirmed
importance: Undecided → Wishlist
Revision history for this message
PatRiehecky (jcpunk) wrote :

I figured I would put forth a patch to implement the simplest starting ground. Established connections aren't overly protected by this (there are some easy things to do), but a basic bad flags scan will be blocked.

Revision history for this message
Ryan Giobbi (ryan-tgbemail) wrote : Re: [Bug 323950] Re: block invalid combinations of TCP flags

They look very reasonable - great job!

On Fri, Nov 13, 2009 at 12:05 PM, PatRiehecky <email address hidden> wrote:
> I figured I would put forth a patch to implement the simplest starting
> ground.  Established connections aren't overly protected by this (there
> are some easy things to do), but a basic bad flags scan will be blocked.
>
> ** Attachment added: "Basic bad flags block"
>   http://launchpadlibrarian.net/35658585/tcpflags.patch
>
> --
> block invalid combinations of TCP flags
> https://bugs.launchpad.net/bugs/323950
> You received this bug notification because you are a direct subscriber
> of the bug.
>

Revision history for this message
Ryan Giobbi (ryan-tgbemail) wrote :

These rules can be applied to ipv6 connections also (switch iptables
to ip6table).

On Fri, Nov 13, 2009 at 12:05 PM, PatRiehecky <email address hidden> wrote:
> I figured I would put forth a patch to implement the simplest starting
> ground.  Established connections aren't overly protected by this (there
> are some easy things to do), but a basic bad flags scan will be blocked.
>
> ** Attachment added: "Basic bad flags block"
>   http://launchpadlibrarian.net/35658585/tcpflags.patch
>
> --
> block invalid combinations of TCP flags
> https://bugs.launchpad.net/bugs/323950
> You received this bug notification because you are a direct subscriber
> of the bug.
>

Revision history for this message
PatRiehecky (jcpunk) wrote :

I believe I built the patch to update both rule sets.... I may have botched it (and it wouldn't be the first time I've done that), but my intent was for the first section to update IPv6 and the second to do v4.

Revision history for this message
Ryan Giobbi (ryan-tgbemail) wrote :

Got it, looks good.

On Fri, Nov 20, 2009 at 5:18 PM, PatRiehecky <email address hidden> wrote:
> I believe I built the patch to update both rule sets.... I may have
> botched it (and it wouldn't be the first time I've done that), but my
> intent was for the first section to update IPv6 and the second to do v4.
>
> --
> block invalid combinations of TCP flags
> https://bugs.launchpad.net/bugs/323950
> You received this bug notification because you are a direct subscriber
> of the bug.
>

Changed in ufw:
status: Confirmed → Triaged
Changed in ufw (Ubuntu):
milestone: none → ubuntu-10.04
status: Confirmed → Triaged
Revision history for this message
Jamie Strandboge (jdstrand) wrote :

The following lines were put into /etc/ufw/before.rules to address invalid combinations of tcp flags in the first place:
# drop INVALID packets (logs these in loglevel medium and higher)
-A ufw-before-input -m state --state INVALID -j ufw-logging-deny
-A ufw-before-input -m state --state INVALID -j DROP

Due to this bug, I looked into this quite a bit, and in my research and testing I have found that the above rule does block these packets already.

Reading the man page for iptables reveals:
       INVALID
              meaning that the packet is associated with no known connection
...
       [!] --state state
              Where state is a comma separated list of the connection states
              to match. Possible states are INVALID meaning that the packet
              could not be identified for some reason which includes running
              out of memory and ICMP errors which don't correspond to any
              known connection

That man page does not explicitly state that incorrect combinations of tcp flags are marked INVALID, so I looked at the kernel source (netfilter/nf_conntrack_proto_tcp.c), and it has the following:
        /* Check TCP flags. */
        tcpflags = (((u_int8_t *)th)[13] & ~(TH_ECE|TH_CWR|TH_PUSH));
        if (!tcp_valid_flags[tcpflags]) {
                if (LOG_INVALID(net, IPPROTO_TCP))
                        nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
                                  "nf_ct_tcp: invalid TCP flag combination ");
                return -NF_ACCEPT;

Interestingly, the kernel code also has:
/* "Be conservative in what you do,
    be liberal in what you accept from others."
    If it's non-zero, we mark only out of window RST segments as INVALID. */
static int nf_ct_tcp_be_liberal __read_mostly = 0;

However, it still will mark packets with incorrect combinations of tcp flags as INVALID when using that sysctl value (I didn't look any further into this, because the default on Ubuntu is to have this set to '0'):
sudo sysctl net.ipv4.netfilter.ip_conntrack_tcp_be_liberal=1

The invalid combinations I was most interested in blocking were:
Christmas: ALL FIN,URG,PSH (nmap -sX)
NULL scan: ALL NONE (nmap -sN)
SYN,RST SYN,RST (nmap --scanflags SYNRST)
SYN,FIN SYN,FIN (nmap --scanflags SYNFIN)
ALL FIN (nmap -sF)

and all of the above are blocked in the default ufw configuration. Please remember that ufw sets up a stateful firewall and is not a simple packet filter. From the nmap man page:
...
           The key advantage to these scan types is that they can sneak
           through certain non-stateful firewalls and packet filtering
           routers.
...

Also note, that depending on the version of ufw you are using, the INVALID packets won't be logged unless you are at loglevel medium or higher (but they are always blocked).

If you want to test this yourself, it might be easier to change this line:
-A ufw-before-input -m state --state INVALID -j ufw-logging-deny

to:
-A ufw-before-input -m state --state INVALID -j LOG --log-prefix "[UFW BLOCK INVALID] "

then perform:
sudo ufw reload

Changed in ufw:
status: Triaged → Invalid
Changed in ufw (Ubuntu):
status: Triaged → Invalid
Revision history for this message
PatRiehecky (jcpunk) wrote :

Thanks for your research into the kernel source, it was most helpful in determining what INVALID does (as you mentioned the man pages are a bit vague there).

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Duplicates of this bug

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.