diff --git a/src/analyzer/protocol/http/HTTP.cc b/src/analyzer/protocol/http/HTTP.cc index 62b2216179..5bb608022a 100644 --- a/src/analyzer/protocol/http/HTTP.cc +++ b/src/analyzer/protocol/http/HTTP.cc @@ -166,6 +166,7 @@ void HTTP_Entity::Deliver(int len, const char* data, bool trailing_CRLF) if ( expect_data_length <= 0 ) { SetPlainDelivery(0); + http_message->SetDeliverySize(-1); EndOfData(); } } @@ -510,6 +511,9 @@ void HTTP_Entity::SubmitAllHeaders() // in_header should be set to false when SubmitAllHeaders() is called. ASSERT(! in_header); + if (content_length >= 0 ) + http_message->SetDeliverySize(content_length); + if ( DEBUG_http ) DEBUG_MSG("%.6f end of headers\n", run_state::network_time); @@ -825,6 +829,11 @@ void HTTP_Message::SetPlainDelivery(int64_t length) content_line->SkipBytesAfterThisLine(length); } +void HTTP_Message::SetDeliverySize(int64_t length) + { + content_line->SetDeliverySize(length); + } + void HTTP_Message::SkipEntityData() { if ( current_entity ) diff --git a/src/analyzer/protocol/http/HTTP.h b/src/analyzer/protocol/http/HTTP.h index 927c19df97..713538247c 100644 --- a/src/analyzer/protocol/http/HTTP.h +++ b/src/analyzer/protocol/http/HTTP.h @@ -120,6 +120,7 @@ public: void SubmitTrailingHeaders(analyzer::mime::MIME_HeaderList& /* hlist */); void SetPlainDelivery(int64_t length); + void SetDeliverySize(int64_t length); void SkipEntityData(); HTTP_Analyzer* MyHTTP_Analyzer() const diff --git a/src/analyzer/protocol/tcp/ContentLine.cc b/src/analyzer/protocol/tcp/ContentLine.cc index 97d9a33e62..749aa23d2c 100644 --- a/src/analyzer/protocol/tcp/ContentLine.cc +++ b/src/analyzer/protocol/tcp/ContentLine.cc @@ -31,6 +31,7 @@ void ContentLine_Analyzer::InitState() seq = 0; seq_to_skip = 0; plain_delivery_length = 0; + delivery_length = -1; is_plain = false; suppress_weirds = false; @@ -91,8 +92,19 @@ void ContentLine_Analyzer::DeliverStream(int len, const u_char* data, return; } + if ( delivery_length > 0 ) + delivery_length -= len; + DoDeliver(len, data); + // If we have parsed all the data of the packet but there is no CRLF at the end + // Force the process by flushing buffer + if ( delivery_length == 0 && HasPartialLine() ) + { + Weird("No CRLF at the end of the packet"); + DoDeliver(2, (const u_char*) "\r\n"); + } + seq += len; } @@ -119,6 +131,19 @@ void ContentLine_Analyzer::SetPlainDelivery(int64_t length) plain_delivery_length = length; } +void ContentLine_Analyzer::SetDeliverySize(int64_t length) + { + // Length can be unset with -1 value, all other negative length will be rejected + if ( length < -1 ) + { + reporter->AnalyzerError( + this, "negative length for delivery size"); + return; + } + + delivery_length = length; + } + void ContentLine_Analyzer::DoDeliver(int len, const u_char* data) { seq_delivered_in_lines = seq; diff --git a/src/analyzer/protocol/tcp/ContentLine.h b/src/analyzer/protocol/tcp/ContentLine.h index c69ed7673b..f58e273ae6 100644 --- a/src/analyzer/protocol/tcp/ContentLine.h +++ b/src/analyzer/protocol/tcp/ContentLine.h @@ -50,6 +50,7 @@ public: // via DeliverStream() and can differentiated by calling // IsPlainDelivery(). void SetPlainDelivery(int64_t length); + void SetDeliverySize(int64_t length); int64_t GetPlainDeliveryLength() const { return plain_delivery_length; } bool IsPlainDelivery() { return is_plain; } @@ -97,6 +98,8 @@ protected: // Remaining bytes to deliver plain. int64_t plain_delivery_length; + // Remaining bytes to deliver + int64_t delivery_length; bool is_plain; // Don't deliver further data. diff --git a/testing/btest/Baseline/scripts.base.protocols.http.http-no-crlf/conn.log b/testing/btest/Baseline/scripts.base.protocols.http.http-no-crlf/conn.log new file mode 100644 index 0000000000..8d0abd4ebe --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.http.http-no-crlf/conn.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 conn +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig local_resp missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string bool bool count string count count count count set[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.1.6.206 49783 5.2.136.90 80 tcp http 109.987365 36349 1483945 SF - - 0 ShADadfF 406 52601 1113 1528477 - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.http.http-no-crlf/http.log b/testing/btest/Baseline/scripts.base.protocols.http.http-no-crlf/http.log new file mode 100644 index 0000000000..3860f20db5 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.http.http-no-crlf/http.log @@ -0,0 +1,15 @@ +### 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 10.1.6.206 49783 5.2.136.90 80 1 POST 5.2.136.90 /7u0e9j2avwlvnuynyo/szcm27k/fzb067wy/ 5.2.136.90/7u0e9j2avwlvnuynyo/szcm27k/fzb067wy/ 1.1 Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E) - 6086 306596 200 OK - - (empty) - - - FZLrmN1Yfib3JXC6T6 iVOWebWBCLKvFqxScD - FM9Psl4fUa9gBZCQQh - - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.1.6.206 49783 5.2.136.90 80 2 POST 5.2.136.90 /ko5ezxmguvv/p8d4003oiu/utkdae7r/74uzr8n74r/ 5.2.136.90/ko5ezxmguvv/p8d4003oiu/utkdae7r/74uzr8n74r/ 1.1 Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E) - 7558 411556 200 OK - - (empty) - - - FHPOuh2TVJgp3pJq3j NyhdNgYAMkJTEH - FOKNaz1g8KecRiTWhi - - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.1.6.206 49783 5.2.136.90 80 3 POST 5.2.136.90 /vwst360x8syxks325x/26dtqu31wzhmwqq/8p9iu8zbragj/ 5.2.136.90/vwst360x8syxks325x/26dtqu31wzhmwqq/8p9iu8zbragj/ 1.1 Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E) - 8214 473908 200 OK - - (empty) - - - FYaldg1JYa11cOBei YJOjLXCTqhWyWCU - FoNDxZ3lGCLGrBdTJh - - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.1.6.206 49783 5.2.136.90 80 4 POST 5.2.136.90 /mro86v6nvs42/ 5.2.136.90/mro86v6nvs42/ 1.1 Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E) - 6278 287012 200 OK - - (empty) - - - F8vuNh3ptzshBJwPw5 qzLwsgh - FsVY0sBNS0RyFWK55 - - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.1.6.206 49783 5.2.136.90 80 5 POST 5.2.136.90 /raet/u6tpsbdmo5g7crj4f/8l720ln/lwrl5fe38/1yje7g5qc/ 5.2.136.90/raet/u6tpsbdmo5g7crj4f/8l720ln/lwrl5fe38/1yje7g5qc/ 1.1 Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E) - 6230 1172 200 OK - - (empty) - - - FwDnoS3IYtb3kfjBhh HNmSIHcQqiuDjyl - FDuXok3U88iL5gT5Ij - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Traces/http/no_crlf.pcap b/testing/btest/Traces/http/no_crlf.pcap new file mode 100644 index 0000000000..1d9bab34ba Binary files /dev/null and b/testing/btest/Traces/http/no_crlf.pcap differ diff --git a/testing/btest/scripts/base/protocols/http/http-no-crlf.zeek b/testing/btest/scripts/base/protocols/http/http-no-crlf.zeek new file mode 100644 index 0000000000..10326a62a8 --- /dev/null +++ b/testing/btest/scripts/base/protocols/http/http-no-crlf.zeek @@ -0,0 +1,10 @@ +# This tests that the HTTP analyzer handles HTTP with no CRLF at end correctly. + +# @TEST-EXEC: zeek -b -r $TRACES/http/no_crlf.pcap %INPUT +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: btest-diff http.log +# @TEST-EXEC: test ! -f weird.log + +@load base/protocols/conn +@load base/protocols/http +@load base/frameworks/dpd