diff --git a/CHANGES b/CHANGES index 3c4a32c3a3..5107e16649 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,11 @@ +5.2.0-dev.355 | 2022-11-22 12:26:50 -0700 + + * http: Heuristic around rejecting malformed HTTP/0.9 traffic (Arne Welzel, Corelight) + + 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. + 5.2.0-dev.352 | 2022-11-21 09:10:28 -0700 * Fix logic error in vfmt() when growing the buffer (Michael Dopheide) diff --git a/VERSION b/VERSION index f8df61922f..e0fd3f8c5c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -5.2.0-dev.352 +5.2.0-dev.355 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 0000000000..67c421c13d Binary files /dev/null and b/testing/btest/Traces/http/curl_http_09.pcap differ diff --git a/testing/btest/Traces/http/http_09.pcap b/testing/btest/Traces/http/http_09.pcap new file mode 100644 index 0000000000..5f1907a00a Binary files /dev/null and b/testing/btest/Traces/http/http_09.pcap differ 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