def test_honeypot_sql(self): """Objective: Testing overall Honeypot integration. Input: Loads the honeypot module with mongodb as main database. Expected Response: Honeypot responses with a non-empty HTTP response. Note: This test verifies the overall functionality.""" db_file = tempfile.mkstemp()[1] conn_string = "sqlite:///{0}".format(db_file) sql_engine = create_engine(conn_string) helpers.populate_main_sql_testdatabase(sql_engine) config_file = tempfile.mkstemp()[1] with open(config_file, "w") as f: f.writelines(helpers.gen_config(conn_string)) try: raw_request = "GET /honeypot_test HTTP/1.1\r\nHost: honeypot\r\n\r\n" source_address = ["127.0.0.1", "12345"] sensor_address = ["1.2.3.4", "8080"] GlastopfHoneypot.prepare_environment(self.tmpdir) self.glastopf = GlastopfHoneypot(work_dir=self.tmpdir, config=config_file) self.glastopf.options["enabled"] = "False" print "Sending request: http://localhost:8080/" response = self.glastopf.handle_request(raw_request, source_address, sensor_address) self.assertIsNot(response, None) finally: if os.path.isfile(config_file): os.remove(config_file) if os.path.isfile(db_file): os.remove(db_file)
def test_honeypot_mongo(self): """Objective: Testing overall Honeypot integration. Input: Loads the honeypot module with mongodb as main database. Expected Response: Honeypot responses with a non-empty HTTP response. Note: This test verifies the overall functionality.""" conn_string = helpers.create_mongo_database(fill=True) config_file = tempfile.mkstemp()[1] with open(config_file, 'w') as f: f.writelines(helpers.gen_config(conn_string)) try: raw_request = "GET /honeypot_test HTTP/1.1\r\nHost: honeypot\r\n\r\n" source_address = ["127.0.0.1", "12345"] GlastopfHoneypot.prepare_environment(self.tmpdir) self.glastopf = GlastopfHoneypot(work_dir=self.tmpdir, config=config_file) self.glastopf.options["enabled"] = "False" print "Sending request: http://localhost:8080/" connection = FakeCon() connection.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) response = self.glastopf.handle_request(raw_request, source_address, connection) connection.sock.close() self.assertIsNot(response, None) finally: helpers.delete_mongo_testdata(conn_string) if os.path.isfile(config_file): os.remove(config_file)
def test_honeypot_sql(self): """Objective: Testing overall Honeypot integration. Input: Loads the honeypot module with mongodb as main database. Expected Response: Honeypot responses with a non-empty HTTP response. Note: This test verifies the overall functionality.""" db_file = tempfile.mkstemp()[1] conn_string = "sqlite:///{0}".format(db_file) sql_engine = create_engine(conn_string) helpers.populate_main_sql_testdatabase(sql_engine) config_file = tempfile.mkstemp()[1] with open(config_file, 'w') as f: f.writelines(helpers.gen_config(conn_string)) try: raw_request = "GET /honeypot_test HTTP/1.1\r\nHost: honeypot\r\n\r\n" source_address = ["127.0.0.1", "12345"] sensor_address = ["1.2.3.4", "8080"] GlastopfHoneypot.prepare_environment(self.tmpdir) self.glastopf = GlastopfHoneypot(work_dir=self.tmpdir, config=config_file) self.glastopf.options["enabled"] = "False" print "Sending request: http://localhost:8080/" response = self.glastopf.handle_request(raw_request, source_address, sensor_address) self.assertIsNot(response, None) finally: if os.path.isfile(config_file): os.remove(config_file) if os.path.isfile(db_file): os.remove(db_file)
def setUp(self): self.work_dir = tempfile.mkdtemp() GlastopfHoneypot.prepare_environment(self.work_dir) 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/')
def setUp(self): self.config = ConfigParser() self.config.add_section('main-database') self.config.set('main-database', 'enabled', "True") self.workdir = tempfile.mkdtemp() self.datadir = os.path.join(self.workdir, 'data') GlastopfHoneypot.prepare_environment(self.workdir)
def test_get_entry(self): """Objective: Test if the entries generated by the '_get_entry()'different. Input: Return value from GlastopfHoneypot._get_entry() Expected Result: Two runs of GlastopfHoneypot._get_entry() generate different results Notes:""" user_id1 = random.randint(1000, 1500) # Realistic user ID pwd_entry1, shd_entry1, grp_entry1 = GlastopfHoneypot._get_entry(user_id1) user_id2 = random.randint(1000, 1500) pwd_entry2, shd_entry2, grp_entry2 = GlastopfHoneypot._get_entry(user_id2) self.assertNotEqual(pwd_entry1, pwd_entry2) self.assertNotEqual(shd_entry1, shd_entry2) self.assertNotEqual(grp_entry1, grp_entry2)
def test_get_entry(self): """Objective: Test if the entries generated by the '_get_entry()'different. Input: Return value from GlastopfHoneypot._get_entry() Expected Result: Two runs of GlastopfHoneypot._get_entry() generate different results Notes:""" user_id1 = random.randint(1000, 1500) # Realistic user ID pwd_entry1, shd_entry1, grp_entry1 = GlastopfHoneypot._get_entry( user_id1) user_id2 = random.randint(1000, 1500) pwd_entry2, shd_entry2, grp_entry2 = GlastopfHoneypot._get_entry( user_id2) self.assertNotEqual(pwd_entry1, pwd_entry2) self.assertNotEqual(shd_entry1, shd_entry2) self.assertNotEqual(grp_entry1, grp_entry2)
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/')) request = "POST /index.php?-d+allow_url_include=on+-d+safe_mode=off+-d+open_basedir=off-d+auto_prepend_file=php://input HTTP/1.0\r\n\r\n" \ '<?php echo "testing"; ?>' event = attack.AttackEvent() event.http_request = HTTPHandler(request, None) event.matched_pattern = "php_cgi_rce" request_handler = RequestHandler(self.data_dir) emulator = request_handler.get_handler(event.matched_pattern) emulator.handle(event) print "Return value:", event.http_request.get_response() self.assertTrue("""testing""" == event.http_request.get_response())
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" event = attack.AttackEvent() event.http_request = HTTPHandler('GET /test.php?p=http://1durch0.de/test_file.txt HTTP/1.0', None) event.matched_pattern = "rfi" helpers.create_sandbox(self.data_dir) request_handler = RequestHandler(self.data_dir) emulator = request_handler.get_handler(event.matched_pattern) print "Sending request:", "http://localhost:8080" + event.http_request.path emulator.handle(event) self.assertEqual(event.http_request.get_response(), "test successful") print "Return value 'test successful', matching our expectation."
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" event = attack.AttackEvent() url = "https://gist.githubusercontent.com/glaslos/02c4c4be39fb03b3bbee5c862cd304c6/raw/adf146469e8eeee4498874164ecd80c70ffb4e7a/test_file.txt" event.http_request = HTTPHandler('GET /test.php?p={} HTTP/1.0'.format(url), None) event.matched_pattern = "rfi" helpers.create_sandbox(self.data_dir) request_handler = RequestHandler(self.data_dir) emulator = request_handler.get_handler(event.matched_pattern) print "Sending request:", "http://localhost:8080" + event.http_request.path emulator.handle(event) self.assertEqual(event.http_request.get_response(), "test successful") print "Return value 'test successful', matching our expectation."
def test_rfi_emulator(self): # TODO: Handle return value from sandbox """Objective: Remote File Injection test. 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=http://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_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" event = attack.AttackEvent() url = "https://gist.githubusercontent.com/glaslos/02c4c4be39fb03b3bbee5c862cd304c6/raw/adf146469e8eeee4498874164ecd80c70ffb4e7a/test_file.txt" event.http_request = HTTPHandler( 'GET /test.php?p={} HTTP/1.0'.format(url), None) event.matched_pattern = "rfi" helpers.create_sandbox(self.data_dir) request_handler = RequestHandler(self.data_dir) emulator = request_handler.get_handler(event.matched_pattern) print "Sending request:", "http://localhost:8080" + event.http_request.path emulator.handle(event) self.assertEqual(event.http_request.get_response(), "test successful") print "Return value 'test successful', matching our expectation."
def test_virtualdocs(self): """Objective: Test for the creation of random files in the virtual directories Input: Return value from GlastopfHoneypot.randomize_vdocs() Expected Result: Two runs of GlastopfHoneypot.randomize_vdocs() have different results Notes:""" v_files = ("shadow", "passwd", "group") f_dir1 = tempfile.mkdtemp() f_dir2 = tempfile.mkdtemp() os.makedirs(os.path.join(f_dir1, "linux/etc")) os.makedirs(os.path.join(f_dir2, "linux/etc")) GlastopfHoneypot.randomize_vdocs(f_dir1) GlastopfHoneypot.randomize_vdocs(f_dir2) for v_file in v_files: file_1 = open(os.path.join(f_dir1, "linux/etc/", v_file), "r") file_2 = open(os.path.join(f_dir2, "linux/etc/", v_file), "r") md5_1 = hashlib.md5(file_1.read()).hexdigest() md5_2 = hashlib.md5(file_2.read()).hexdigest() file_1.close() file_2.close() self.assertNotEqual(md5_1, md5_2) shutil.rmtree(f_dir1) shutil.rmtree(f_dir2)
def setUp(self): self.tmpdir = tempfile.mkdtemp() data_dir = os.path.join(self.tmpdir, 'data') GlastopfHoneypot.prepare_environment(self.tmpdir) self.requestClassifier = request_classifier.Classifier(data_dir)
class TestHoneypotFunctionality(unittest.TestCase): """Tests the basic honeypot functionality Test set-up instantiates the honeypot. The main Test sends a request and checks the response.""" def setUp(self): self.tmpdir = tempfile.mkdtemp() def tearDown(self): if os.path.isdir(self.tmpdir): shutil.rmtree(self.tmpdir) @unittest.skip('disabled until mongodb is a real database') def test_honeypot_mongo(self): """Objective: Testing overall Honeypot integration. Input: Loads the honeypot module with mongodb as main database. Expected Response: Honeypot responses with a non-empty HTTP response. Note: This test verifies the overall functionality.""" conn_string = helpers.create_mongo_database(fill=True) config_file = tempfile.mkstemp()[1] with open(config_file, 'w') as f: f.writelines(helpers.gen_config(conn_string)) try: raw_request = "GET /honeypot_test HTTP/1.1\r\nHost: honeypot\r\n\r\n" source_address = ["127.0.0.1", "12345"] sensor_address = ["1.2.3.4", "8080"] GlastopfHoneypot.prepare_environment(self.tmpdir) self.glastopf = GlastopfHoneypot(work_dir=self.tmpdir, config=config_file) self.glastopf.options["enabled"] = "False" print "Sending request: http://localhost:8080/" response = self.glastopf.handle_request(raw_request, source_address, sensor_address) self.assertIsNot(response, None) finally: helpers.delete_mongo_testdata(conn_string) if os.path.isfile(config_file): os.remove(config_file) def test_honeypot_sql(self): """Objective: Testing overall Honeypot integration. Input: Loads the honeypot module with mongodb as main database. Expected Response: Honeypot responses with a non-empty HTTP response. Note: This test verifies the overall functionality.""" db_file = tempfile.mkstemp()[1] conn_string = "sqlite:///{0}".format(db_file) sql_engine = create_engine(conn_string) helpers.populate_main_sql_testdatabase(sql_engine) config_file = tempfile.mkstemp()[1] with open(config_file, 'w') as f: f.writelines(helpers.gen_config(conn_string)) try: raw_request = "GET /honeypot_test HTTP/1.1\r\nHost: honeypot\r\n\r\n" source_address = ["127.0.0.1", "12345"] sensor_address = ["1.2.3.4", "8080"] GlastopfHoneypot.prepare_environment(self.tmpdir) self.glastopf = GlastopfHoneypot(work_dir=self.tmpdir, config=config_file) self.glastopf.options["enabled"] = "False" print "Sending request: http://localhost:8080/" response = self.glastopf.handle_request(raw_request, source_address, sensor_address) self.assertIsNot(response, None) finally: if os.path.isfile(config_file): os.remove(config_file) if os.path.isfile(db_file): os.remove(db_file)
def setUp(self): self.workdir = tempfile.mkdtemp() self.datadir = os.path.join(self.workdir, 'data') GlastopfHoneypot.prepare_environment(self.workdir)
class TestHoneypotFunctionality(unittest.TestCase): """Tests the basic honeypot functionality Test set-up instantiates the honeypot. The main Test sends a request and checks the response.""" def setUp(self): self.tmpdir = tempfile.mkdtemp() def tearDown(self): if os.path.isdir(self.tmpdir): shutil.rmtree(self.tmpdir) def test_honeypot_mongo(self): """Objective: Testing overall Honeypot integration. Input: Loads the honeypot module with mongodb as main database. Expected Response: Honeypot responses with a non-empty HTTP response. Note: This test verifies the overall functionality.""" conn_string = helpers.create_mongo_database(fill=True) config_file = tempfile.mkstemp()[1] with open(config_file, 'w') as f: f.writelines(helpers.gen_config(conn_string)) try: raw_request = "GET /honeypot_test HTTP/1.1\r\nHost: honeypot\r\n\r\n" source_address = ["127.0.0.1", "12345"] sensor_address = ["1.2.3.4", "8080"] GlastopfHoneypot.prepare_environment(self.tmpdir) self.glastopf = GlastopfHoneypot(work_dir=self.tmpdir, config=config_file) self.glastopf.options["enabled"] = "False" print "Sending request: http://localhost:8080/" response = self.glastopf.handle_request(raw_request, source_address, sensor_address) self.assertIsNot(response, None) finally: helpers.delete_mongo_testdata(conn_string) if os.path.isfile(config_file): os.remove(config_file) def test_honeypot_sql(self): """Objective: Testing overall Honeypot integration. Input: Loads the honeypot module with mongodb as main database. Expected Response: Honeypot responses with a non-empty HTTP response. Note: This test verifies the overall functionality.""" db_file = tempfile.mkstemp()[1] conn_string = "sqlite:///{0}".format(db_file) sql_engine = create_engine(conn_string) helpers.populate_main_sql_testdatabase(sql_engine) config_file = tempfile.mkstemp()[1] with open(config_file, 'w') as f: f.writelines(helpers.gen_config(conn_string)) try: raw_request = "GET /honeypot_test HTTP/1.1\r\nHost: honeypot\r\n\r\n" source_address = ["127.0.0.1", "12345"] sensor_address = ["1.2.3.4", "8080"] GlastopfHoneypot.prepare_environment(self.tmpdir) self.glastopf = GlastopfHoneypot(work_dir=self.tmpdir, config=config_file) self.glastopf.options["enabled"] = "False" print "Sending request: http://localhost:8080/" response = self.glastopf.handle_request(raw_request, source_address, sensor_address) self.assertIsNot(response, None) finally: if os.path.isfile(config_file): os.remove(config_file) if os.path.isfile(db_file): os.remove(db_file)
file_log.setLevel(logging.DEBUG) file_log.setFormatter(formatter) root_logger.addHandler(file_log) if __name__ == '__main__': parser = argparse.ArgumentParser(description='Glastopf runner') #defaults to current directory (aka. working directory) parser.add_argument('--workdir', dest='workdir', default=os.getcwd()) parser.add_argument('--prepare', action='store_true', default=False) args = parser.parse_args() #prepare directory if workdir directory contains no files or if we are asked to do it. if args.prepare or len(os.listdir(args.workdir)) == 0: GlastopfHoneypot.prepare_environment(args.workdir) conf_parser = ConfigParser() if not os.path.isfile("glastopf.cfg"): sys.exit("Could not find configuration file: glastopf.cfg") conf_parser.read("glastopf.cfg") if conf_parser.getboolean("logging", "filelog_enabled"): logfile = conf_parser.get("logging", "logfile") else: logfile = None logconsole = conf_parser.getboolean("logging", "consolelog_enabled") logger = logging.getLogger() setup_logging(logconsole, logfile) host = conf_parser.get("webserver", "host") port = conf_parser.getint("webserver", "port")