* iptables STILL incorrectly using TCP packet contents without checking header!
@ 2005-03-31 18:57 Simon Kirby
2005-03-31 20:04 ` Jonas Berlin
0 siblings, 1 reply; 6+ messages in thread
From: Simon Kirby @ 2005-03-31 18:57 UTC (permalink / raw)
To: netfilter-devel
Hi,
Since my post in December, iptables is STILL incorrectly using TCP packet
contents without checking the header. I bet this is resulting in dropped
connections and other issues all over the place but people aren't easily
able to see why.
Example:
iptables -A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset
These two lines will set up a typical stateful TCP firewall that blocks
anything incoming that isn't related to outgoing traffic. Unfortunately,
it also immediately disconnects any TCP sessions as soon as a corrupted
packet is received. Why? Because:
The "state" module checks the TCP checksum. Good.
The REJECT module uses TCP data without checking the checksum. Bad.
In fact, a simple "-p tcp --dport 80" also matches without checking the
TCP checksum. This is bad -- the port could be corrupted!
IMHO:
1: -p tcp needs to verify that the IP header is valid (it probably does
this already), since the protocol is specified there.
2: -p tcp --dport 80 needs to verify that the IP _AND_ TCP header is
valid, since the port is in the TCP header. It does not do this now.
3: REJECT needs to verify that the data it is using in --tcp-reset is
actually valid, because it can be used with just "-p tcp". ICMP
REJECT might also need checking.
Right? Does this make sense? Anyone?
(Yes, I'll fix the corrupted packets next..)
Simon-
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: iptables STILL incorrectly using TCP packet contents without checking header!
2005-03-31 18:57 iptables STILL incorrectly using TCP packet contents without checking header! Simon Kirby
@ 2005-03-31 20:04 ` Jonas Berlin
2005-03-31 23:27 ` Henrik Nordstrom
2005-04-01 0:03 ` Simon Kirby
0 siblings, 2 replies; 6+ messages in thread
From: Jonas Berlin @ 2005-03-31 20:04 UTC (permalink / raw)
To: Simon Kirby; +Cc: netfilter-devel
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Simon Kirby wrote:
| Since my post in December, iptables is STILL incorrectly using TCP packet
| contents without checking the header. I bet this is resulting in dropped
| connections and other issues all over the place but people aren't easily
| able to see why.
Forgive me, I was not around in december.. :)
| The "state" module checks the TCP checksum. Good.
What does it do if it mismatches? Match state "INVALID" ? Or not match any
state at all?
| The REJECT module uses TCP data without checking the checksum. Bad.
|
| In fact, a simple "-p tcp --dport 80" also matches without checking the
| TCP checksum. This is bad -- the port could be corrupted!
I agree.
| IMHO:
|
| 2: -p tcp --dport 80 needs to verify that the IP _AND_ TCP header is
| valid, since the port is in the TCP header. It does not do this now.
I think this sounds just fine, with the implementation note that a flag was
attached to the packet indicating that the layer 4+ checksum has been
verified (and what was the outcome) so it would only be verified the first
time someone (match, target) requests verification. Of course then there's
the issue if someone (userspace for example) modifies the packet in
between.. maybe these possibilities could be intercepted and the cached
result be destroyed in these cases?
If (and only if) the "state" match doesn't let us match the packet with
f.ex. the INVALID state, how would we allow the user to match these packets?
Maybe a --verify-checksum could be added to -p tcp and -p udp, which would
maybe mostly be used inverted?
| 3: REJECT needs to verify that the data it is using in --tcp-reset is
| actually valid, because it can be used with just "-p tcp". ICMP
| REJECT might also need checking.
But what will be done in case REJECT notices it's not valid? Return
IPT_CONTINUE? If that, then at least the packet & byte counters will
possibly be misleading - aren't they incremented regardless of the return
value of the target?
Another possibility of REJECT would be to drop the packet, but that's not
very customizable behaviour.. Looking at your first point, I find one more
possibility:
| 1: -p tcp needs to verify that the IP header is valid (it probably does
| this already), since the protocol is specified there.
If it would verify the TCP header too, then things like -j REJECT would also
work without hassle, and the counters would be right. On the other hand, it
would not regard broken tcp packets as tcp packets, and that might trigger
other unwanted side-effects of some firewall out there.
| Right? Does this make sense? Anyone?
Yeah I agree something should be done about this :)
- --
- - xkr47
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
iD8DBQFCTFfqxyF48ZTvn+4RAoAQAJsFS5GoJquksvgLbsFkyWu+9SGJ0QCfaCLt
12pPh8tUEquLQV3bzOLmVK8=
=rdei
-----END PGP SIGNATURE-----
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: iptables STILL incorrectly using TCP packet contents without checking header!
2005-03-31 20:04 ` Jonas Berlin
@ 2005-03-31 23:27 ` Henrik Nordstrom
2005-04-03 18:34 ` Patrick McHardy
2005-04-01 0:03 ` Simon Kirby
1 sibling, 1 reply; 6+ messages in thread
From: Henrik Nordstrom @ 2005-03-31 23:27 UTC (permalink / raw)
To: Jonas Berlin; +Cc: netfilter-devel
On Thu, 31 Mar 2005, Jonas Berlin wrote:
> But what will be done in case REJECT notices it's not valid?
In such case REJECT should silently DROP the packet without sending a
reject response.
Same as you see in a TCP/IP stack when receiving malformed TCP packets.
These are dropped as invalid, not generating TCP RST like most "odd but
not malformed" TCP packets do.
Regards
Henrik
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: iptables STILL incorrectly using TCP packet contents without checking header!
2005-03-31 23:27 ` Henrik Nordstrom
@ 2005-04-03 18:34 ` Patrick McHardy
0 siblings, 0 replies; 6+ messages in thread
From: Patrick McHardy @ 2005-04-03 18:34 UTC (permalink / raw)
To: Henrik Nordstrom; +Cc: netfilter-devel
Henrik Nordstrom wrote:
> On Thu, 31 Mar 2005, Jonas Berlin wrote:
>
>> But what will be done in case REJECT notices it's not valid?
>
>
> In such case REJECT should silently DROP the packet without sending a
> reject response.
>
> Same as you see in a TCP/IP stack when receiving malformed TCP packets.
> These are dropped as invalid, not generating TCP RST like most "odd but
> not malformed" TCP packets do.
Agreed. I'll fix it up.
Regards
Patrick
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: iptables STILL incorrectly using TCP packet contents without checking header!
2005-03-31 20:04 ` Jonas Berlin
2005-03-31 23:27 ` Henrik Nordstrom
@ 2005-04-01 0:03 ` Simon Kirby
2005-04-05 14:24 ` Amin Azez
1 sibling, 1 reply; 6+ messages in thread
From: Simon Kirby @ 2005-04-01 0:03 UTC (permalink / raw)
To: Jonas Berlin; +Cc: netfilter-devel
On Thu, Mar 31, 2005 at 11:04:59PM +0300, Jonas Berlin wrote:
> What does it do if it mismatches? Match state "INVALID" ? Or not match any
> state at all?
Yes, state INVALID.
> If (and only if) the "state" match doesn't let us match the packet with
> f.ex. the INVALID state, how would we allow the user to match these packets?
> Maybe a --verify-checksum could be added to -p tcp and -p udp, which would
> maybe mostly be used inverted?
>...
> But what will be done in case REJECT notices it's not valid? Return
> IPT_CONTINUE? If that, then at least the packet & byte counters will
> possibly be misleading - aren't they incremented regardless of the return
> value of the target?
Ahh, right, the details... always in the way!
I was thinking that REJECT should DROP in any case where it is unable to
respond due to bad checksums, etc., but where the match side of the rule
did match. It would be very bad to skip the rule in this case and
incorrect, I would suspsect, to do anything else.
Others have mentioned that a "is corrupted?" match option would be useful
for this and other reasons. It is not sufficient to depend on the state
module for this feature because there are situations where using stateful
tracking is not possible (eg: BGP routers, as in my case). Maybe
something like this:
iptables -A FORWARD -m checksum ! --checksum ip -J DROP
iptables -A FORWARD -p tcp -m checksum ! --checksum tcp -J DROP
(Grr, the "-m module --module-foo" syntax is annoyingly redundant.)
As for the matching side of things, let's see... Is it ever bad to
skip a rule that with otherwise block a corrupted packet? For instance:
iptables -A FORWARD -d 1.2.3.4 --dport 22 -j REJECT
iptables -P FORWARD ACCEPT
If checksumming were implemented in this case and the rule no longer
matched a corrupted packet, the packet would still be forwarded.
However, the end point should just discard it. I don't think this
will introduce any new problems except possibly for the ability to
fling loads of corrupted packets (DoS) past firewalls if TCP is
blocked with something like:
iptables -A FORWARD -p tcp --dport 0:65535 -j REJECT
This is probably a rare case, but probably worth noting.
Is there anything else?
Simon-
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: iptables STILL incorrectly using TCP packet contents without checking header!
2005-04-01 0:03 ` Simon Kirby
@ 2005-04-05 14:24 ` Amin Azez
0 siblings, 0 replies; 6+ messages in thread
From: Amin Azez @ 2005-04-05 14:24 UTC (permalink / raw)
To: netfilter-devel
Simon Kirby wrote:
> If checksumming were implemented in this case and the rule no longer
> matched a corrupted packet, the packet would still be forwarded.
> However, the end point should just discard it. I don't think this
> will introduce any new problems except possibly for the ability to
> fling loads of corrupted packets (DoS) past firewalls if TCP is
> blocked with something like:
>
> iptables -A FORWARD -p tcp --dport 0:65535 -j REJECT
>
> This is probably a rare case, but probably worth noting.
>
> Is there anything else?
Possibly this discussion is about to get philosophical:
One mans corrupt packet is another mans disguise.
Off the top of my head, propogating corrupt packets could perhaps be
used to subvert the firewall with the help of a co-operating box on the
inside that will accept and perhaps fixup the corrupt packets, or at
least do something with it.
We know that if an internal box has been "taken over" that all bets are
off anyway, but that is no excuse for the firewall to fail in its duty.
Various means including TCP/IP encapsulated in DNS requests can be used
to subvert firewalls but at least they show up and can be handled be
iptables or various other mechanisms.
Is this a "new problem"? I don't know, but it could be a problem.
Perhaps there is no practical difference between "corrupted packet" and
"unknown protocol" ?
IMHO corrupt packets should be dropped and not forwarded, and possibly
people want a similar rule for unknown protocols?
I much perfer your previous suggestion:
iptables -A FORWARD -m checksum ! --checksum ip -J DROP
iptables -A FORWARD -p tcp -m checksum ! --checksum tcp -J DROP
and I really think they ought to be the first rules in the FORWARD chain
by default.
Amin
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2005-04-05 14:24 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-03-31 18:57 iptables STILL incorrectly using TCP packet contents without checking header! Simon Kirby
2005-03-31 20:04 ` Jonas Berlin
2005-03-31 23:27 ` Henrik Nordstrom
2005-04-03 18:34 ` Patrick McHardy
2005-04-01 0:03 ` Simon Kirby
2005-04-05 14:24 ` Amin Azez
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.