LinuxQuestions.org
View the Most Wanted LQ Wiki articles.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Security
User Name
Password
Linux - Security This forum is for all security related questions.
Questions, tips, system compromises, firewalls, etc. are all included here.

Notices

Reply
 
LinkBack Search this Thread
Old 11-03-2008, 06:28 AM   #1
win32sux
Guru
 
Registered: Jul 2003
Location: Los Angeles
Distribution: Ubuntu
Posts: 9,870

Rep: Reputation: 371Reputation: 371Reputation: 371Reputation: 371
Arrow iptables good packet chain (instead of bad packet chain)


Almost anyone who's used Netfilter/iptables for packet-filtering is familiar with "bad packet chains". They are user-built chains with rules that match packets with characteristics you consider to be "bad", mainly unusual TCP flag combinations. Essentially, a bad packet chain is a packet blacklist (default allow).

I've often wondered if anyone has ever taken the opposite approach. That is, use a whitelist (default deny) to create a "good packet chain" instead. Default deny has shown to be a much more solid approach than default allow when it comes to information security in general, and I would like to know if it is feasible to use it in this particular context.

Some specific questions I have might be: Would it be asking for trouble? Would it take too much work to build this kind of chain? Is it worth the effort? Your opinions on these and any other relevant questions would be greatly appreciated.

Last edited by win32sux; 11-03-2008 at 06:45 AM.
 
Old 11-03-2008, 07:47 AM   #2
estabroo
Senior Member
 
Registered: Jun 2008
Distribution: debian, ubuntu, sidux
Posts: 1,091
Blog Entries: 2

Rep: Reputation: 109Reputation: 109
Its definitely worth the effort. It is more secure especially if you default deny on all 3 main chains (input, forward, output). When you are first setting it up make sure you do it on a local machine that you have console access because more than likely you'll lock yourself out network wise at least once. Usually people only need a few "good" rules, though output can be messy which leads most people to just doing the deny on input and forward (which is still a good idea).
 
Old 11-03-2008, 08:30 AM   #3
win32sux
Guru
 
Registered: Jul 2003
Location: Los Angeles
Distribution: Ubuntu
Posts: 9,870

Original Poster
Rep: Reputation: 371Reputation: 371Reputation: 371Reputation: 371
Quote:
Originally Posted by estabroo View Post
Its definitely worth the effort. It is more secure especially if you default deny on all 3 main chains (input, forward, output). When you are first setting it up make sure you do it on a local machine that you have console access because more than likely you'll lock yourself out network wise at least once. Usually people only need a few "good" rules, though output can be messy which leads most people to just doing the deny on input and forward (which is still a good idea).
It seems you've misunderstood my question. I'm not referring to default policies for the built-in chains. I'm referring specifically to user-built chains designed to filter packets with bad TCP flag combinations. These chains are AFAICT always designed using a default allow approach (not a policy, as user-built chains don't have policies). My question is about changing from a "match all packets with weird TCP flag combinations" approach to a "match all packets with proper TCP flag combinations" one. Whatever you've got set as a default policy for your built-in chains is irrelevant in this case. Thanks for your reply, though, as it allows me to clarify my question - something I was expecting I would need to do.

Last edited by win32sux; 11-03-2008 at 09:07 AM. Reason: Spelling/grammar.
 
Old 11-03-2008, 09:08 AM   #4
estabroo
Senior Member
 
Registered: Jun 2008
Distribution: debian, ubuntu, sidux
Posts: 1,091
Blog Entries: 2

Rep: Reputation: 109Reputation: 109
hehe, glad I could be of some service at least, sorry it wasn't to answer the question
 
Old 11-04-2008, 07:13 AM   #5
win32sux
Guru
 
Registered: Jul 2003
Location: Los Angeles
Distribution: Ubuntu
Posts: 9,870

