[PATCH] netfilter: conntrack: tcp: do not lower timeout to CLOSE for in-window RSTs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



With previous commit https://github.com/torvalds/linux/commit/be0502a
("netfilter: conntrack: tcp: only close if RST matches exact sequence")
to fight against TCP in-window reset attacks, current version of netfilter
will keep the connection state in ESTABLISHED, but lower the timeout to
that of CLOSE (10 seconds by default) for in-window TCP RSTs, and wait for
the peer to send a challenge ack to restore the connection timeout
(5 mins in tests).

However, malicious attackers can prevent incurring challenge ACKs by
manipulating the TTL value of RSTs. The attacker can probe the TTL value
between the NAT device and itself and send in-window RST packets with
a TTL value to be decreased to 0 after arriving at the NAT device.
This causes the packet to be dropped rather than forwarded to the
internal client, thus preventing a challenge ACK from being triggered.
As the window of the sequence number is quite large (bigger than 60,000
in tests) and the sequence number is 16-bit, the attacker only needs to
send nearly 60,000 RST packets with different sequence numbers
(i.e., 1, 60001, 120001, and so on) and one of them will definitely
fall within in the window.

Therefore we can't simply lower the connection timeout to 10 seconds
(rather short) upon receiving in-window RSTs. With this patch, netfilter
will lower the connection timeout to that of CLOSE only when it receives
RSTs with exact sequence numbers (i.e., old_state != new_state).

Signed-off-by: yyxRoy <979093444@xxxxxx>
---
 net/netfilter/nf_conntrack_proto_tcp.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index ae493599a..d06259407 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -1280,7 +1280,8 @@ int nf_conntrack_tcp_packet(struct nf_conn *ct,
 	if (ct->proto.tcp.retrans >= tn->tcp_max_retrans &&
 	    timeouts[new_state] > timeouts[TCP_CONNTRACK_RETRANS])
 		timeout = timeouts[TCP_CONNTRACK_RETRANS];
-	else if (unlikely(index == TCP_RST_SET))
+	else if (unlikely(index == TCP_RST_SET) &&
+		 old_state != new_state)
 		timeout = timeouts[TCP_CONNTRACK_CLOSE];
 	else if ((ct->proto.tcp.seen[0].flags | ct->proto.tcp.seen[1].flags) &
 		 IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED &&
-- 
2.34.1





[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux