diff --git a/CHANGES b/CHANGES index 5a6fbf9031..dd3053ed3e 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,10 @@ +3.1.0-dev.229 | 2019-10-30 07:57:19 +0000 + + * GH-664: fix signature matching for cases where the first TCP + packet seen contained payload data, regardless of its TCP flags. + (Jon Siwek, Corelight) + 3.1.0-dev.227 | 2019-10-29 09:39:10 -0700 * Replace build_unique with make_unique (Johanna Amann, Corelight) diff --git a/VERSION b/VERSION index 9efafa03b6..a056cf85e8 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.1.0-dev.227 +3.1.0-dev.229 diff --git a/src/analyzer/protocol/tcp/TCP.cc b/src/analyzer/protocol/tcp/TCP.cc index c1844679bf..873f5d6689 100644 --- a/src/analyzer/protocol/tcp/TCP.cc +++ b/src/analyzer/protocol/tcp/TCP.cc @@ -1190,6 +1190,13 @@ void TCP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, if ( (tcp_option || tcp_options) && tcp_hdr_len > sizeof(*tp) ) ParseTCPOptions(tp, is_orig); + // PIA/signature matching state needs to be initialized before + // processing/reassembling any TCP data, since that processing may + // itself try to perform signature matching. Also note that a SYN + // packet may technically carry data (see RFC793 Section 3.4 and also + // TCP Fast Open). + CheckPIA_FirstPacket(is_orig, ip); + if ( DEBUG_tcp_data_sent ) { DEBUG_MSG("%.6f before DataSent: len=%d caplen=%d skip=%d\n", @@ -1243,8 +1250,6 @@ void TCP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, if ( ! reassembling ) ForwardPacket(len, data, is_orig, rel_data_seq, ip, caplen); - - CheckPIA_FirstPacket(is_orig, ip); } void TCP_Analyzer::DeliverStream(int len, const u_char* data, bool orig) diff --git a/testing/btest/Baseline/signatures.tcp-syn-with-payload/payload-syn.out b/testing/btest/Baseline/signatures.tcp-syn-with-payload/payload-syn.out new file mode 100644 index 0000000000..4c5110213b --- /dev/null +++ b/testing/btest/Baseline/signatures.tcp-syn-with-payload/payload-syn.out @@ -0,0 +1 @@ +signature_match [orig_h=192.168.0.1, orig_p=80/tcp, resp_h=192.168.0.2, resp_p=80/tcp] - payload of dst-port=80/tcp contains 'passwd' diff --git a/testing/btest/Baseline/signatures.tcp-syn-with-payload/payload-synack.out b/testing/btest/Baseline/signatures.tcp-syn-with-payload/payload-synack.out new file mode 100644 index 0000000000..4c5110213b --- /dev/null +++ b/testing/btest/Baseline/signatures.tcp-syn-with-payload/payload-synack.out @@ -0,0 +1 @@ +signature_match [orig_h=192.168.0.1, orig_p=80/tcp, resp_h=192.168.0.2, resp_p=80/tcp] - payload of dst-port=80/tcp contains 'passwd' diff --git a/testing/btest/Baseline/signatures.tcp-syn-with-payload/tcp-fast-open.out b/testing/btest/Baseline/signatures.tcp-syn-with-payload/tcp-fast-open.out new file mode 100644 index 0000000000..cb13fa5a47 --- /dev/null +++ b/testing/btest/Baseline/signatures.tcp-syn-with-payload/tcp-fast-open.out @@ -0,0 +1 @@ +signature_match [orig_h=10.99.99.1, orig_p=55534/tcp, resp_h=10.99.99.45, resp_p=80/tcp] - payload of dst-port=80/tcp contains 'passwd' diff --git a/testing/btest/Traces/tcp/payload-syn.pcap b/testing/btest/Traces/tcp/payload-syn.pcap new file mode 100644 index 0000000000..4082590877 Binary files /dev/null and b/testing/btest/Traces/tcp/payload-syn.pcap differ diff --git a/testing/btest/Traces/tcp/payload-synack.pcap b/testing/btest/Traces/tcp/payload-synack.pcap new file mode 100644 index 0000000000..2a2e58c9cb Binary files /dev/null and b/testing/btest/Traces/tcp/payload-synack.pcap differ diff --git a/testing/btest/Traces/tcp/tcp-fast-open.pcap b/testing/btest/Traces/tcp/tcp-fast-open.pcap new file mode 100644 index 0000000000..88e9a99b0d Binary files /dev/null and b/testing/btest/Traces/tcp/tcp-fast-open.pcap differ diff --git a/testing/btest/signatures/tcp-syn-with-payload.zeek b/testing/btest/signatures/tcp-syn-with-payload.zeek new file mode 100644 index 0000000000..0b20c23353 --- /dev/null +++ b/testing/btest/signatures/tcp-syn-with-payload.zeek @@ -0,0 +1,20 @@ +# @TEST-EXEC: zeek -b -s payload-http.sig -r $TRACES/tcp/payload-syn.pcap %INPUT >payload-syn.out +# @TEST-EXEC: zeek -b -s payload-http.sig -r $TRACES/tcp/payload-synack.pcap %INPUT >payload-synack.out +# @TEST-EXEC: zeek -b -s payload-http.sig -r $TRACES/tcp/tcp-fast-open.pcap %INPUT >tcp-fast-open.out +# @TEST-EXEC: btest-diff payload-syn.out +# @TEST-EXEC: btest-diff payload-synack.out +# @TEST-EXEC: btest-diff tcp-fast-open.out + +@TEST-START-FILE payload-http.sig +signature test-signature { + ip-proto == tcp + dst-port = 80 + payload /.*passwd/ + event "payload of dst-port=80/tcp contains 'passwd'" +} +@TEST-END-FILE + +event signature_match(state: signature_state, msg: string, data: string) + { + print fmt("signature_match %s - %s", state$conn$id, msg); + }