[Snort-devel] HttpInpsect/HTTP preprocessor: false positives + parsing of header/body?

Bram bram-fabeg at ...3414...
Mon Aug 12 08:50:07 EDT 2013


Hi,


There appear to be several false positives in the HTTP preprocessor.

Attempting to find the source of the false positives led me to the  
'HttpResponseInspection' in  
preprocessors/HttpInspect/server/hi_server.c.

What *appears* to be happening is that 'HttpResponseInspection' makes  
the distinction between header and body based on the first five bytes  
in the buffer.
When the buffer starts with 'HTTP/' then it seems to parse the packet  
as HTTP Headers, when it does not start with 'HTTP/' then it seems to  
parse the packet as HTTP Body.

This looks incorrect... there is no reason for all the HTTP headers to  
be in a single packet nor is there a reason for the HTTP body to be in  
a separate packet...
The end of the HTTP header is indicated by an empty line.. (i.e., a  
line with nothing preceding the CRLF)


Configuration used:
	dynamicpreprocessor directory /usr/lib/snort_dynamicpreprocessor/
	preprocessor stream5_global: \
	   track_tcp yes, \
	   track_udp no, \
	   track_icmp no
	preprocessor stream5_tcp: policy first, ports 80 8080

	preprocessor http_inspect: global iis_unicode_map unicode.map 1252  
compress_depth 65535 decompress_depth 65535
	preprocessor http_inspect_server: server default \
	    http_methods { GET POST PUT SEARCH MKCOL COPY MOVE LOCK UNLOCK  
NOTIFY POLL BCOPY BDELETE BMOVE LINK UNLINK OPTIONS HEAD DELETE TRACE  
TRACK CONNECT SOURCE SUBSCRIBE UNSUBSCRIBE PROPFIND PROPPATCH  
BPROPFIND BPROPPATCH RPC_CONNECT PROXY_SUCCESS BITS_POST CCM_POST  
SMS_POST RPC_IN_DATA RPC_OUT_DATA RPC_ECHO_DATA } \
	    chunk_length 500000 \
	    server_flow_depth 0 \
	    client_flow_depth 0 \
	    post_depth 65495 \
	    oversize_dir_length 500 \
	    max_header_length 4096 \
	    max_headers 100 \
	    max_spaces 0 \
	    small_chunk_length { 10 5 } \
	    ports { 80 7000 8080 } \
	    non_rfc_char { 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 } \
	    enable_cookie \
	    extended_response_inspection \
	    inspect_gzip \
	    normalize_utf \
	    unlimited_decompress \
	    normalize_javascript \
	    apache_whitespace no \
	    ascii no \
	    bare_byte no \
	    directory no \
	    double_decode no \
	    iis_backslash no \
	    iis_delimiter no \
	    iis_unicode no \
	    multi_slash no \
	    utf_8 no \
	    u_encode yes \
	    webroot no

	alert ( msg: "HI_SERVER_INVALID_STATCODE"; sid: 2; gid: 120; rev: 1;  
metadata: rule-type preproc ;  )
         alert ( msg: "HI_SERVER_NO_CONTLEN"; sid: 3; gid: 120; rev:  
1; metadata: rule-type preproc ;  )

	output alert_fast: stdout


Running it:
	$ snort -v -l /var/log -c /etc/ips/snort.conf --daq-dir /lib/daq/ -r  
/tmp/120_2_1.cap 2>&1 | grep '120:'
	07/15-15:27:54.244754  [**] [120:2:1] (http_inspect) INVALID STATUS  
CODE IN HTTP RESPONSE [**] [Priority: 0] {TCP} 192.168.173.1:80 ->  
192.168.173.153:54940

	$ snort -v -l /var/log -c /etc/ips/snort.conf --daq-dir /lib/daq/ -r  
/tmp/120_3_1_A.cap 2>&1  | grep '120:'
	08/18-16:46:53.189936  [**] [120:3:1] (http_inspect) NO  
CONTENT-LENGTH OR TRANSFER-ENCODING IN HTTP RESPONSE [**] [Priority:  
0] {TCP} 192.168.173.1:80 -> 192.168.173.153:43674

	$ snort -v -l /var/log -c /etc/ips/snort.conf --daq-dir /lib/daq/ -r  
/tmp/120_3_1_B.cap 2>&1 | grep '120:'
	08/18-16:54:58.860230  [**] [120:3:1] (http_inspect) NO  
CONTENT-LENGTH OR TRANSFER-ENCODING IN HTTP RESPONSE [**] [Priority:  
0] {TCP} 192.168.173.1:80 -> 192.168.173.153:43675


Capture files:

120_2_1.cap:
	This triggers the 'HI_SERVER_INVALID_STATCODE' alert.
	The dump consist out of 1 request and 1 response.
	'Special' about the response is that the HTTP body happens to contain  
the string 'HTTP/2.0' and this happens to be at the start of a TCP  
packet.
	[This false positive was detected due to a visit to the HTTP/2.0  
draft, which contains the string 'HTTP/2.0' many times]

	Analyzing it with gdb and breaking on hi_server.c line 1480 (right  
before '/*If this is the next expected pac ...') shows:
	* packet 6: data starts with 'HTTP/1.1', expected_pkt is 0 => parsed  
as HTTP headers => OK
	* packet 7: data starts with 'HTTP/2.0', expected_pkt is 0 => parsed  
as HTTP headers => NOT OK, this is part of the body

120_3_1_A.cap:
	This triggers the 'HI_SERVER_NO_CONTLEN' alert.
	In the dump the HTTP Headers are split over two TCP packets.
	The first packets consist of 'HTTP/1.1 200 OK', the second packet  
contains the remainder of the headers, the third packet contains the  
body

	Analyzing it with gdb and breaking on hi_server.c line 1480 (right  
before '/*If this is the next expected pac ...')
	* packet 8: data starts with 'HTTP/1.1', expected_pkt is 0 => parsed  
as HTTP headers => OK
	* packet 10: data starts with 'Content-Length...', expected_pkt is 1  
=> parsed as HTTP body => NOT OK, this packet contains headers
	* packet 12: data starts with 'foo', expected_pkt is 1 => parsed as  
HTTP body => OK

120_3_1_B.cap:
	This triggers the 'HI_SERVER_NO_CONTLEN' alert.
	In the dump the HTTP Headers are split over two TCP packets.
	The first packets consist of 'HTTP/1.1 200 OK' while the second  
packet contains the remainder of the headers + the body

	Analyzing it with gdb and breaking on hi_server.c line 1480 (right  
before '/*If this is the next expected pac ...')
	* packet 8: data starts with 'HTTP/1.1', expected_pkt is 0 => parsed  
as HTTP headers => OK
	* packet 10: data starts with 'Content-Length...', expected_pkt is 1  
=> parsed as HTTP body => NOT OK, this packet contains a part of the  
headers and a part of the body



Best regards,

Bram


----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: 120_2_1.cap
Type: application/octet-stream
Size: 2639 bytes
Desc: not available
URL: <https://lists.snort.org/pipermail/snort-devel/attachments/20130812/a15a950d/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 120_3_1_A.cap
Type: application/octet-stream
Size: 1412 bytes
Desc: not available
URL: <https://lists.snort.org/pipermail/snort-devel/attachments/20130812/a15a950d/attachment-0001.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 120_3_1_B.cap
Type: application/octet-stream
Size: 1248 bytes
Desc: not available
URL: <https://lists.snort.org/pipermail/snort-devel/attachments/20130812/a15a950d/attachment-0002.obj>


More information about the Snort-devel mailing list