Original Poster
Rep: Reputation: 371Reputation: 371Reputation: 371Reputation: 371
You can see an example of a typical bad packet chain here:
Code:
# Our "hey, them's some bad tcp flags!" chain.
$IPT -N badflags
$IPT -A badflags -m limit --limit 15/minute -j LOG --log-prefix Badflags:
$IPT -A badflags -j DROP

# Drop those nasty packets! These are all TCP flag 
# combinations that should never, ever occur in the
# wild. All of these are illegal combinations that 
# are used to attack a box in various ways, so we 
# just drop them and log them here.
$IPT -A INPUT -p tcp --tcp-flags ALL FIN,URG,PSH -j badflags
$IPT -A INPUT -p tcp --tcp-flags ALL ALL -j badflags
$IPT -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j badflags
$IPT -A INPUT -p tcp --tcp-flags ALL NONE -j badflags
$IPT -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j badflags
$IPT -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j badflags
As you can see, the chain sends to LOG and then to DROP any packets which are determined to have a weird combination of TCP flags. There are, of course, much more lengthy bad packet chains out there - this is just an example.

The idea I've been kicking around is to do the inverse, kinda like this:
Code:
$IPT -N GOOD_FLAGS
$IPT -A GOOD_FLAGS -p TCP --tcp-flags SYN,RST,ACK,FIN SYN -j ACCEPT
# The list of ACCEPT rules continues here.
$IPT -A GOOD_FLAGS -j LOG --log-prefix "BAD FLAGS: "
$IPT -A GOOD_FLAGS -j DROP
As you can see, this would send to ACCEPT any packet with a valid TCP flag combination, and those which don't have one will get sent to LOG and then to DROP. I've only used one possible ACCEPT rule to illustrate, the idea is of course to have enough rules to cover all proper TCP flag combinations (instead of trying to cover as many bad ones as possible).

Last edited by win32sux; 11-04-2008 at 07:14 AM.
 
Old 11-04-2008, 11:05 AM   #6
win32sux
Guru
 
Registered: Jul 2003
Location: Los Angeles
Distribution: Ubuntu
Posts: 9,870

Original Poster
Rep: Reputation: 371Reputation: 371Reputation: 371Reputation: 371
Okay, I decided to go for it and get started with a proof-of-concept. I've made a CHECK_FLAGS chain with matches for the TCP flag combinations which AFAIK I need for the handshake, data transfer, and termination phases. Here's the rules I'm using to test right now, with INPUT policy set to DROP and OUTPUT policy set to ACCEPT. This is on my laptop, which does run one service (BitTorrent), so the TCP flags I'm checking include both client and server angles.
Code:
$IPT -N CHECK_FLAGS
$IPT -A CHECK_FLAGS -p TCP --tcp-flags SYN,ACK,FIN,RST ACK -j ACCEPT
$IPT -A CHECK_FLAGS -p TCP --tcp-flags SYN,ACK,FIN,RST SYN,ACK -j ACCEPT
$IPT -A CHECK_FLAGS -p TCP --tcp-flags SYN,ACK,FIN,RST RST -j ACCEPT
$IPT -A CHECK_FLAGS -p TCP --tcp-flags SYN,ACK,FIN,RST RST,ACK -j ACCEPT
$IPT -A CHECK_FLAGS -p TCP --tcp-flags SYN,ACK,FIN,RST FIN -j ACCEPT
$IPT -A CHECK_FLAGS -p TCP --tcp-flags SYN,ACK,FIN,RST FIN,ACK -j ACCEPT
$IPT -A CHECK_FLAGS -j LOG --log-prefix "BAD TCP FLAGS: "
$IPT -A CHECK_FLAGS -j DROP

$IPT -A INPUT -i lo -j ACCEPT
$IPT -A INPUT -p TCP -m state --state ESTABLISHED -j CHECK_FLAGS
$IPT -A INPUT -p UDP -m state --state ESTABLISHED -j ACCEPT

$IPT -A INPUT -p TCP ! --syn -m state --state NEW -j LOG --log-prefix "NEW NOT SYN: "
$IPT -A INPUT -p TCP ! --syn -m state --state NEW -j DROP

