From 540fe7aff721146797dbfed01a87a521bca13763 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Fri, 18 Nov 2022 14:45:18 +0100 Subject: [PATCH] http: Heuristic around rejecting malformed HTTP/0.9 traffic oss-fuzz generated "HTTP traffic" containing 250k+ sequences of "T\r\r" which Zeek then logged as individual HTTP requests. Add a heuristic to bail on such request lines. It's a bit specific to the test case, but should work. There are more issues around handling HTTP/0.9, e.g. triggering "not a http reply line" when HTTP/0.9 never had such a thing, but I don't think that's worth fixing up. Fixes #119 --- src/analyzer/protocol/http/HTTP.cc | 12 ++++++++++++ .../http.log | 11 +++++++++++ .../scripts.base.protocols.http.http-09/http.log | 12 ++++++++++++ .../weird.log | 13 +++++++++++++ testing/btest/Traces/http/curl_http_09.pcap | Bin 0 -> 829 bytes testing/btest/Traces/http/http_09.pcap | Bin 0 -> 4352 bytes .../base/protocols/http/curl-http-09.zeek | 7 +++++++ .../scripts/base/protocols/http/http-09.zeek | 7 +++++++ 8 files changed, 62 insertions(+) create mode 100644 testing/btest/Baseline/scripts.base.protocols.http.curl-http-09/http.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.http.http-09/http.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.http.http-09/weird.log create mode 100644 testing/btest/Traces/http/curl_http_09.pcap create mode 100644 testing/btest/Traces/http/http_09.pcap create mode 100644 testing/btest/scripts/base/protocols/http/curl-http-09.zeek create mode 100644 testing/btest/scripts/base/protocols/http/http-09.zeek diff --git a/src/analyzer/protocol/http/HTTP.cc b/src/analyzer/protocol/http/HTTP.cc index e80b6cf72f..6358c7573b 100644 --- a/src/analyzer/protocol/http/HTTP.cc +++ b/src/analyzer/protocol/http/HTTP.cc @@ -1230,6 +1230,18 @@ int HTTP_Analyzer::HTTP_RequestLine(const char* line, const char* end_of_line) return -1; } + // If we determined HTTP/0.9 (no HTTP/ in the request line), assert that + // minimally we have an URI and a 3 character method (HTTP 0.9 only + // supports GET). If that doesn't hold, probably not HTTP or very stange. + if ( request_version.major == 0 && request_version.minor == 9 ) + { + bool maybe_get_method = (end_of_method - line) >= 3; + bool has_uri = request_URI && request_URI->Len() > 0; + + if ( ! maybe_get_method || ! has_uri ) + goto error; + } + request_method = make_intrusive(end_of_method - line, line); Conn()->Match(zeek::detail::Rule::HTTP_REQUEST, diff --git a/testing/btest/Baseline/scripts.base.protocols.http.curl-http-09/http.log b/testing/btest/Baseline/scripts.base.protocols.http.curl-http-09/http.log new file mode 100644 index 0000000000..12dca7dd6c --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.http.curl-http-09/http.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path http +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p trans_depth method host uri referrer version user_agent origin request_body_len response_body_len status_code status_msg info_code info_msg tags username password proxied orig_fuids orig_filenames orig_mime_types resp_fuids resp_filenames resp_mime_types +#types time string addr port addr port count string string string string string string string count count count string count string set[enum] string string set[string] vector[string] vector[string] vector[string] vector[string] vector[string] vector[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 49404 127.0.0.1 80 1 GET localhost /zeek.html - - curl/7.74.0 - 0 0 - - - - (empty) - - - - - - - - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.http.http-09/http.log b/testing/btest/Baseline/scripts.base.protocols.http.http-09/http.log new file mode 100644 index 0000000000..814b2ccdda --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.http.http-09/http.log @@ -0,0 +1,12 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path http +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p trans_depth method host uri referrer version user_agent origin request_body_len response_body_len status_code status_msg info_code info_msg tags username password proxied orig_fuids orig_filenames orig_mime_types resp_fuids resp_filenames resp_mime_types +#types time string addr port addr port count string string string string string string string count count count string count string set[enum] string string set[string] vector[string] vector[string] vector[string] vector[string] vector[string] vector[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 42960 127.0.0.1 80 1 GET - /zeek.html - - - - 0 0 - - - - (empty) - - - - - - - - - +XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 127.0.0.1 42964 127.0.0.1 80 1 POST - /zeek.html - - - - 0 0 - - - - (empty) - - - - - - - - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.http.http-09/weird.log b/testing/btest/Baseline/scripts.base.protocols.http.http-09/weird.log new file mode 100644 index 0000000000..0c40a3a626 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.http.http-09/weird.log @@ -0,0 +1,13 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path weird +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer source +#types time string addr port addr port string string bool string string +XXXXXXXXXX.XXXXXX C4J4Th3PJpwUYZZ6gc 127.0.0.1 42968 127.0.0.1 80 bad_HTTP_request - F zeek HTTP +XXXXXXXXXX.XXXXXX CtPZjS20MLrsMUOJi2 127.0.0.1 42970 127.0.0.1 80 bad_HTTP_request - F zeek HTTP +XXXXXXXXXX.XXXXXX CUM0KZ3MLUfNB0cl11 127.0.0.1 42972 127.0.0.1 80 bad_HTTP_request - F zeek HTTP +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Traces/http/curl_http_09.pcap b/testing/btest/Traces/http/curl_http_09.pcap new file mode 100644 index 0000000000000000000000000000000000000000..67c421c13d6ac74685df8877012baf2c2ae9b3af GIT binary patch literal 829 zcmca|c+)~A1{MYw`2U}Qff2}gUQ?cYte1ts3&;jxWWd4T%D`ZwHl?ULk0#WmjBmTm^iqs6}{ep#2J~H*+C|A_2Dy_fdOQ)%`TY9 z3;_rJ)T@3B0-D~jKp&UyGNEmkZ=Z6`&h&``RfL&rkBOM%`6VPpXIb-Gg;*hCGiCQ2~=fA|#DL>rK2?YI;aLNZbnqJX|v@JlTz&o9bW z2u=n1EwiLj!8boIvn0QW%SIof7UZoDc)g|M0uK5*m?NN(c?%esZJ@~Xx{2b5_aGCk bCg2UIbg;LgU?xHXstp`aB0v+bqM8T*j10%L literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/http/http_09.pcap b/testing/btest/Traces/http/http_09.pcap new file mode 100644 index 0000000000000000000000000000000000000000..5f1907a00ae3e8f46a198f16f3421a0b21877c03 GIT binary patch literal 4352 zcmaKue@xV69LFC~$c{!7wdwrlwzSPmNu*LCK+7PSc&Y1$)olXDPmy+j@>4WWOrbj@ zeq^Drh&u-T@_FX+ic|-M&k&^mF6IY<|OB|yyiPet_k z`C2oQs1<4p7wQ2b(#(Ythn2+sEOtC5i8{xvM?t(DPW(nm^v$v3HA&PQx02&meCrTm z9^Ja$Yf_}JvmM0I^^)kC5SA-}dwbA!q%dcnJ}Vj1_#9aQxl>6N0%Su9CmL&74iLQ; zDg6Gpk(`#4F)hi1M2_D3&JK1?4RP)zdIhR5zfIOPV;WSrP7-l9xnt`WkMwh$?=ta` zh(sFc?ZZZ*W!D}<3~|D&(s}54oY2=GPoU1B8WmIx7dvk>o&e&Z&rD(`$ztmlJ7*4M zGqExvk(_@lGZORn7n&<<)g_gMCcs+=t|+mC3z8z?+E}d}`))q`C((xyFGsqO zoR(xQljI9Tj^2CgX?A`p#Ce$LH&6u+J)(jSLTeeQaNYh_yvQbZZ2jU<-D2g3%*+!J zi8QK-CyYeAyub&7fNu0N-)Zzw~Sa2kN+Jn^2iWdzgRTO{}>Zb zMj}w;21ni5}h8%FnHt#phOV7)HtY4*OnT@CCgbzVk|= ze;xbwg!ta!3Qz<*bK%6?TS`ZM63%RrL~UTxqUJ7V!Cmk1p&S27YXn6sESJ6s=SWKMTKO#Dmx{kf3;B zIbBS=KO&KYtG+N2buTQyKO%T^-R4xTMu&uJGvOy?2kRa&!a)ouiB31`u9QTr01hqy zC84`1oLD%hbbOK>+a*!w=tQ=<8y1LFm@GJUD2dJyc3dHenxm5(=lIt324YnK5j}me zifnoFK|KD7B)YB&i!Xb(8}o;3c{240aGb&CNC3#cDak^BZ1_HSwQ=(w4MZP7wvNpj z$X#hkjx&;+_~nfr{w6%DUGjQ7b?j7l7v9eL9?YT}kv7vE%EK hsB=7tM7d9e6Yu*_>3EGD=Oj^cJV}n9@U26L{{yPY(*pni literal 0 HcmV?d00001 diff --git a/testing/btest/scripts/base/protocols/http/curl-http-09.zeek b/testing/btest/scripts/base/protocols/http/curl-http-09.zeek new file mode 100644 index 0000000000..4c4a427675 --- /dev/null +++ b/testing/btest/scripts/base/protocols/http/curl-http-09.zeek @@ -0,0 +1,7 @@ +# @TEST-DOC: curl --http0.9 to accept the headerless response. +# @TEST-EXEC: zeek -b -Cr $TRACES/http/curl_http_09.pcap %INPUT +# @TEST-EXEC: btest-diff http.log +# @TEST-EXEC: test ! -f weird.log + +@load base/frameworks/notice/weird +@load base/protocols/http diff --git a/testing/btest/scripts/base/protocols/http/http-09.zeek b/testing/btest/scripts/base/protocols/http/http-09.zeek new file mode 100644 index 0000000000..0a7f368fb2 --- /dev/null +++ b/testing/btest/scripts/base/protocols/http/http-09.zeek @@ -0,0 +1,7 @@ +# @TEST-DOC: Artificially created PCAP with one proper HTTP 0.9 request/response and a few invalid ones. +# @TEST-EXEC: zeek -b -Cr $TRACES/http/http_09.pcap %INPUT +# @TEST-EXEC: btest-diff http.log +# @TEST-EXEC: btest-diff weird.log + +@load base/frameworks/notice/weird +@load base/protocols/http