def test_ls_long_backref(self): """ Test basic 'ls -l .. var' with multiple directory arguments """ honeypot = Hornet(self.working_dir) honeypot.start() self.create_filesystem(honeypot) while honeypot.server.server_port == 0: # wait until the server is ready gevent.sleep(0) port = honeypot.server.server_port client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # If we log in properly, this should raise no errors client.connect('127.0.0.1', port=port, username='******', password='******') channel = client.invoke_shell() while not channel.recv_ready(): gevent.sleep(0) # :-( welcome = '' while channel.recv_ready(): welcome += channel.recv(1) lines = welcome.split('\r\n') prompt = lines[-1] self.assertTrue(prompt.endswith('$ ')) # Now send the ls command ls_command = 'ls -l .. var' channel.send(ls_command + '\r\n') while not channel.recv_ready(): gevent.sleep(0) # :-( output = '' while not output.endswith('$ '): output += channel.recv(1) lines = output.split('\r\n') command = lines[0] command_output = '\r\n'.join(lines[1:-1]) next_prompt = lines[-1] self.assertEquals(command, ls_command) dir_outputs = sorted(command_output.split('\r\n\r\n')) self.assertTrue(dir_outputs[0].startswith('..:')) self.assertTrue('total ' in dir_outputs[0]) self.assertTrue('var' in dir_outputs[0]) self.assertTrue('bin' in dir_outputs[0]) self.assertTrue('initrd.img' in dir_outputs[0]) self.assertTrue('etc' in dir_outputs[0]) self.assertEquals(len(dir_outputs[0].split('\r\n')), 6) self.assertTrue(dir_outputs[1].startswith('var:')) self.assertTrue('total 0' in dir_outputs[1]) self.assertEquals(len(dir_outputs[1].split('\r\n')), 2) self.assertTrue(next_prompt.endswith('$ ')) honeypot.stop()
def test_basic_ls_all_with_multiple_dir_args(self): """ Test basic 'ls -a etc var' """ honeypot = Hornet(self.working_dir) honeypot.start() self.create_filesystem(honeypot) while honeypot.server.server_port == 0: # wait until the server is ready gevent.sleep(0) port = honeypot.server.server_port client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # If we log in properly, this should raise no errors client.connect('127.0.0.1', port=port, username='******', password='******') channel = client.invoke_shell() while not channel.recv_ready(): gevent.sleep(0) # :-( welcome = '' while channel.recv_ready(): welcome += channel.recv(1) lines = welcome.split('\r\n') prompt = lines[-1] self.assertTrue(prompt.endswith('$ ')) # Now send the ls command ls_command = 'ls -a etc var' channel.send(ls_command + '\r\n') while not channel.recv_ready(): gevent.sleep(0) # :-( output = '' while not output.endswith('$ '): output += channel.recv(1) lines = output.split('\r\n') command = lines[0] command_output = '\r\n'.join(lines[1:-1]) next_prompt = lines[-1] dir_outputs = sorted(command_output.split('\r\n\r\n')) self.assertEquals(command, ls_command) self.assertTrue('passwd' in dir_outputs[0]) self.assertTrue('.config' in dir_outputs[0]) self.assertTrue('. ' in dir_outputs[0]) self.assertTrue('..' in dir_outputs[0]) self.assertTrue('init.d' in dir_outputs[0]) self.assertTrue('sysctl.conf' in dir_outputs[0]) self.assertTrue("var:" in dir_outputs[1]) self.assertTrue(next_prompt.endswith('$ ')) honeypot.stop()
def test_ifconfig(self): """ Tests if ifconfig command works """ honeypot = Hornet(self.working_dir) honeypot.start() self.create_filesystem(honeypot) while honeypot.server.server_port == 0: # wait until the server is ready gevent.sleep(0) port = honeypot.server.server_port client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # If we log in properly, this should raise no errors client.connect('127.0.0.1', port=port, username='******', password='******') channel = client.invoke_shell() while not channel.recv_ready(): gevent.sleep(0) # :-( welcome = '' while channel.recv_ready(): welcome += channel.recv(1) lines = welcome.split('\r\n') prompt = lines[-1] self.assertTrue(prompt.endswith('$ ')) # Now send the cd command cd_command = 'ifconfig' channel.send(cd_command + '\r\n') while not channel.recv_ready(): gevent.sleep(0) # :-( output = '' while not output.endswith('$ '): output += channel.recv(1) lines = output.split('\r\n') command = lines[0] command_output = '\r\n'.join(lines[1:-1]) next_prompt = lines[-1] self.assertEquals(command, cd_command) interfaces = sorted(command_output.split('\r\n\r\n')) self.assertTrue(interfaces[0].startswith('eth0 ')) self.assertTrue('HWaddr 00:16:3e:76:35:d1' in interfaces[0]) self.assertTrue('inet addr:192.168.0.232 ' in interfaces[0]) self.assertTrue('Bcast:192.168.0.255 ' in interfaces[0]) self.assertTrue('Mask:255.255.255.0' in interfaces[0]) self.assertTrue(interfaces[1].startswith('lo ')) self.assertTrue('inet addr:127.0.0.1 ' in interfaces[1]) self.assertTrue('Mask:255.0.0.0' in interfaces[1]) self.assertTrue(next_prompt.endswith('$ ')) honeypot.stop()
def test_vfs_creation(self): """ Tests whether virtual file systems for each host are created """ honeypot = Hornet(self.working_dir) honeypot.start() vfs_dir = os.path.join(self.working_dir, 'vhosts') self.assertTrue(os.path.isdir(vfs_dir)) for item in os.listdir(vfs_dir): self.assertTrue(item.startswith('test')) honeypot.stop()
def test_ifconfig_help_param(self): """ Tests if 'ifconfig --help' works """ honeypot = Hornet(self.working_dir) honeypot.start() self.create_filesystem(honeypot) while honeypot.server.server_port == 0: # wait until the server is ready gevent.sleep(0) port = honeypot.server.server_port client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # If we log in properly, this should raise no errors client.connect('127.0.0.1', port=port, username='******', password='******') channel = client.invoke_shell() while not channel.recv_ready(): gevent.sleep(0) # :-( welcome = '' while channel.recv_ready(): welcome += channel.recv(1) lines = welcome.split('\r\n') prompt = lines[-1] self.assertTrue(prompt.endswith('$ ')) # Now send the ifconfig command ifconfig_command = 'ifconfig --help' channel.send(ifconfig_command + '\r\n') while not channel.recv_ready(): gevent.sleep(0) # :-( output = '' while not output.endswith('$ '): output += channel.recv(1) lines = output.split('\r\n') command = lines[0] command_output = '\r\n'.join(lines[1:-1]) next_prompt = lines[-1] expected_output = [] help_file_path = os.path.join(os.path.dirname(hornet.__file__), 'data', 'commands', 'ifconfig', 'help') with open(help_file_path) as help_file: for line in help_file: line = line.strip() expected_output.append(line) self.assertEquals(command, ifconfig_command) self.assertEquals(command_output, '\r\n'.join(expected_output)) self.assertTrue(next_prompt.endswith('$ ')) honeypot.stop()
def test_wget_bad_content_length(self): """ Tests if 'wget http://pathod.net/response_preview?spec=200%3Ar%3Ah%22Content-Length %22%3D%22%27unparsable%22' shows an error resolving """ honeypot = Hornet(self.working_dir) honeypot.start() while honeypot.server.server_port == 0: # wait until the server is ready gevent.sleep(0) port = honeypot.server.server_port client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # If we log in properly, this should raise no errors client.connect('127.0.0.1', port=port, username='******', password='******') channel = client.invoke_shell() while not channel.recv_ready(): gevent.sleep(0) # :-( welcome = '' while channel.recv_ready(): welcome += channel.recv(1) lines = welcome.split('\r\n') prompt = lines[-1] self.assertTrue(prompt.endswith('$ ')) # Now send the wget command wget_command = 'wget http://pathod.net/response_preview?spec=200%3Ar%3Ah%22' \ 'Content-Length%22%3D%22%27unparsable%22' channel.send(wget_command + '\r\n') while not channel.recv_ready(): gevent.sleep(0) # :-( output = '' while not output.endswith('$ '): output += channel.recv(1) lines = output.split('\r\n') command = lines[0] next_prompt = lines[-1] self.assertEquals(command, wget_command) self.assertTrue(lines[1].startswith('--')) self.assertTrue('http://pathod.net/response_preview?spec=200%3Ar%3Ah%22' 'Content-Length%22%3D%22%27unparsable%22' in lines[1]) self.assertEquals('Resolving pathod.net (pathod.net)... ' 'failed: Name or service not known.', lines[2]) self.assertEquals('wget: unable to resolve host address \'pathod.net\'', lines[3]) self.assertTrue(next_prompt.endswith('$ ')) honeypot.stop()
def test_uname_with_params(self): """ Tests if 'uname -a' command works """ honeypot = Hornet(self.working_dir) honeypot.start() self.create_filesystem(honeypot) while honeypot.server.server_port == 0: # wait until the server is ready gevent.sleep(0) port = honeypot.server.server_port client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # If we log in properly, this should raise no errors client.connect('127.0.0.1', port=port, username='******', password='******') channel = client.invoke_shell() while not channel.recv_ready(): gevent.sleep(0) # :-( welcome = '' while channel.recv_ready(): welcome += channel.recv(1) lines = welcome.split('\r\n') prompt = lines[-1] self.assertTrue(prompt.endswith('$ ')) # Now send the cd command uname_command = 'uname -a' channel.send(uname_command + '\r\n') while not channel.recv_ready(): gevent.sleep(0) # :-( output = '' while not output.endswith('$ '): output += channel.recv(1) lines = output.split('\r\n') command = lines[0] command_output = '\r\n'.join(lines[1:-1]) next_prompt = lines[-1] expected_info = ['Linux', honeypot.config.default_hostname, '3.13.0-37-generic', '#64-Ubuntu SMP Mon Sep 22 21:30:01 UTC 2014', 'i686', 'i686', 'i686', 'GNU/Linux'] self.assertEquals(command, uname_command) self.assertEquals(command_output, ' '.join(expected_info)) self.assertTrue(next_prompt.endswith('$ ')) honeypot.stop()
def test_login_success(self): """ Tests whether an SSH client can login to the Honeypot """ honeypot = Hornet(self.working_dir) honeypot.start() while honeypot.server.server_port == 0: # wait until the server is ready gevent.sleep(0) port = honeypot.server.server_port client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # If we log in properly, this should raise no errors client.connect('127.0.0.1', port=port, username='******', password='******') gevent.sleep(1) honeypot.stop()
def test_wget_bad_hostname(self): """ Tests if 'wget http://asdjkhaskdh/index.html' works (bad hostname case) """ honeypot = Hornet(self.working_dir) honeypot.start() while honeypot.server.server_port == 0: # wait until the server is ready gevent.sleep(0) port = honeypot.server.server_port client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # If we log in properly, this should raise no errors client.connect('127.0.0.1', port=port, username='******', password='******') channel = client.invoke_shell() while not channel.recv_ready(): gevent.sleep(0) # :-( welcome = '' while channel.recv_ready(): welcome += channel.recv(1) lines = welcome.split('\r\n') prompt = lines[-1] self.assertTrue(prompt.endswith('$ ')) # Now send the wget command wget_command = 'wget http://asdjkhaskdh/index.html' channel.send(wget_command + '\r\n') while not channel.recv_ready(): gevent.sleep(0) # :-( output = '' while not output.endswith('$ '): output += channel.recv(1) lines = output.split('\r\n') command = lines[0] next_prompt = lines[-1] self.assertEquals(command, wget_command) self.assertTrue(lines[1].startswith('--')) self.assertTrue('http://asdjkhaskdh/index.html' in lines[1]) self.assertEquals('Resolving asdjkhaskdh (asdjkhaskdh)... ' 'failed: Name or service not known.', lines[2]) self.assertEquals('wget: unable to resolve host address \'asdjkhaskdh\'', lines[3]) self.assertTrue(next_prompt.endswith('$ ')) honeypot.stop()
def test_ls_ld(self): """ Test basic 'ls -ld var bin etc/passwd initrd.img' with files as well as directories """ honeypot = Hornet(self.working_dir) honeypot.start() self.create_filesystem(honeypot) while honeypot.server.server_port == 0: # wait until the server is ready gevent.sleep(0) port = honeypot.server.server_port client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # If we log in properly, this should raise no errors client.connect('127.0.0.1', port=port, username='******', password='******') channel = client.invoke_shell() while not channel.recv_ready(): gevent.sleep(0) # :-( welcome = '' while channel.recv_ready(): welcome += channel.recv(1) lines = welcome.split('\r\n') prompt = lines[-1] self.assertTrue(prompt.endswith('$ ')) # Now send the ls command ls_command = 'ls -ld var bin etc/passwd initrd.img' channel.send(ls_command + '\r\n') while not channel.recv_ready(): gevent.sleep(0) # :-( output = '' while not output.endswith('$ '): output += channel.recv(1) lines = output.split('\r\n') command = lines[0] command_output = '\r\n'.join(lines[1:-1]) next_prompt = lines[-1] self.assertEquals(command, ls_command) actual_list = command_output.split('\r\n') expected_list = ['initrd.img', 'var', 'passwd', 'bin'] self.verify_long_list(actual_list, expected_list) self.assertTrue('total' not in command_output) self.assertTrue(next_prompt.endswith('$ ')) honeypot.stop()
def test_login_failure(self): """ Tests whether an SSH client login fails on bad credentials """ honeypot = Hornet(self.working_dir) honeypot.start() while honeypot.server.server_port == 0: # wait until the server is ready gevent.sleep(0) port = honeypot.server.server_port client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) with self.assertRaises(paramiko.AuthenticationException): client.connect('127.0.0.1', port=port, username='******', password='******') gevent.sleep(1) honeypot.stop()
def test_key_creation(self): """ Tests if key file is generated on run """ honeypot = Hornet(self.working_dir) honeypot.start() while honeypot.server.server_port == 0: # wait until the server is ready gevent.sleep(0) port = honeypot.server.server_port client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect('127.0.0.1', port=port, username='******', password='******') # Add a sleep here if this test fails for no reason... the server needs time to write the key file # gevent.sleep(1) self.assertTrue(os.path.isfile(os.path.join(self.working_dir, 'test_server.key'))) honeypot.stop()
def test_ping_multiple_hosts(self): """ Tests basic 'ping lolwakaka awasd' Makes sure the last param is picked up as the host to ping. """ honeypot = Hornet(self.working_dir) honeypot.start() while honeypot.server.server_port == 0: # wait until the server is ready gevent.sleep(0) port = honeypot.server.server_port client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # If we log in properly, this should raise no errors client.connect('127.0.0.1', port=port, username='******', password='******') channel = client.invoke_shell() while not channel.recv_ready(): gevent.sleep(0) # :-( welcome = '' while channel.recv_ready(): welcome += channel.recv(1) lines = welcome.split('\r\n') prompt = lines[-1] self.assertTrue(prompt.endswith('$ ')) # Now send the ping command ping_command = 'ping lolwakaka awasd' channel.send(ping_command + '\r\n') while not channel.recv_ready(): gevent.sleep(0) # :-( output = '' while not output.endswith('$ '): output += channel.recv(1) lines = output.split('\r\n') command = lines[0] command_output = '\r\n'.join(lines[1:-1]) next_prompt = lines[-1] self.assertEquals(command, ping_command) self.assertEquals(command_output, 'ping: unknown host awasd') self.assertTrue(next_prompt.endswith('$ ')) honeypot.stop()
def test_default_welcome_message(self): """ Tests whether a virtual host loads a default welcome message """ honeypot = Hornet(self.working_dir) for ip, host in honeypot.vhosts.iteritems(): self.assertTrue(host.welcome.startswith('Welcome to '))
def test_ls_l_non_existant_path(self): """ Test basic 'ls -l nonexistantpath' with non-existant path argument """ honeypot = Hornet(self.working_dir) honeypot.start() self.create_filesystem(honeypot) while honeypot.server.server_port == 0: # wait until the server is ready gevent.sleep(0) port = honeypot.server.server_port client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # If we log in properly, this should raise no errors client.connect('127.0.0.1', port=port, username='******', password='******') channel = client.invoke_shell() while not channel.recv_ready(): gevent.sleep(0) # :-( welcome = '' while channel.recv_ready(): welcome += channel.recv(1) lines = welcome.split('\r\n') prompt = lines[-1] self.assertTrue(prompt.endswith('$ ')) # Now send the ls command ls_command = 'ls -l nonexistantpath' channel.send(ls_command + '\r\n') while not channel.recv_ready(): gevent.sleep(0) # :-( output = '' while not output.endswith('$ '): output += channel.recv(1) lines = output.split('\r\n') command = lines[0] command_output = '\r\n'.join(lines[1:-1]) next_prompt = lines[-1] self.assertEquals(command, ls_command) self.assertEquals(command_output, 'ls: cannot access nonexistantpath: No such file or directory') self.assertTrue(next_prompt.endswith('$ ')) honeypot.stop()
def test_ifconfig_bad_input_multiple_params(self): """ Tests if 'ifconfig asd up' works """ honeypot = Hornet(self.working_dir) honeypot.start() self.create_filesystem(honeypot) while honeypot.server.server_port == 0: # wait until the server is ready gevent.sleep(0) port = honeypot.server.server_port client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # If we log in properly, this should raise no errors client.connect('127.0.0.1', port=port, username='******', password='******') channel = client.invoke_shell() while not channel.recv_ready(): gevent.sleep(0) # :-( welcome = '' while channel.recv_ready(): welcome += channel.recv(1) lines = welcome.split('\r\n') prompt = lines[-1] self.assertTrue(prompt.endswith('$ ')) # Now send the cd command cd_command = 'ifconfig asd lol' channel.send(cd_command + '\r\n') while not channel.recv_ready(): gevent.sleep(0) # :-( output = '' while not output.endswith('$ '): output += channel.recv(1) lines = output.split('\r\n') command = lines[0] command_output = '\r\n'.join(lines[1:-1]) next_prompt = lines[-1] self.assertEquals(command, cd_command) self.assertEquals(command_output, 'SIOCSIFFLAGS: Operation not permitted') self.assertTrue(next_prompt.endswith('$ ')) honeypot.stop()
def test_custom_welcome_message(self): honeypot = Hornet(self.working_dir) random_host = get_random_item(honeypot.vhosts) random_host.filesystem.makedir('/etc') with random_host.filesystem.open('/etc/motd', 'w') as motd_file: motd_file.write(u'TestingCustomWelcomeMessage') self.assertEquals(random_host.welcome, u'TestingCustomWelcomeMessage')
def test_ssh_with_username(self): """ Tests if ssh command works when username is provided in host string eg: $ ssh mango@test01 """ honeypot = Hornet(self.working_dir) honeypot.start() while honeypot.server.server_port == 0: # wait until the server is ready gevent.sleep(0) port = honeypot.server.server_port client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # If we log in properly, this should raise no errors client.connect('127.0.0.1', port=port, username='******', password='******') channel = client.invoke_shell() while not channel.recv_ready(): gevent.sleep(0) # :-( welcome = '' while channel.recv_ready(): welcome += channel.recv(1) lines = welcome.split('\r\n') prompt = lines[-1] self.assertTrue(prompt.endswith('$ ')) # Now send the ssh command channel.send('ssh root@test01\r\n') while not channel.recv_ready(): gevent.sleep(0) # :-( output = '' while not output.endswith('Password:'******'toor\r\n') output = '' while not output.endswith('$ '): output += channel.recv(1) self.assertTrue('Welcome to test01 server' in output) self.assertTrue(output.endswith('$ ')) honeypot.stop()
def test_logout_close(self): """ Tests logout command when only logged in to the default VirtualHost eg: $ logout """ honeypot = Hornet(self.working_dir) honeypot.start() while honeypot.server.server_port == 0: # wait until the server is ready gevent.sleep(0) port = honeypot.server.server_port client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # If we log in properly, this should raise no errors client.connect('127.0.0.1', port=port, username='******', password='******') channel = client.invoke_shell() while not channel.recv_ready(): gevent.sleep(0) # :-( welcome = '' while channel.recv_ready(): welcome += channel.recv(1) lines = welcome.split('\r\n') prompt = lines[-1] self.assertTrue(prompt.endswith('$ ')) # Now send the logout command channel.send('logout\r\n') honeypot.stop()
def test_shell_set_host(self): """ Tests if host related attributes are set on the shell properly """ honeypot = Hornet(self.working_dir) honeypot.start() while honeypot.server.server_port == 0: # wait until the server is ready gevent.sleep(0) port = honeypot.server.server_port client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # If we log in properly, this should raise no errors client.connect('127.0.0.1', port=port, username='******', password='******') channel = client.invoke_shell() while not channel.recv_ready(): gevent.sleep(0) # :-( welcome = '' while channel.recv_ready(): welcome += channel.recv(1) lines = welcome.split('\r\n') prompt = lines[-1] username, remaining = prompt.split('@') self.assertEquals(username, 'testuser') hostname, remaining = remaining.split(':') self.assertEquals(hostname, 'test02') self.assertTrue(prompt.endswith('$ ')) honeypot.stop()
def test_uname_version_param(self): """ Tests if 'uname --version' works """ honeypot = Hornet(self.working_dir) honeypot.start() self.create_filesystem(honeypot) while honeypot.server.server_port == 0: # wait until the server is ready gevent.sleep(0) port = honeypot.server.server_port client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # If we log in properly, this should raise no errors client.connect('127.0.0.1', port=port, username='******', password='******') channel = client.invoke_shell() while not channel.recv_ready(): gevent.sleep(0) # :-( welcome = '' while channel.recv_ready(): welcome += channel.recv(1) lines = welcome.split('\r\n') prompt = lines[-1] self.assertTrue(prompt.endswith('$ ')) # Now send the uname command uname_command = 'uname --version' channel.send(uname_command + '\r\n') while not channel.recv_ready(): gevent.sleep(0) # :-( output = '' while not output.endswith('$ '): output += channel.recv(1) lines = output.split('\r\n') command = lines[0] command_output = '\r\n'.join(lines[1:-1]) next_prompt = lines[-1] expected_output = [] version_file_path = os.path.join(os.path.dirname(hornet.__file__), 'data', 'commands', 'uname', 'version') with open(version_file_path) as version_file: for line in version_file: line = line.strip() expected_output.append(line) self.assertEquals(command, uname_command) self.assertEquals(command_output, '\r\n'.join(expected_output)) self.assertTrue(next_prompt.endswith('$ ')) honeypot.stop()
def test_logout(self): """ Tests logout command eg: $ logout """ honeypot = Hornet(self.working_dir) honeypot.start() while honeypot.server.server_port == 0: # wait until the server is ready gevent.sleep(0) port = honeypot.server.server_port client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # If we log in properly, this should raise no errors client.connect('127.0.0.1', port=port, username='******', password='******') channel = client.invoke_shell() while not channel.recv_ready(): gevent.sleep(0) # :-( welcome = '' while channel.recv_ready(): welcome += channel.recv(1) lines = welcome.split('\r\n') prompt = lines[-1] self.assertTrue(prompt.endswith('$ ')) # Now send the ssh command channel.send('ssh test01\r\n') while not channel.recv_ready(): gevent.sleep(0) # :-( output = '' while not output.endswith('Password:'******'passtest\r\n') output = '' while not output.endswith('$ '): output += channel.recv(1) self.assertTrue('Welcome to test01 server' in output) self.assertTrue(output.endswith('$ ')) # Now send the logout command channel.send('logout\r\n') while not channel.recv_ready(): gevent.sleep(0) # :-( output = '' while not output.endswith('$ '): output += channel.recv(1) self.assertTrue('testuser@test02' in output) self.assertTrue(output.endswith('$ ')) honeypot.stop()
def test_uname_with_params(self): """ Tests if 'uname -a' command works """ honeypot = Hornet(self.working_dir) honeypot.start() self.create_filesystem(honeypot) while honeypot.server.server_port == 0: # wait until the server is ready gevent.sleep(0) port = honeypot.server.server_port client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # If we log in properly, this should raise no errors client.connect('127.0.0.1', port=port, username='******', password='******') channel = client.invoke_shell() while not channel.recv_ready(): gevent.sleep(0) # :-( welcome = '' while channel.recv_ready(): welcome += channel.recv(1) lines = welcome.split('\r\n') prompt = lines[-1] self.assertTrue(prompt.endswith('$ ')) # Now send the cd command uname_command = 'uname -a' channel.send(uname_command + '\r\n') while not channel.recv_ready(): gevent.sleep(0) # :-( output = '' while not output.endswith('$ '): output += channel.recv(1) lines = output.split('\r\n') command = lines[0] command_output = '\r\n'.join(lines[1:-1]) next_prompt = lines[-1] expected_info = [ 'Linux', honeypot.config.default_hostname, '3.13.0-37-generic', '#64-Ubuntu SMP Mon Sep 22 21:30:01 UTC 2014', 'i686', 'i686', 'i686', 'GNU/Linux' ] self.assertEquals(command, uname_command) self.assertEquals(command_output, ' '.join(expected_info)) self.assertTrue(next_prompt.endswith('$ ')) honeypot.stop()
def test_ip_assignment(self): """ Tests whether IP addresses are assigned to each host. """ def check_ipv4(value): parts = value.split('.') if len(parts) == 4 and all(x.isdigit() for x in parts): numbers = list(int(x) for x in parts) return all(0 <= num < 256 for num in numbers) return False honeypot = Hornet(self.working_dir) for hostname, host in honeypot.vhosts.iteritems(): self.assertTrue(check_ipv4(host.ip_address))
def test_cd_invalid_args(self): """ Tests if cd command works with invalid arguments """ honeypot = Hornet(self.working_dir) honeypot.start() self.create_filesystem(honeypot) while honeypot.server.server_port == 0: # wait until the server is ready gevent.sleep(0) port = honeypot.server.server_port client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # If we log in properly, this should raise no errors client.connect('127.0.0.1', port=port, username='******', password='******') channel = client.invoke_shell() while not channel.recv_ready(): gevent.sleep(0) # :-( welcome = '' while channel.recv_ready(): welcome += channel.recv(1) lines = welcome.split('\r\n') prompt = lines[-1] self.assertTrue(prompt.endswith('$ ')) # Now send the cd command cd_command = 'cd /etc/invalidlocation' channel.send(cd_command + '\r\n') while not channel.recv_ready(): gevent.sleep(0) # :-( output = '' while not output.endswith('$ '): output += channel.recv(1) lines = output.split('\r\n') command = lines[0] command_output = '\r\n'.join(lines[1:-1]) next_prompt = lines[-1] self.assertEquals(command, cd_command) self.assertEquals( command_output, 'cd: /etc/invalidlocation: No such file or directory') self.assertTrue(next_prompt.endswith('$ ')) honeypot.stop()
def test_echo_star(self): """ Tests if echo command works when '*' exists in the params """ honeypot = Hornet(self.working_dir) honeypot.start() default_host = honeypot.vhosts[honeypot.config.default_hostname] default_host.filesystem.makedir('/etc') default_host.filesystem.makedir('/var') default_host.filesystem.makedir('/opt') while honeypot.server.server_port == 0: # wait until the server is ready gevent.sleep(0) port = honeypot.server.server_port client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # If we log in properly, this should raise no errors client.connect('127.0.0.1', port=port, username='******', password='******') channel = client.invoke_shell() while not channel.recv_ready(): gevent.sleep(0) # :-( welcome = '' while channel.recv_ready(): welcome += channel.recv(1) lines = welcome.split('\r\n') prompt = lines[-1] self.assertTrue(prompt.endswith('$ ')) # Now send the echo command channel.send('echo *\r\n') while not channel.recv_ready(): gevent.sleep(0) # :-( output = '' while not output.endswith('$ '): output += channel.recv(1) lines = output.split('\r\n') command = lines[0] command_output = '\r\n'.join(lines[1:-1]) next_prompt = lines[-1] self.assertEquals('echo *', command) self.assertTrue('var' in command_output) self.assertTrue('etc' in command_output) self.assertTrue('opt' in command_output) self.assertTrue(next_prompt.endswith('$ ')) honeypot.stop()
def test_echo_env_var(self): """ Tests if echo command works when environment variables as specified in the config are specified """ honeypot = Hornet(self.working_dir) honeypot.start() while honeypot.server.server_port == 0: # wait until the server is ready gevent.sleep(0) port = honeypot.server.server_port client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # If we log in properly, this should raise no errors client.connect('127.0.0.1', port=port, username='******', password='******') channel = client.invoke_shell() while not channel.recv_ready(): gevent.sleep(0) # :-( welcome = '' while channel.recv_ready(): welcome += channel.recv(1) lines = welcome.split('\r\n') prompt = lines[-1] self.assertTrue(prompt.endswith('$ ')) # Now send the echo command channel.send('echo $BROWSER\r\n') while not channel.recv_ready(): gevent.sleep(0) # :-( output = '' while not output.endswith('$ '): output += channel.recv(1) lines = output.split('\r\n') command = lines[0] command_output = '\r\n'.join(lines[1:-1]) next_prompt = lines[-1] self.assertEquals('echo $BROWSER', command) self.assertEquals('firefox', command_output) self.assertTrue(next_prompt.endswith('$ ')) honeypot.stop()
def test_ssh_bad_hostname(self): """ Tests if ssh command returns correct string if host doesn't exist eg: $ ssh test01 -l mango """ honeypot = Hornet(self.working_dir) honeypot.start() while honeypot.server.server_port == 0: # wait until the server is ready gevent.sleep(0) port = honeypot.server.server_port client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # If we log in properly, this should raise no errors client.connect('127.0.0.1', port=port, username='******', password='******') channel = client.invoke_shell() while not channel.recv_ready(): gevent.sleep(0) # :-( welcome = '' while channel.recv_ready(): welcome += channel.recv(1) lines = welcome.split('\r\n') prompt = lines[-1] self.assertTrue(prompt.endswith('$ ')) # Now send the ssh command channel.send('ssh blahblah\r\n') while not channel.recv_ready(): gevent.sleep(0) # :-( output = '' while not output.endswith('$ '): output += channel.recv(1) self.assertTrue('Name or service not known' in output) self.assertTrue(output.endswith('$ ')) honeypot.stop()
def test_ping_ctrl_c_ip_addr(self): """ Tests basic 'ping 192.168.0.232' Makes sure the last param is picked up as the host to ping. """ honeypot = Hornet(self.working_dir) honeypot.start() while honeypot.server.server_port == 0: # wait until the server is ready gevent.sleep(0) port = honeypot.server.server_port client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # If we log in properly, this should raise no errors client.connect('127.0.0.1', port=port, username='******', password='******') channel = client.invoke_shell() while not channel.recv_ready(): gevent.sleep(0) # :-( welcome = '' while channel.recv_ready(): welcome += channel.recv(1) lines = welcome.split('\r\n') prompt = lines[-1] self.assertTrue(prompt.endswith('$ ')) # Now send the ping command ping_command = 'ping 192.168.0.232' channel.send(ping_command + '\r\n') while not channel.recv_ready(): gevent.sleep(0) # :-( lines = [] for i in range(2): line = '' while not line.endswith('\r\n'): line += channel.recv(1) line = line.strip('\r\n') if line.startswith('64 bytes from'): self.assertTrue('test02 (192.168.0.232)' in line) lines.append(line) channel.send(chr(3)) output = '' while not output.endswith('$ '): data = channel.recv(1) output += data lines = output.split('\r\n') lines = [l for l in lines if not l.startswith('64 bytes from') ] # Skip the ping response lines self.assertEquals('^C', lines[0]) self.assertEquals('--- 192.168.0.232 ping statistics ---', lines[1]) self.assertTrue('packets transmitted, ' in lines[2]) self.assertTrue('received, ' in lines[2]) self.assertTrue('% packet loss, time' in lines[2]) self.assertTrue(lines[2].endswith('ms')) self.assertTrue(lines[3].startswith('rtt min/avg/max/mdev = ')) self.assertTrue(lines[3].endswith('ms')) next_prompt = lines[-1] self.assertTrue(next_prompt.endswith('$ ')) honeypot.stop()
def test_ping_ctrl_c_ip_addr(self): """ Tests basic 'ping 192.168.0.232' Makes sure the last param is picked up as the host to ping. """ honeypot = Hornet(self.working_dir) honeypot.start() while honeypot.server.server_port == 0: # wait until the server is ready gevent.sleep(0) port = honeypot.server.server_port client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # If we log in properly, this should raise no errors client.connect('127.0.0.1', port=port, username='******', password='******') channel = client.invoke_shell() while not channel.recv_ready(): gevent.sleep(0) # :-( welcome = '' while channel.recv_ready(): welcome += channel.recv(1) lines = welcome.split('\r\n') prompt = lines[-1] self.assertTrue(prompt.endswith('$ ')) # Now send the ping command ping_command = 'ping 192.168.0.232' channel.send(ping_command + '\r\n') while not channel.recv_ready(): gevent.sleep(0) # :-( lines = [] for i in range(2): line = '' while not line.endswith('\r\n'): line += channel.recv(1) line = line.strip('\r\n') if line.startswith('64 bytes from'): self.assertTrue('test02 (192.168.0.232)' in line) lines.append(line) channel.send(chr(3)) output = '' while not output.endswith('$ '): data = channel.recv(1) output += data lines = output.split('\r\n') lines = [l for l in lines if not l.startswith('64 bytes from')] # Skip the ping response lines self.assertEquals('^C', lines[0]) self.assertEquals('--- 192.168.0.232 ping statistics ---', lines[1]) self.assertTrue('packets transmitted, ' in lines[2]) self.assertTrue('received, ' in lines[2]) self.assertTrue('% packet loss, time' in lines[2]) self.assertTrue(lines[2].endswith('ms')) self.assertTrue(lines[3].startswith('rtt min/avg/max/mdev = ')) self.assertTrue(lines[3].endswith('ms')) next_prompt = lines[-1] self.assertTrue(next_prompt.endswith('$ ')) honeypot.stop()
def test_wget_download_url(self): """ Tests if 'wget http://httpbin.org/drip?numbytes=28&duration=3&code=200' downloads the file properly """ honeypot = Hornet(self.working_dir) honeypot.start() while honeypot.server.server_port == 0: # wait until the server is ready gevent.sleep(0) port = honeypot.server.server_port client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # If we log in properly, this should raise no errors client.connect('127.0.0.1', port=port, username='******', password='******') channel = client.invoke_shell() while not channel.recv_ready(): gevent.sleep(0) # :-( welcome = '' while channel.recv_ready(): welcome += channel.recv(1) lines = welcome.split('\r\n') prompt = lines[-1] self.assertTrue(prompt.endswith('$ ')) # Now send the wget command wget_command = 'wget http://httpbin.org/drip?numbytes=2048&duration=3&code=200 -O drip' channel.send(wget_command + '\r\n') while not channel.recv_ready(): gevent.sleep(0) # :-( output = '' while not output.endswith('$ '): output += channel.recv(1) lines = output.split('\r\n') command = lines[0] command_output = lines[1:-1] next_prompt = lines[-1] self.assertEquals(command, wget_command) self.assertTrue(lines[1].startswith('--')) default_host = honeypot.vhosts[honeypot.config.default_hostname] file_ = default_host.filesystem.getsyspath('drip') with open(file_, 'r') as downloaded_file: data = downloaded_file.read() self.assertEquals(len(data), 2048) self.assertTrue(command_output[0].startswith('--')) self.assertTrue(command_output[0].endswith( 'http://httpbin.org/drip?numbytes=2048&duration=3&code=200' )) self.assertTrue(command_output[1].startswith('Resolving httpbin.org (httpbin.org)...')) self.assertTrue(command_output[2].startswith('Connecting to httpbin.org (httpbin.org)')) self.assertTrue(command_output[2].endswith('|:80... connected.')) self.assertEquals(command_output[3], 'HTTP request sent, awaiting response... 200 OK') self.assertEquals(command_output[4], 'Length: 2048 (2.0K) [application/octet-stream]') self.assertEquals(command_output[5], 'Saving to:\'drip\'') self.assertTrue(command_output[-1].endswith('\'drip\' saved [2048/2048]')) self.assertTrue(next_prompt.endswith('$ ')) honeypot.stop()
def test_cd_with_backref(self): """ Tests if cd command works with backref (cd ../..) """ honeypot = Hornet(self.working_dir) honeypot.start() self.create_filesystem(honeypot) while honeypot.server.server_port == 0: # wait until the server is ready gevent.sleep(0) port = honeypot.server.server_port client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # If we log in properly, this should raise no errors client.connect('127.0.0.1', port=port, username='******', password='******') channel = client.invoke_shell() while not channel.recv_ready(): gevent.sleep(0) # :-( welcome = '' while channel.recv_ready(): welcome += channel.recv(1) lines = welcome.split('\r\n') prompt = lines[-1] self.assertTrue(prompt.endswith('$ ')) # Now send the cd command cd_command = 'cd /etc/init.d' channel.send(cd_command + '\r\n') while not channel.recv_ready(): gevent.sleep(0) # :-( output = '' while not output.endswith('$ '): output += channel.recv(1) lines = output.split('\r\n') command = lines[0] command_output = '\r\n'.join(lines[1:-1]) next_prompt = lines[-1] self.assertEquals(command, cd_command) self.assertEquals(command_output, '') # cd should normally give no output self.assertTrue(next_prompt.endswith('$ ')) self.assertTrue('/etc/init.d' in next_prompt) # Now send the cd command cd_command = 'cd ../..' channel.send(cd_command + '\r\n') while not channel.recv_ready(): gevent.sleep(0) # :-( output = '' while not output.endswith('$ '): output += channel.recv(1) lines = output.split('\r\n') command = lines[0] command_output = '\r\n'.join(lines[1:-1]) next_prompt = lines[-1] self.assertEquals(command, cd_command) self.assertEquals(command_output, '') # cd should normally give no output self.assertTrue(next_prompt.endswith(':/$ ')) honeypot.stop()
def test_pwd(self): """ Tests if pwd command works """ honeypot = Hornet(self.working_dir) honeypot.start() while honeypot.server.server_port == 0: # wait until the server is ready gevent.sleep(0) port = honeypot.server.server_port client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # If we log in properly, this should raise no errors client.connect('127.0.0.1', port=port, username='******', password='******') channel = client.invoke_shell() while not channel.recv_ready(): gevent.sleep(0) # :-( welcome = '' while channel.recv_ready(): welcome += channel.recv(1) lines = welcome.split('\r\n') prompt = lines[-1] self.assertTrue(prompt.endswith('$ ')) # Now send the pwd command pwd_command = 'pwd /something/ any kind of param 123' channel.send(pwd_command + '\r\n') while not channel.recv_ready(): gevent.sleep(0) # :-( output = '' while not output.endswith('$ '): output += channel.recv(1) lines = output.split('\r\n') command = lines[0] command_output = '\r\n'.join(lines[1:-1]) next_prompt = lines[-1] self.assertEquals(command, pwd_command) self.assertEquals(command_output, 'pwd: too many arguments') self.assertTrue(next_prompt.endswith('$ ')) pwd_command = 'pwd' channel.send(pwd_command + '\r\n') while not channel.recv_ready(): gevent.sleep(0) # :-( output = '' while not output.endswith('$ '): output += channel.recv(1) lines = output.split('\r\n') command = lines[0] command_output = '\r\n'.join(lines[1:-1]) next_prompt = lines[-1] self.assertEquals(command, pwd_command) self.assertEquals(command_output, '/') self.assertTrue(next_prompt.endswith('$ ')) honeypot.stop()
def test_ls_long_after_cd(self): """ Test basic 'cd var; ls -al ../etc' """ honeypot = Hornet(self.working_dir) honeypot.start() self.create_filesystem(honeypot) while honeypot.server.server_port == 0: # wait until the server is ready gevent.sleep(0) port = honeypot.server.server_port client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # If we log in properly, this should raise no errors client.connect('127.0.0.1', port=port, username='******', password='******') channel = client.invoke_shell() while not channel.recv_ready(): gevent.sleep(0) # :-( welcome = '' while channel.recv_ready(): welcome += channel.recv(1) lines = welcome.split('\r\n') prompt = lines[-1] self.assertTrue(prompt.endswith('$ ')) cd_command = 'cd var' channel.send(cd_command + '\r\n') while not channel.recv_ready(): gevent.sleep(0) # :-( output = '' while not output.endswith('$ '): output += channel.recv(1) lines = output.split('\r\n') command = lines[0] next_prompt = lines[-1] self.assertEquals(command, cd_command) self.assertTrue(next_prompt.endswith('$ ')) # Now send the ls command ls_command = 'ls -la ../etc' channel.send(ls_command + '\r\n') while not channel.recv_ready(): gevent.sleep(0) # :-( output = '' while not output.endswith('$ '): output += channel.recv(1) lines = output.split('\r\n') command = lines[0] command_output = '\r\n'.join(lines[1:-1]) next_prompt = lines[-1] actual_list = command_output.split('\r\n')[1:] # Ignore the first "total" entry expected_list = ['init.d', 'passwd', 'sysctl.conf', '..', '.'] self.assertEquals(command, ls_command) self.verify_long_list(actual_list, expected_list) self.assertTrue(next_prompt.endswith('$ ')) honeypot.stop()