$IPT -A INPUT -p ICMP -m state --state RELATED -j ACCEPT

$IPT -A INPUT -p TCP --dport 6881 -m state --state NEW -j ACCEPT

$IPT -A INPUT -j LOG --log-prefix "INPUT DROP: "
A few things to note: I'm only checking packets in the ESTABLISHED state, as the check for packets in state NEW is a one-liner (they need to have the SYN bit set and the RST, ACK, and FIN bits unset, which is what the --syn match does). Since I know that for my laptop all incoming packets in state RELATED should be ICMP, I'm just sending to DROP any which aren't. Of course, every packet sent to DROP is sent to LOG first so that I may spot problems. So far the CHECK_FLAGS chain seems to be working just fine, but I'm expecting that I'll need to make changes after I've tested it more thoroughly.

Last edited by win32sux; 11-04-2008 at 10:09 PM.
 
Old 11-06-2008, 06:02 AM   #7
win32sux
Guru
 
Registered: Jul 2003
Location: Los Angeles
Distribution: Ubuntu
Posts: 9,870

Original Poster
Rep: Reputation: 371Reputation: 371Reputation: 371Reputation: 371
Okay, after a couple days worth of testing, I've concluded that the whitelist approach is feasible. I can also say somewhat less conclusively (I still need to do more testing) that it works well. That said, I haven't really finished the chain yet, as I haven't been able to decide on how to deal with bad PSH and URG flags yet (I could easily do some blacklisting, but the whole point of my endeavor is to do whitelisting only).

Here's what I've got so far:
Code:
$IPT -N CHECK_TCP_FLAGS
$IPT -A CHECK_TCP_FLAGS -p TCP --tcp-flags SYN,ACK,FIN,RST ACK -j ACCEPT
$IPT -A CHECK_TCP_FLAGS -p TCP --tcp-flags SYN,ACK,FIN,RST SYN -j ACCEPT
$IPT -A CHECK_TCP_FLAGS -p TCP --tcp-flags SYN,ACK,FIN,RST SYN,ACK -j ACCEPT
$IPT -A CHECK_TCP_FLAGS -p TCP --tcp-flags SYN,ACK,FIN,RST RST -j ACCEPT
$IPT -A CHECK_TCP_FLAGS -p TCP --tcp-flags SYN,ACK,FIN,RST RST,ACK -j ACCEPT
$IPT -A CHECK_TCP_FLAGS -p TCP --tcp-flags SYN,ACK,FIN,RST FIN -j ACCEPT
$IPT -A CHECK_TCP_FLAGS -p TCP --tcp-flags SYN,ACK,FIN,RST FIN,ACK -j ACCEPT
$IPT -A CHECK_TCP_FLAGS -j LOG --log-prefix "BAD TCP FLAGS: "
$IPT -A CHECK_TCP_FLAGS -j DROP

