Tuesday, March 5, 2013

filtering bad tcp_flags


In this blog we will speak of filtering  bad tcp_flags combos. TCP uses 6 primary flags for control of a tcp session. URG ACK PSH RST SYN FIN

A quick phrase to help remember the tcpflags and the ordering;

Unskilled 
Attackers
Piss-Off
Real
Security
Folks

In the tcp 3-way handshake,   ( SYN ;  SYN-ACK ; ACK ) this  is the  ordering of the 1st three flags 
that start EVERY tcp session.


In this tcp 3-way handshake, the client+server will issues certain unique  information as of their MSS value,  support for SACK and/or  WindowScaling options,etc…..
 
After a TCP session has been established, we have some tcp_fag combinations that should never exist. 

For example;

A SYN packet only comes with a SYN-ACK or by itself. So a SYN+FIN would not be a legit packet. 
( what are you trying to do, start or finish a session )

Another example of a bad packet combination;

SYN+RST  
( once again why would we try to start and reset a session )

Most bad tcp_flags combination are self-explanatory, but here’s a way to apply filtering for bad flag combinations.

(ios)


access-list 101 deny tcp any any syn fin ack   
access-list 101 deny tcp any any ack fin psh rst syn urg   
access-list 101 deny tcp any any rst syn   
access-list 101 deny tcp any any rst syn fin ack
access-list 101 deny tcp any any rst syn fin 
access-list 101 deny tcp any any syn fin   

(ios-xr)

Tue Mar  5 11:04:19.248 GMT
ipv4 access-list badflags
10 deny tcp any any ack fin syn
20 deny tcp any any established fin psh syn urg
30 deny tcp any any rst syn
40 deny tcp any any established fin syn
50 deny tcp any any fin rst syn
60 deny tcp any any fin syn


(linux) 


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

(juniper)


 filter bad_flags  {
             
            term badflgs {
                        from {
                                    source-address 0.0.0.0/0;
                                    destination-address 0.0.0.0/0;
                                    protocol tcp;
                                    source-port [ 1024-65535];
                                    destination-port 80;
                                    tcp-flags "fin | syn | rst | push | ack";
                        }
                        then {
                                    count discarded;
                                    discard;
                        }
            }
            term default-rule {
                        /* "from" anything else? */
                        then {
                                    count accepted;
                                    accept;
                        }
            }
}


In all examples, bad tcp_flags combination can be drop. If you have a stateful firewall, they should also drop these packet also.

Keep in mind the following tcp rules;

  • All tcp-datagram should have a flag set ( no null_flags )
  • Likewise, ALL flags set is not validate either
  • After the establishment of a tcp session, the SYN flag will never be seen again during that  session
  • The graceful way for tearing down a tcp session is with the FIN+ACK
  • FIN-WAIT is not a flag ( it’s a state )
  • MSS ( Max Segment Size ) is the max size of a single segment in a tcp flow, it’s not re-negotiated after the initial SYN and SYN-ACK of the 3way tcp handshake
I hope you find this post useful


Ken Felix
Freelance Network/Security Engineer
kfelix at hyperfeed dot com

No comments:

Post a Comment