]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
stream: ignore ack value if ack flag is not set. Add stream.pkt_broken_ack event...
authorVictor Julien <victor@inliniac.net>
Tue, 16 Oct 2012 11:27:58 +0000 (13:27 +0200)
committerVictor Julien <victor@inliniac.net>
Tue, 16 Oct 2012 11:27:58 +0000 (13:27 +0200)
rules/stream-events.rules
src/decode-events.h
src/detect-engine-event.h
src/stream-tcp.c

index 447885d8b4859047c32642c10d7d7ebe2164f04f..3e57b6a9359c02d817d368d0113075bfe05da4aa 100644 (file)
@@ -50,6 +50,9 @@ alert tcp any any -> any any (msg:"SURICATA STREAM TIMEWAIT ACK with wrong seq";
 alert tcp any any -> any any (msg:"SURICATA STREAM TIMEWAIT invalid ack"; stream-event:timewait_invalid_ack; sid:2210043; rev:1;)
 alert tcp any any -> any any (msg:"SURICATA STREAM Packet with invalid timestamp"; stream-event:pkt_invalid_timestamp; sid:2210044; rev:1;)
 alert tcp any any -> any any (msg:"SURICATA STREAM Packet with invalid ack"; stream-event:pkt_invalid_ack; sid:2210045; rev:1;)
+# Broken TCP: ack field non 0, but ACK flag not set. http://ask.wireshark.org/questions/3183/acknowledgment-number-broken-tcp-the-acknowledge-field-is-nonzero-while-the-ack-flag-is-not-set
+# Often result of broken load balancers, firewalls and such.
+#alert tcp any any -> any any (msg:"SURICATA STREAM Packet with broken ack"; stream-event:pkt_broken_ack; sid:2210051; rev:1;)
 alert tcp any any -> any any (msg:"SURICATA STREAM SHUTDOWN RST invalid ack"; stream-event:rst_invalid_ack; sid:2210046; rev:1;)
 # SYN (re)send during shutdown (closing, closewait, finwait1, finwait2, lastack, timewait states)
 #alert tcp any any -> any any (msg:"SURICATA STREAM SYN resend"; stream-event:shutdown_syn_resend; sid:2210049; rev:1;)
@@ -57,5 +60,5 @@ alert tcp any any -> any any (msg:"SURICATA STREAM SHUTDOWN RST invalid ack"; st
 # Sequence gap: missing data in the reassembly engine. Usually due to packet loss. Will be very noisy on a overloaded link / sensor.
 #alert tcp any any -> any any (msg:"SURICATA STREAM reassembly sequence GAP -- missing packet(s)"; stream-event:reassembly_seq_gap; sid:2210048; rev:1;)
 alert tcp any any -> any any (msg:"SURICATA STREAM reassembly overlap with different data"; stream-event:reassembly_overlap_different_data; sid:2210050; rev:1;)
-# next sid 2210051
+# next sid 2210052
 
index 2a1bb69f5c10e1ce94500112e46f300a653a67ec..3e08f2c2f673807fc075e68f4ef92c654ad6e469 100644 (file)
@@ -176,6 +176,7 @@ enum {
     STREAM_SHUTDOWN_SYN_RESEND,
     STREAM_PKT_INVALID_TIMESTAMP,
     STREAM_PKT_INVALID_ACK,
+    STREAM_PKT_BROKEN_ACK,
     STREAM_RST_INVALID_ACK,
 
     STREAM_REASSEMBLY_SEGMENT_BEFORE_BASE_SEQ,
index b16d2138250176846ac1e01ea13f2b029d2ca2ea..52653e35818ec6f6642cad05448d134d0e7344de 100644 (file)
@@ -166,6 +166,7 @@ struct DetectEngineEvents_ {
     { "stream.timewait_invalid_ack", STREAM_TIMEWAIT_INVALID_ACK, },
     { "stream.pkt_invalid_timestamp", STREAM_PKT_INVALID_TIMESTAMP, },
     { "stream.pkt_invalid_ack", STREAM_PKT_INVALID_ACK, },
+    { "stream.pkt_broken_ack", STREAM_PKT_BROKEN_ACK, },
     { "stream.rst_invalid_ack", STREAM_RST_INVALID_ACK, },
     { "stream.shutdown_syn_resend", STREAM_SHUTDOWN_SYN_RESEND, },
     { "stream.reassembly_segment_before_base_seq", STREAM_REASSEMBLY_SEGMENT_BEFORE_BASE_SEQ, },
index 45e78eba3cb60392bdf91d6007bfed164e24b8b7..8b881a73946af3f1ad374bdeb8239d3f07f5089a 100644 (file)
@@ -3591,6 +3591,11 @@ static int StreamTcpPacket (ThreadVars *tv, Packet *p, StreamTcpThread *stt,
         SCPerfCounterIncr(stt->counter_tcp_rst, tv->sc_perf_pca);
     }
 
+    /* broken TCP http://ask.wireshark.org/questions/3183/acknowledgment-number-broken-tcp-the-acknowledge-field-is-nonzero-while-the-ack-flag-is-not-set */
+    if (!(p->tcph->th_flags & TH_ACK) && TCP_GET_ACK(p) != 0) {
+        StreamTcpSetEvent(p, STREAM_PKT_BROKEN_ACK);
+    }
+
     /* If we are on IPS mode, and got a drop action triggered from
      * the IP only module, or from a reassembled msg and/or from an
      * applayer detection, then drop the rest of the packets of the
@@ -4012,7 +4017,8 @@ static int StreamTcpValidateRst(TcpSession *ssn, Packet *p)
 
         os_policy = ssn->server.os_policy;
 
-        if (TCP_GET_ACK(p) && StreamTcpValidateAck(ssn, &ssn->server, p) == -1) {
+        if (p->tcph->th_flags & TH_ACK &&
+                TCP_GET_ACK(p) && StreamTcpValidateAck(ssn, &ssn->server, p) == -1) {
             SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn);
             StreamTcpSetEvent(p, STREAM_RST_INVALID_ACK);
             SCReturnInt(0);
@@ -4024,7 +4030,8 @@ static int StreamTcpValidateRst(TcpSession *ssn, Packet *p)
 
         os_policy = ssn->client.os_policy;
 
-        if (TCP_GET_ACK(p) && StreamTcpValidateAck(ssn, &ssn->client, p) == -1) {
+        if (p->tcph->th_flags & TH_ACK &&
+                TCP_GET_ACK(p) && StreamTcpValidateAck(ssn, &ssn->client, p) == -1) {
             SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn);
             StreamTcpSetEvent(p, STREAM_RST_INVALID_ACK);
             SCReturnInt(0);