GH-664: fix signature matching for payload-carrying SYN packets

Or more generally, signatures would not work correctly for any case
where the first TCP packet seen contained payload data, regardless of
its TCP flags.
This commit is contained in:
Jon Siwek 2019-10-29 17:20:08 -07:00
parent 7b9a27c96a
commit 9c4e44924f
8 changed files with 30 additions and 2 deletions

View file

@ -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)

View file

@ -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'

View file

@ -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'

View file

@ -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'

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -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);
}