$IPT -A INPUT -i lo -j ACCEPT
$IPT -A INPUT -p TCP -m state --state ESTABLISHED -j CHECK_TCP_FLAGS
$IPT -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
$IPT -A INPUT -p TCP --dport 6881 --syn -m state --state NEW -j ACCEPT
$IPT -A INPUT -j LOG --log-prefix "INPUT DROP: "
As you can see, pretty much the only thing that's changed since my last post is the addition of a match in the CHECK_TCP_FLAGS chain for packets with the SYN bit set (I've put the rule in bold). With that rule commented, I get several SYN packets being sent to DROP. This is interesting, as these are packets which the kernel sees as being in the ESTABLISHED state (otherwise they wouldn't be traversing that chain). Here's a sample from my log file to show you what I mean:
Quote:
Nov 6 05:22:56 candystore kernel: [ 7109.994754] BAD TCP FLAGS: IN=wlan0 OUT= MAC=01:18:de:b4:b8:c0:00:13:cf:1d:12:3c:08:00 SRC=80.173.8.58 DST=192.168.1.100 LEN=64 TOS=0x00 PREC=0x00 TTL=52 ID=5636 DF PROTO=TCP SPT=53143 DPT=6881 WINDOW=65535 RES=0x00 SYN URGP=0
Nov 6 05:22:59 candystore kernel: [ 7110.558050] BAD TCP FLAGS: IN=wlan0 OUT= MAC=01:18:de:b4:b8:c0:00:13:cf:1d:12:3c:08:00 SRC=80.173.8.58 DST=192.168.1.100 LEN=64 TOS=0x00 PREC=0x00 TTL=52 ID=5898 DF PROTO=TCP SPT=53143 DPT=6881 WINDOW=65535 RES=0x00 SYN URGP=0
Nov 6 05:23:04 candystore kernel: [ 7111.642276] BAD TCP FLAGS: IN=wlan0 OUT= MAC=01:18:de:b4:b8:c0:00:13:cf:1d:12:3c:08:00 SRC=80.173.8.58 DST=192.168.1.100 LEN=64 TOS=0x00 PREC=0x00 TTL=52 ID=6410 DF PROTO=TCP SPT=53164 DPT=6881 WINDOW=65535 RES=0x00 SYN URGP=0
Nov 6 05:23:07 candystore kernel: [ 7112.320472] BAD TCP FLAGS: IN=wlan0 OUT= MAC=01:18:de:b4:b8:c0:00:13:cf:1d:12:3c:08:00 SRC=80.173.8.58 DST=192.168.1.100 LEN=64 TOS=0x00 PREC=0x00 TTL=52 ID=6667 DF PROTO=TCP SPT=53164 DPT=6881 WINDOW=65535 RES=0x00 SYN URGP=0
Nov 6 05:23:11 candystore kernel: [ 7113.216864] BAD TCP FLAGS: IN=wlan0 OUT= MAC=01:18:de:b4:b8:c0:00:13:cf:1d:12:3c:08:00 SRC=80.173.8.58 DST=192.168.1.100 LEN=48 TOS=0x00 PREC=0x00 TTL=52 ID=6993 DF PROTO=TCP SPT=53164 DPT=6881 WINDOW=65535 RES=0x00 SYN URGP=0
Nov 6 05:23:27 candystore kernel: [ 7116.773364] BAD TCP FLAGS: IN=wlan0 OUT= MAC=01:18:de:b4:b8:c0:00:13:cf:1d:12:3c:08:00 SRC=75.34.32.251 DST=192.168.1.100 LEN=48 TOS=0x00 PREC=0x00 TTL=118 ID=49628 DF PROTO=TCP SPT=3151 DPT=6881 WINDOW=64240 RES=0x00 SYN URGP=0
Nov 6 05:24:09 candystore kernel: [ 7125.650846] BAD TCP FLAGS: IN=wlan0 OUT= MAC=01:18:de:b4:b8:c0:00:13:cf:1d:12:3c:08:00 SRC=79.220.62.58 DST=192.168.1.100 LEN=64 TOS=0x00 PREC=0x00 TTL=54 ID=48585 DF PROTO=TCP SPT=43137 DPT=6881 WINDOW=65535 RES=0x00 SYN URGP=0
Nov 6 05:24:32 candystore kernel: [ 7130.554235] BAD TCP FLAGS: IN=wlan0 OUT= MAC=01:18:de:b4:b8:c0:00:13:cf:1d:12:3c:08:00 SRC=218.242.68.109 DST=192.168.1.100 LEN=52 TOS=0x00 PREC=0x00 TTL=52 ID=51218 DF PROTO=TCP SPT=15772 DPT=6881 WINDOW=65535 RES=0x00 SYN URGP=0
Nov 6 05:25:20 candystore kernel: [ 7140.799262] BAD TCP FLAGS: IN=wlan0 OUT= MAC=01:18:de:b4:b8:c0:00:13:cf:1d:12:3c:08:00 SRC=203.176.178.23 DST=192.168.1.100 LEN=64 TOS=0x00 PREC=0x00 TTL=53 ID=52041 DF PROTO=TCP SPT=50996 DPT=6881 WINDOW=65535 RES=0x00 SYN URGP=0
Nov 6 05:25:25 candystore kernel: [ 7141.944061] BAD TCP FLAGS: IN=wlan0 OUT= MAC=01:18:de:b4:b8:c0:00:13:cf:1d:12:3c:08:00 SRC=203.176.178.23 DST=192.168.1.100 LEN=64 TOS=0x00 PREC=0x00 TTL=53 ID=57190 DF PROTO=TCP SPT=50996 DPT=6881 WINDOW=65535 RES=0x00 SYN URGP=0
Nov 6 05:26:32 candystore kernel: [ 7156.678510] BAD TCP FLAGS: IN=wlan0 OUT= MAC=01:18:de:b4:b8:c0:00:13:cf:1d:12:3c:08:00 SRC=82.11.32.84 DST=192.168.1.100 LEN=64 TOS=0x00 PREC=0x00 TTL=53 ID=40447 DF PROTO=TCP SPT=62799 DPT=6881 WINDOW=65535 RES=0x00 SYN URGP=0
Nov 6 05:29:28 candystore kernel: [ 7195.533458] BAD TCP FLAGS: IN=wlan0 OUT= MAC=01:18:de:b4:b8:c0:00:13:cf:1d:12:3c:08:00 SRC=80.179.37.252 DST=192.168.1.100 LEN=60 TOS=0x00 PREC=0x00 TTL=54 ID=41365 DF PROTO=TCP SPT=53183 DPT=6881 WINDOW=5840 RES=0x00 SYN URGP=0
Nov 6 05:29:34 candystore kernel: [ 7197.818324] BAD TCP FLAGS: IN=wlan0 OUT= MAC=01:18:de:b4:b8:c0:00:13:cf:1d:12:3c:08:00 SRC=90.25.251.215 DST=192.168.1.100 LEN=64 TOS=0x00 PREC=0x00 TTL=52 ID=37093 DF PROTO=TCP SPT=58356 DPT=6881 WINDOW=65535 RES=0x00 SYN URGP=0
Nov 6 05:29:50 candystore kernel: [ 7204.241106] BAD TCP FLAGS: IN=wlan0 OUT= MAC=01:18:de:b4:b8:c0:00:13:cf:1d:12:3c:08:00 SRC=79.220.62.58 DST=192.168.1.100 LEN=64 TOS=0x00 PREC=0x00 TTL=54 ID=52674 DF PROTO=TCP SPT=33283 DPT=6881 WINDOW=65535 RES=0x00 SYN URGP=0
Nov 6 05:30:17 candystore kernel: [ 7215.477959] BAD TCP FLAGS: IN=wlan0 OUT= MAC=01:18:de:b4:b8:c0:00:13:cf:1d:12:3c:08:00 SRC=72.201.198.107 DST=192.168.1.100 LEN=60 TOS=0x00 PREC=0x00 TTL=56 ID=2813 DF PROTO=TCP SPT=55044 DPT=6881 WINDOW=5840 RES=0x00 SYN URGP=0
I used QUOTE tags instead of CODE tags for that as otherwise the page rendering gets all weird and stuff, sorry. Can anyone shed some light as to what conditions would make Linux/Netfilter treat certain SYN packets as being in the ESTABLISHED state?

Last edited by win32sux; 11-06-2008 at 11:11 AM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Which is the chain name in iptables dkn4a1 Linux - Software 4 09-22-2008 05:23 AM
userdefined chain in iptables yawe_frek Red Hat 2 11-28-2006 06:20 AM
Bad Packet Chain (iptables) Feedback / Suggestions win32sux Linux - Security 1 09-17-2005 07:32 AM
iptables chain modification gizza23 Linux - Networking 2 07-10-2005 05:45 AM
iptables and LD chain spawing? lode Linux - Networking 8 04-21-2004 03:30 AM


All times are GMT -5. The time now is 12:16 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration