commit 8598223e8526b79c86bb2a61ce2c81253137430c Author: Arturo Filastò art@fuffa.org Date: Wed Jan 30 22:46:15 2013 +0100
Add HTTP Filtering bypass tests and some HTTP Trix test
Update HTTP Host test to check for bypassing strategies
Remove InputFile from HTTP Invalid Request Line test
Remove input file and superfluous test --- nettests/experimental/http_filtering_bypassing.py | 84 ++++++++++++++++++++ nettests/experimental/http_trix.py | 47 +++++++++++ nettests/manipulation/http_host.py | 22 +++++- nettests/manipulation/http_invalid_request_line.py | 5 +- 4 files changed, 153 insertions(+), 5 deletions(-)
diff --git a/nettests/experimental/http_filtering_bypassing.py b/nettests/experimental/http_filtering_bypassing.py new file mode 100644 index 0000000..a82994a --- /dev/null +++ b/nettests/experimental/http_filtering_bypassing.py @@ -0,0 +1,84 @@ +# -*- encoding: utf-8 -*- +from twisted.python import usage + +from ooni.utils import log +from ooni.utils import randomStr, randomSTR +from ooni.templates import tcpt + +class UsageOptions(usage.Options): + optParameters = [['backend', 'b', '127.0.0.1', + 'The OONI backend that runs a TCP echo server'], + ['backendport', 'p', 80, 'Specify the port that the TCP echo server is running (should only be set for debugging)']] + +class HTTPFilteringBypass(tcpt.TCPTest): + name = "HTTPFilteringBypass" + version = "0.1" + authors = "xx" + + inputFile = ['file', 'f', None, + 'Specify a list of hostnames to use as inputs'] + + usageOptions = UsageOptions + requiredOptions = ['backend'] + + def setUp(self): + self.port = int(self.localOptions['backendport']) + self.address = self.localOptions['backend'] + + def check_for_manipulation(self, response, payload): + log.debug("Checking if %s == %s" % (response, payload)) + if response != payload: + self.report['tampering'] = True + else: + self.report['tampering'] = False + + def test_prepend_newline(self): + payload = "\nGET / HTTP/1.1\n\r" + payload += "Host: %s\n\r" % self.input + + d = self.sendPayload(payload) + d.addCallback(self.check_for_manipulation, payload) + return d + + def test_tab_trick(self): + payload = "GET / HTTP/1.1\n\r" + payload += "Host: %s\t\n\r" % self.input + + d = self.sendPayload(payload) + d.addCallback(self.check_for_manipulation, payload) + return d + + def test_subdomain_blocking(self): + payload = "GET / HTTP/1.1\n\r" + payload += "Host: %s\n\r" % randomStr(10) + '.' + self.input + + d = self.sendPayload(payload) + d.addCallback(self.check_for_manipulation, payload) + return d + + def test_fuzzy_domain_blocking(self): + hostname_field = randomStr(10) + '.' + self.input + '.' + randomStr(10) + payload = "GET / HTTP/1.1\n\r" + payload += "Host: %s\n\r" % hostname_field + + d = self.sendPayload(payload) + d.addCallback(self.check_for_manipulation, payload) + return d + + def test_fuzzy_match_blocking(self): + hostname_field = randomStr(10) + self.input ++ randomStr(10) + payload = "GET / HTTP/1.1\n\r" + payload += "Host: %s\n\r" % hostname_field + + d = self.sendPayload(payload) + d.addCallback(self.check_for_manipulation, payload) + return d + + def test_normal_request(self): + payload = "GET / HTTP/1.1\n\r" + payload += "Host: %s\n\r" % self.input + + d = self.sendPayload(payload) + d.addCallback(self.check_for_manipulation, payload) + return d + diff --git a/nettests/experimental/http_trix.py b/nettests/experimental/http_trix.py new file mode 100644 index 0000000..85a4ba2 --- /dev/null +++ b/nettests/experimental/http_trix.py @@ -0,0 +1,47 @@ +# -*- encoding: utf-8 -*- +from twisted.python import usage + +from ooni.utils import log +from ooni.utils import randomStr, randomSTR +from ooni.templates import tcpt + +class UsageOptions(usage.Options): + optParameters = [['backend', 'b', '127.0.0.1', + 'The OONI backend that runs a TCP echo server'], + ['backendport', 'p', 80, 'Specify the port that the TCP echo server is running (should only be set for debugging)']] + +class HTTPTrix(tcpt.TCPTest): + name = "HTTPTrix" + version = "0.1" + authors = "Arturo Filastò" + + usageOptions = UsageOptions + requiredOptions = ['backend'] + + def setUp(self): + self.port = int(self.localOptions['backendport']) + self.address = self.localOptions['backend'] + + def check_for_manipulation(self, response, payload): + log.debug("Checking if %s == %s" % (response, payload)) + if response != payload: + self.report['tampering'] = True + else: + self.report['tampering'] = False + + def test_for_squid_cache_object(self): + """ + This detects the presence of a squid transparent HTTP proxy by sending + a request for cache_object://localhost/info. + + This tests for the presence of a Squid Transparent proxy by sending: + + GET cache_object://localhost/info HTTP/1.1 + """ + payload = 'GET cache_object://localhost/info HTTP/1.1' + payload += '\n\r' + + d = self.sendPayload(payload) + d.addCallback(self.check_for_manipulation, payload) + return d + diff --git a/nettests/manipulation/http_host.py b/nettests/manipulation/http_host.py index 3ebfd04..3e0996a 100644 --- a/nettests/manipulation/http_host.py +++ b/nettests/manipulation/http_host.py @@ -9,6 +9,8 @@ import json from twisted.python import usage
+from ooni.utils import randomStr, randomSTR + from ooni.utils import log from ooni.templates import httpt
@@ -31,7 +33,7 @@ class HTTPHost(httpt.HTTPTest): """ name = "HTTP Host" author = "Arturo Filastò" - version = "0.2" + version = "0.2.1"
usageOptions = UsageOptions
@@ -40,6 +42,24 @@ class HTTPHost(httpt.HTTPTest):
requiredOptions = ['backend']
+ def test_filtering_add_tab_to_host(self): + headers = {} + headers["Host"] = [self.input + '\t'] + return self.doRequest('http://%27+self.input, + headers=headers) + + def test_filtering_of_subdomain(self): + headers = {} + headers["Host"] = [randomStr(10) + '.' + self.input] + return self.doRequest('http://%27+self.input, + headers=headers) + + def test_filtering_via_fuzzy_matching(self): + headers = {} + headers["Host"] = [randomStr(10) + self.input + randomStr(10)] + return self.doRequest('http://%27+self.input, + headers=headers) + def test_send_host_header(self): """ Stuffs the HTTP Host header field with the site to be tested for diff --git a/nettests/manipulation/http_invalid_request_line.py b/nettests/manipulation/http_invalid_request_line.py index 01626ab..2482282 100644 --- a/nettests/manipulation/http_invalid_request_line.py +++ b/nettests/manipulation/http_invalid_request_line.py @@ -20,12 +20,9 @@ class HTTPInvalidRequestLine(tcpt.TCPTest): ascii letters or numbers ('XxXx' will be 4). """ name = "HTTP Invalid Request Line" - version = "0.1.3" + version = "0.1.4" authors = "Arturo Filastò"
- inputFile = ['file', 'f', None, - 'Input file of list of hostnames to attempt to resolve'] - usageOptions = UsageOptions requiredOptions = ['backend']