def test_automated_extension(self): """Objective: Test if the dork database extends on new requests to the honeypot. Input: A test request with URL: http://localhost:8080/test.php?c=test Expected Results: An entry in the 'inurl' db table containing '/test.php'. Notes: The test adds the '/test.php' entry to the database.""" attack_event = attack.AttackEvent() attack_event.matched_pattern = "internal_test" attack_event.parsed_request = util.HTTPRequest() attack_event.parsed_request.url = "/thiswillNeVeRHaPPend.php?c=test" print "Attack event prepared." pages_dir = tempfile.mkdtemp() try: (db, engine, dork_generator) = self.dork_generator_chain('sql', pages_dir) dork_generator.regular_generate_dork(0) dork_generator.collect_dork(attack_event) print "Done collecting the path from the event and writing to the database." sql = "SELECT * FROM inurl WHERE content = :x" result = engine.connect().execute(sql, x='/thiswillNeVeRHaPPend.php').fetchall() print "Done fetching the entries matching the request URL" self.assertTrue(len(result) > 0) print "Number of entries in the database matching our URL:", print len(result), print "which equates our expectation." finally: if os.path.isdir(pages_dir): shutil.rmtree(pages_dir)
def test_unknown_emulator(self): """Objective: Emulator testing for non-malicious requests. Input: http://localhost:8080/ Expected Result: One of the generated attack surfaces. Notes:""" tmp_file = os.path.join(self.data_dir, 'dork_pages', format(str(uuid.uuid4()))) with open(tmp_file, 'w+') as f: f.write("tmpfile") print "Starting 'unknown' request emulation module" self.event.parsed_request = util.HTTPRequest() self.event.parsed_request.url = "/" self.event.matched_pattern = "unknown" self.event.response = "" self.event.source_addr = ("127.0.0.1", "8080") request_handler = RequestHandler(self.data_dir) emulator = request_handler.get_handler(self.event.matched_pattern) print "Sending request:", "http://localhost:8080/" emulator.handle(self.event) remote_hash = hashlib.md5(self.event.response).hexdigest() local_hash = hashlib.md5(emulator.template).hexdigest() print "Hash of the local 'response' file:", local_hash self.assertEqual(remote_hash, local_hash) print "Return value:", remote_hash print "matched a generated attack surface item."
def setUp(self): self.event = attack.AttackEvent() self.event.parsed_request = util.HTTPRequest() self.event.parsed_request.url = "/test.php" self.event.parsed_request.parameters_dict = { "q": "SELECT A FROM B", } self.data_dir = tempfile.mkdtemp()
def setUp(self): self.event = attack.AttackEvent() self.event.parsed_request = util.HTTPRequest() self.work_dir = tempfile.mkdtemp() self.data_dir = os.path.join(self.work_dir, 'data/') package_directory = os.path.dirname( os.path.abspath(inspect.getfile(RequestHandler))) #original data as stored with new glatopf installations self.original_data_dir = os.path.join(package_directory, 'emulators/data/') #copy the data to a isolated data directory shutil.copytree(self.original_data_dir, self.data_dir)
def test_phpinfo_emulator(self): """Objective: Emulator testing for phpinfo.php requests Input: http://localhost/phpinfo.php Expected Result: Result of the phpinfo() function Notes:""" self.event.parsed_request = util.HTTPRequest() self.event.parsed_request.method = 'GET' self.event.parsed_request.url = "/info.php?param1" self.event.matched_pattern = "phpinfo" request_handler = RequestHandler(self.data_dir) emulator = request_handler.get_handler(self.event.matched_pattern) emulator.handle(self.event) self.assertTrue("PHP Version " in self.event.response) self.assertTrue("Zend Extension" in self.event.response)
def test_mongodb_insert(self): conn_string = helpers.create_mongo_database(fill=False) db_name = uri_parser.parse_uri(conn_string)['database'] try: maindb = log_mongodb.Database(conn_string) #prepare attack event attack_event = attack.AttackEvent() attack_event.event_time = self.event_time = datetime.now( ).strftime("%Y-%m-%d %H:%M:%S") attack_event.matched_pattern = "test_test" attack_event.source_addr = ("192.168.1.201", 12345) attack_event.parsed_request = util.HTTPRequest() attack_event.parsed_request.url = "/breadandbytter.php?a=b" attack_event.parsed_request.method = "GET" attack_event.parsed_request.header = { 'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3', 'Connection': 'keep-alive' } attack_event.parsed_request.body = "some stuff" maindb.insert(attack_event) with warnings.catch_warnings(record=True): collection = MongoClient(conn_string)[db_name]['events'] results = list(collection.find()) #Check if database returned the correct amount self.assertEqual(len(list(results)), 1) entry = results[0] self.assertEqual(entry["pattern"], "test_test") self.assertEqual(entry["request"]["body"], "some stuff") self.assertEqual(entry["request"]["parameters"], "") self.assertEqual(entry["request"]["url"], "/breadandbytter.php?a=b") self.assertEqual(entry["request"]["header"]['Accept-Charset'], "ISO-8859-1,utf-8;q=0.7,*;q=0.3") self.assertEqual(entry["request"]["header"]['Connection'], "keep-alive") self.assertEqual(entry["request"]["method"], "GET") self.assertEqual(entry["source"][0], "192.168.1.201") self.assertEqual(entry["source"][1], 12345) finally: helpers.delete_mongo_testdata(conn_string)
def test_sqla_insert(self): #in-memory sqlite database sqla_engine = create_engine("sqlite:///") maindb = log_sql.Database(sqla_engine) #prepare attack event attack_event = attack.AttackEvent() attack_event.event_time = self.event_time = datetime.now().strftime( "%Y-%m-%d %H:%M:%S") attack_event.matched_pattern = "test_test" attack_event.source_addr = ("192.168.1.201", 12345) attack_event.parsed_request = util.HTTPRequest() attack_event.parsed_request.url = "/breadandbytter.php?a=b" attack_event.parsed_request.method = "GET" attack_event.parsed_request.header = { 'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3', 'Connection': 'keep-alive' } attack_event.parsed_request.body = "some stuff" #insert attack event maindb.insert(attack_event) #try to extract event from the database sql = "SELECT * FROM events" results = sqla_engine.connect().execute(sql).fetchall() #Check if database returned the correct amount self.assertEqual(len(list(results)), 1) entry = results[0] #check basic attributes #source self.assertEqual(entry[2], "192.168.1.201:12345") #method self.assertEqual(entry[3], "GET") #request_url self.assertEqual(entry[4], "/breadandbytter.php?a=b") #resuest_header self.assertEqual( entry[7], '{"Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.3", "Connection": "keep-alive"}' ) #request_body self.assertEqual(entry[8], "some stuff") #pattern self.assertEqual(entry[9], "test_test")
def test_phpcgi_source_code_disclosure_emulator(self): """Objective: Emulator testing for PHP CGI source code disclosure CVE-2012-1823 Input: http://localhost:8080/index.php?-s Expected Result: Source code disclosure Notes:""" self.event.parsed_request = util.HTTPRequest() self.event.parsed_request.url = "/index.php" self.event.parsed_request.parameters = "-s" self.event.matched_pattern = "php_cgi_rce" self.event.response = "" request_handler = RequestHandler(self.data_dir) emulator = request_handler.get_handler(self.event.matched_pattern) emulator.handle(self.event) self.assertEquals( self.event.response, """<code><span style="color: #000000"> <span style="color: #0000BB"><?php<br />page </span><span style="color: #007700">= </span><span style="color: #0000BB">$_GET</span><span style="color: #007700">[</span><span style="color: #DD0000">'page'</span><span style="color: #007700">];<br />include(</span><span style="color: #0000BB">page</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">?><br /></span> </span>""")
def test_phpcgi_rce_emulator(self): """Objective: Emulator testing for PHP CGI remote code execution CVE-2012-1823 Input: http://localhost/-d+allow_url_include=on+-d+safe_mode=off+-d+open_basedir=off-d+auto_prepend_file=php://input POST: <?php echo("rce attempt"); ?> Expected Result: Remote command execution of a echo command Notes:""" GlastopfHoneypot.prepare_sandbox(self.work_dir) os.mkdir(os.path.join(self.data_dir, 'files/')) self.event.parsed_request = util.HTTPRequest() self.event.parsed_request.method = 'POST' self.event.parsed_request.url = "/index.php" self.event.parsed_request.parameters = "-d+allow_url_include=on+-d+safe_mode=off+-d+open_basedir=off-d+auto_prepend_file=php://input" self.event.matched_pattern = "php_cgi_rce" self.event.parsed_request.body = '<?php echo "testing"; ?>' request_handler = RequestHandler(self.data_dir) emulator = request_handler.get_handler(self.event.matched_pattern) emulator.handle(self.event) print "Return value:", self.event.response self.assertTrue("""testing""" == self.event.response)
def test_rfi_emulator_with_malformed_uri(self): # TODO: Handle return value from sandbox """Objective: Remote File Injection test with malformed uri Input: http://localhost:8080/test.php?p="http://google.com/index.html Expected Result: The return value from the PHP sandbox. Notes: Injected file contains <?php echo("test successful"); ?>""" GlastopfHoneypot.prepare_sandbox(self.work_dir) print "Starting remote file inclusion test" self.event.parsed_request = util.HTTPRequest() self.event.parsed_request.url = "/test.php?p=%22http://1durch0.de/test_file.txt" print "Sending request:", "http://localhost:8080" + self.event.parsed_request.url self.event.matched_pattern = "rfi" self.event.response = "" helpers.create_sandbox(self.data_dir) request_handler = RequestHandler(self.data_dir) emulator = request_handler.get_handler(self.event.matched_pattern) emulator.handle(self.event) self.assertEqual(self.event.response, "test successful") print "Return value 'test successful', matching our expectation."
def test_lfi_emulator(self): """Objective: Local File Inclusion module testing. Input: http://localhost:8080/test.php?p=../../../../../etc/passwd Expected Result: The passwd file from the virtual file system. Notes:""" print "Starting local file inclusion test" with open(os.path.join(self.data_dir, "virtualdocs/linux/etc/passwd"), 'r') as passwd_file: passwd = passwd_file.read() local_hash = hashlib.md5(passwd).hexdigest() print "Hash of the local 'passwd' file:", local_hash self.event.parsed_request = util.HTTPRequest() self.event.parsed_request.url = "/test.php?p=../../../../../etc/passwd" print "Sending request:", "http://localhost:8080" + self.event.parsed_request.url self.event.matched_pattern = "lfi" self.event.response = "" print "Loading the emulator and handling the request." request_handler = RequestHandler(self.data_dir) emulator = request_handler.get_handler(self.event.matched_pattern) emulator.handle(self.event) remote_hash = hashlib.md5(self.event.response).hexdigest() self.assertEqual(remote_hash, local_hash) print "Return value:", remote_hash print "matched the hash of the local file."