From 9c4e44924fe3b283bae0e722f927d0a65d81b205 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 29 Oct 2019 17:20:08 -0700 Subject: [PATCH] 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. --- src/analyzer/protocol/tcp/TCP.cc | 9 ++++++-- .../payload-syn.out | 1 + .../payload-synack.out | 1 + .../tcp-fast-open.out | 1 + testing/btest/Traces/tcp/payload-syn.pcap | Bin 0 -> 460 bytes testing/btest/Traces/tcp/payload-synack.pcap | Bin 0 -> 470 bytes testing/btest/Traces/tcp/tcp-fast-open.pcap | Bin 0 -> 3604 bytes .../signatures/tcp-syn-with-payload.zeek | 20 ++++++++++++++++++ 8 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 testing/btest/Baseline/signatures.tcp-syn-with-payload/payload-syn.out create mode 100644 testing/btest/Baseline/signatures.tcp-syn-with-payload/payload-synack.out create mode 100644 testing/btest/Baseline/signatures.tcp-syn-with-payload/tcp-fast-open.out create mode 100644 testing/btest/Traces/tcp/payload-syn.pcap create mode 100644 testing/btest/Traces/tcp/payload-synack.pcap create mode 100644 testing/btest/Traces/tcp/tcp-fast-open.pcap create mode 100644 testing/btest/signatures/tcp-syn-with-payload.zeek 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 0000000000000000000000000000000000000000..40825908779991521df582edd86679612ee09994 GIT binary patch literal 460 zcmca|c+)~A1{MYw`2U}QAr;6G(9ev0w2Fz~I34Q~baR21X!eVh8|2 z1_mx5W(Z(XU^w!Kfx+E1L_uFaGcP5zLa!jBz`h_cJ=IoEPalF(OOo{q5{rw=QxrTx zLIU&+^$dBrLW@(2bRE-E^Gd7~lB+68jEZ@=9Fvn%3xIqreJx%tUa$=yTOa`Bw#Dn% z7&L%f5C*zU1M0SFkh?(cgSyQKD4ic5q`<&y2k}$YMx6SP{ge;XXB;2^)MpRT_jfZ1 p`UDa7Wo^T$580i@K>G>;K>BPU_I=ucQy;QB3xN7e!0rU<0|4XBT6h2e literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/tcp/payload-synack.pcap b/testing/btest/Traces/tcp/payload-synack.pcap new file mode 100644 index 0000000000000000000000000000000000000000..2a2e58c9cbde482c7acef4b766ad3152a68491d2 GIT binary patch literal 470 zcmca|c+)~A1{MYw`2U}QAr;6G($9=t{F;kF1IPwpR}jU>z~I34v--da21X!eVh8|2 z1_mx5W(Z(XVBmcU(UWu;rO`G5EVsx$4OpvQIO;5}Qs6nS_v#45c$eNCU}`KF=u1 zQjrys0-x++H;nm0f=?7W^WAAd64+teGFU@$T-8qCXd5g|5C<{(Dt{Li2&p4YWXv#C zS0LmG7;S>Fm5;!NAvzaza4ozF4;zT_d29ALkntre+l&hnBzNFz5^E;?glwDrV;kAl zr2odqatz+YjcJlQ_|Cg9M98^1yXCVV!HR~)PaEo*8FF*vIQGZt>sQP-%pLJ@5U+&Y za3S8eU$kZqfQ+w?CNlZ4qm-{;h2wyxF-+;F2o)FvNih}$oNM5^k(l+KR*ijxf8H^CfAbN_g)3R zV${bIh`XzQh~+d>QA^3UcHB5{A;#}Nw`Lh=;~T;Fcj`OD_;Bm87;9q}4@gyv2Z&K|Twv3D3j7^Y6?RB9 zik2cmj=NvM2SE^;tvGOk|JJL1Pr=NBtqj71h`d3gsRs$camd2{a zN09TL>j8{#{$*zWr2FztXkQ-Mysp1_ay6O0b-TJRPXg}`Y8c;B#(mDO1IEYD#y7I} z-9B_UT`)Q5`a*pOhIKasy=Rc||b4AH<#+658 ziab$rQ%)pF(1$Q5bHRAgN)@OdnW-z3lZFr{&A`cFnj`TgoPaNjIijOmaAA&|{IxZ^ z2V{IBIkJWLHR@6TV`guD)`6Iv{{U*#s`qR0qMSg?utpJr7-4^I09G~UBm7Sk+ygi$2bfQnHP1-L5>&U0+e0Tr<- zai*nPP^%d1Er}_(>G<+WPT2vaG~6h0iaNH;N>167K`SG6c66jOpb1TGaZwJNOhGbK zT&Y9s7jY&2qOY(@y(dMFCReik(>RoVyK$V@MW$Bz= zRF<(9%AyYHo8YD*o#0E6g-vxF?e2z~ih;%bc4UU<$!Ltg<3k&PIet4br)XQHGEPe4 zMpVbg#}kU=N}!zvUeaQ-8ISXl{ECNG0X^_knskCM1Gf<*U2|~5r8nU- z05Q|d0=o}7*#XIfOtx*H#mfd}N!_Ds%iMc@jiO_4lR!Tj_+IW2z-^2ESvXQ*|xx zd71)q1s;hM#2Vb<7!t%m;`OO{O)?X(nnCp;|M*Nr-`|Efl%XlX4NJPCGL9>`{^F^M zakb^mVITvS_EjNo90+#a!`KKsY!JSyvN#4)!GVCf2VZBt)o3=@jvejo?IJf~87er6 zwBhQsW;o7>Z^mNo)>xuL(ZE1?#kw1=@mHY!KDx%w(DP*UhiHwze-vu`!!vfZ#-D=o zWUh8*1-~QK{~f@HoQup`SmXEaSX$%nAEh-OzEw`2URvXq#~A%5fDt*XW@7ZLy1I-X z$KYG#;Tib1qjFX~#*g!N0~k?1-ll%^hWt1Netd%G`{`3l{D2n52#>ws`JOpEn2nM3 zWQXO!N2cwtP*cV<1wLN$WmfV3L8~Lp^jl!?jg8OMSLEJ9gV_dpayload-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); + }