├── scripts ├── __load__.zeek └── main.zeek ├── tests ├── http.trace ├── travis.sh └── create_pcap.sh ├── .travis.yml ├── zkg.meta ├── LICENSE └── README.md /scripts/__load__.zeek: -------------------------------------------------------------------------------- 1 | @load ./main.zeek 2 | -------------------------------------------------------------------------------- /tests/http.trace: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/precurse/zeek-httpattacks/HEAD/tests/http.trace -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: python 3 | 4 | dist: focal 5 | 6 | os: 7 | - linux 8 | 9 | script: 10 | - tests/travis.sh 11 | -------------------------------------------------------------------------------- /zkg.meta: -------------------------------------------------------------------------------- 1 | [package] 2 | description = Checks for HTTP anomalies typically used for attacking. 3 | script_dir = scripts 4 | tags = http, detection 5 | version = master 6 | -------------------------------------------------------------------------------- /tests/travis.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Install Zeek 3 | echo 'deb http://download.opensuse.org/repositories/security:/zeek/xUbuntu_20.04/ /' | sudo tee /etc/apt/sources.list.d/security:zeek.list 4 | curl -fsSL https://download.opensuse.org/repositories/security:zeek/xUbuntu_20.04/Release.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/security_zeek.gpg > /dev/null 5 | sudo apt-get update -q 6 | sudo apt-get install -y zeek python3-git 7 | 8 | # Test package install 9 | yes Y | sudo /opt/zeek/bin/zkg install . 10 | 11 | # Test log parsing 12 | /opt/zeek/bin/zeek -Cr tests/http.trace -b scripts/main.zeek || true 13 | grep "HTTP_Smuggling" notice.log | wc -l |grep -q 5 14 | 15 | -------------------------------------------------------------------------------- /tests/create_pcap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -ex 3 | python -m SimpleHTTPServer 8080 & 4 | PYPID=$! 5 | sudo tcpdump -i lo -w tests/http.trace port 8080 & 6 | TCPDPID=$! 7 | 8 | sleep 2 # Wait for http server 9 | 10 | # Normal requests 11 | curl -v http://localhost:8080 12 | sleep 2 13 | curl -X PUT -d "var=somedata&var2=moredata&var3=evenmoredata" http://localhost:8080 14 | sleep 2 15 | 16 | # Non RFC compliant 17 | echo -en 'GET /index.html HTTP/1.1\r\nHost: some_host.com\r\nHost: another_host.com\r\n\r\n' \ 18 | | nc localhost 8080 19 | sleep 2 20 | echo -en 'GET /index.html HTTP/1.1\r\nContent-Length: 5\r\nContent-Length: 6\r\n\r\n' \ 21 | | nc localhost 8080 22 | sleep 2 23 | echo -en 'GET /index.html HTTP/1.1\r\nTransfer-Encoding: chunked\r\nTransfer-encoding: x\r\n\r\n' \ 24 | | nc localhost 8080 25 | sleep 2 26 | echo -en 'GET /index.html HTTP/1.1\r\nContent-Length: 5\r\nTransfer-encoding: chunked\r\n\r\n' \ 27 | | nc localhost 8080 28 | sleep 2 29 | curl -vv -X GET -d "some_data=12345&some_more_data=99999" http://localhost:8080 30 | sleep 30 31 | 32 | kill $PYPID 33 | sudo kill $TCPDPID 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2019 Andrew Klaus 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 4 | 5 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 6 | 7 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 8 | 9 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # zeek-httpattacks 2 | 3 | [![Build Status](https://app.travis-ci.com/precurse/zeek-httpattacks.svg?branch=master)](https://app.travis-ci.com/precurse/zeek-httpattacks) 4 | 5 | # Description 6 | 7 | This module detects HTTP requests that are non RFC compliant requests including: 8 | - Multiple HTTP Host headers 9 | - GET requests with a body 10 | - Both `Content-Length` and `Transfer-Encoding` present 11 | - Multiple of `Content-Length` and/or `Transfer-Encoding` headers 12 | 13 | When any of these are detected, an `HTTP_Smuggling` notice will be added to `notice.log`. 14 | 15 | # Installation 16 | - Install via Zeek package manager: 17 | ```bash 18 | $ zkg install zeek-httpattacks 19 | ``` 20 | 21 | - Download the files to `$PREFIX/zeek/share/zeek/site/zeek-httpattacks` and add the following to your `local.zeek`: 22 | ```bash 23 | @load ./zeek-httpattacks 24 | ``` 25 | 26 | # Configuration 27 | 28 | There are currently no configuration flags that can be used with this module. If you would like a new feature, please create a pull request. 29 | 30 | # notice.log Examples 31 | 32 | ``` 33 | HTTPATTACKS::HTTP_Smuggling Multiple HTTP Host headers detected 34 | HTTPATTACKS::HTTP_Smuggling More than one CL or TE header detected 35 | HTTPATTACKS::HTTP_Smuggling CL and TE headers detected 36 | HTTPATTACKS::HTTP_Smuggling HTTP GET request with body detected 37 | ``` 38 | 39 | # Automated Testing 40 | 41 | Travis CI is used to run automated tests on each and every commit. 42 | 43 | # Created By 44 | Andrew Klaus (@precurse) 45 | -------------------------------------------------------------------------------- /scripts/main.zeek: -------------------------------------------------------------------------------- 1 | @load base/protocols/http 2 | @load base/frameworks/notice 3 | 4 | module HTTPATTACKS; 5 | 6 | redef enum Notice::Type += { 7 | HTTP_Smuggling, 8 | }; 9 | 10 | # Check HTTP GET Request for BODY 11 | event http_entity_data(c: connection, is_orig: bool, length: count, data: string) 12 | { 13 | if (is_orig && c$http?$method && c$http$method == "GET") 14 | NOTICE([$note=HTTP_Smuggling, 15 | $msg="HTTP GET request with body detected", 16 | $conn = c]); 17 | } 18 | 19 | event http_all_headers(c: connection, is_orig: bool, hlist: mime_header_list) 20 | { 21 | if (is_orig) { 22 | local host_h_count = 0; 23 | local cl_h_count = 0; 24 | local te_h_count = 0; 25 | 26 | for (i in hlist) 27 | { 28 | if (hlist[i]$name == "HOST") 29 | ++host_h_count; 30 | if (hlist[i]$name == "CONTENT-LENGTH") 31 | ++cl_h_count; 32 | if (hlist[i]$name == "TRANSFER-ENCODING") 33 | ++te_h_count; 34 | } 35 | 36 | if (host_h_count > 1) 37 | NOTICE([$note=HTTP_Smuggling, 38 | $msg="Multiple HTTP Host headers detected", 39 | $conn = c]); 40 | 41 | if (cl_h_count >= 1 && te_h_count >= 1) 42 | NOTICE([$note=HTTP_Smuggling, 43 | $msg="CL and TE headers detected", 44 | $conn = c]); 45 | 46 | if (cl_h_count > 1 || te_h_count > 1 ) 47 | NOTICE([$note=HTTP_Smuggling, 48 | $msg="More than one CL or TE header detected", 49 | $conn = c]); 50 | } 51 | } 52 | --------------------------------------------------------------------------------