Esempio n. 1
0
class HttpTests(unittest.TestCase):
    def setUp(self):
        self.reportingRelay = ReportingRelay()
        self.reportingRelay.start()

    def tearDown(self):
        self.reportingRelay.stop()

    def test_connection(self):
        """ Tests if the capability is up, and sending
            HTTP 401 (Unauthorized) headers.
        """

        # Use uncommon port so that you can run the test even if the Honeypot
        # is running.
        options = {'enabled': 'True', 'port': 0, 'users': {'test': 'test'}}
        cap = http.Http(options)
        srv = StreamServer(('0.0.0.0', 0), cap.handle_session)
        srv.start()

        client = httplib.HTTPConnection('127.0.0.1', srv.server_port)
        client.request('GET', '/')
        response = client.getresponse()
        self.assertEqual(response.status, 401)
        srv.stop()
Esempio n. 2
0
class HttpTests(unittest.TestCase):
    def setUp(self):
        self.reportingRelay = ReportingRelay()
        self.reportingRelay.start()

    def tearDown(self):
        self.reportingRelay.stop()

    def test_connection(self):
        """ Tests if the capability is up, and sending
            HTTP 401 (Unauthorized) headers.
        """

        # Use uncommon port so that you can run the test even if the Honeypot
        # is running.
        options = {'enabled': 'True', 'port': 0, 'users': {'test': 'test'}}
        cap = http.Http(options)
        srv = StreamServer(('0.0.0.0', 0), cap.handle_session)
        srv.start()

        client = httplib.HTTPConnection('127.0.0.1', srv.server_port)
        client.request('GET', '/')
        response = client.getresponse()
        self.assertEqual(response.status, 401)
        srv.stop()
Esempio n. 3
0
class FtpTests(unittest.TestCase):
    def setUp(self):
        self.reportingRelay = ReportingRelay()
        self.reportingRelay.start()

    def tearDown(self):
        self.reportingRelay.stop()

    def test_login(self):
        """Testing different login combinations"""

        options = {'enabled': 'True', 'port': 0, 'banner': 'Test Banner', 'users': {'test': 'test'},
                   'protocol_specific_data': {'max_attempts': 3, 'banner': 'test banner', 'syst_type': 'Test Type'}}

        ftp_capability = ftp.ftp(options)
        srv = StreamServer(('0.0.0.0', 0), ftp_capability.handle_session)
        srv.start()

        ftp_client = FTP()
        ftp_client.connect('127.0.0.1', srv.server_port, 1)

        # expect perm exception
        try:
            ftp_client.login('james', 'bond')
            response = ftp_client.getresp()  # NOQA
        except ftplib.error_perm:
            pass
        srv.stop()
Esempio n. 4
0
class FtpTests(unittest.TestCase):
    def setUp(self):
        self.reportingRelay = ReportingRelay()
        self.reportingRelay.start()

    def tearDown(self):
        self.reportingRelay.stop()

    def test_login(self):
        """Testing different login combinations"""

        options = {'enabled': 'True', 'port': 0, 'banner': 'Test Banner', 'users': {'test': 'test'},
                   'protocol_specific_data': {'max_attempts': 3, 'banner': 'test banner', 'syst_type': 'Test Type'}}

        ftp_capability = ftp.ftp(options)
        srv = StreamServer(('0.0.0.0', 0), ftp_capability.handle_session)
        srv.start()

        ftp_client = FTP()
        ftp_client.connect('127.0.0.1', srv.server_port, 1)

        # expect perm exception
        try:
            ftp_client.login('james', 'bond')
            response = ftp_client.getresp()
        except ftplib.error_perm:
            pass
        srv.stop()
Esempio n. 5
0
class TelnetTests(unittest.TestCase):
    def setUp(self):
        self.reportingRelay = ReportingRelay()
        self.reportingRelay.start()

    def tearDown(self):
        self.reportingRelay.stop()

    def test_invalid_login(self):
        """Tests if telnet server responds correctly to a invalid login attempt."""

        # initialize capability and start tcp server
        options = {
            'enabled': 'True',
            'port': 2503,
            'protocol_specific_data': {
                'max_attempts': 3
            },
            'users': {
                'test': 'test'
            }
        }

        cap = telnet.Telnet(options)
        server = StreamServer(('0.0.0.0', 2503), cap.handle_session)
        server.start()

        client = telnetlib.Telnet('localhost', 2503)
        # set this to 1 if having problems with this test
        client.set_debuglevel(0)

        # this disables all command negotiation.
        client.set_option_negotiation_callback(self.cb)

        # Expect username as first output
        reply = client.read_until('Username: '******'Username: '******'someuser' + '\r\n')
        reply = client.read_until('Password: '******'Password: '******'somepass' + '\r\n')
        reply = client.read_until('Invalid username/password', 5)
        self.assertTrue('Invalid username/password' in reply)
        server.stop()

    def cb(self, socket, command, option):
        return
Esempio n. 6
0
class SshTests(unittest.TestCase):
    def setUp(self):
        self.reportingRelay = ReportingRelay()
        self.reportingRelay.start()

    def tearDown(self):
        self.reportingRelay.stop()

    def test_basic_login(self):
        options = {'port': 0}
        sut = SSH(options)
        server = StreamServer(('127.0.0.1', 0), sut.handle_session)
        server.start()

        client = SSHClient()
        client.set_missing_host_key_policy(AutoAddPolicy())
        with self.assertRaises(AuthenticationException):
            client.connect('127.0.0.1', server.server_port, 'someuser', 'somepassword')

        server.stop()
Esempio n. 7
0
class TelnetTests(unittest.TestCase):
    def setUp(self):
        self.reportingRelay = ReportingRelay()
        self.reportingRelay.start()

    def tearDown(self):
        self.reportingRelay.stop()

    def test_invalid_login(self):
        """Tests if telnet server responds correctly to a invalid login attempt."""

        # initialize capability and start tcp server
        options = {'enabled': 'True', 'port': 2503, 'protocol_specific_data': {'max_attempts': 3},
                   'users': {'test': 'test'}}

        cap = telnet.Telnet(options)
        server = StreamServer(('0.0.0.0', 2503), cap.handle_session)
        server.start()

        client = telnetlib.Telnet('localhost', 2503)
        # set this to 1 if having problems with this test
        client.set_debuglevel(0)

        # this disables all command negotiation.
        client.set_option_negotiation_callback(self.cb)

        # Expect username as first output
        reply = client.read_until('Username: '******'Username: '******'someuser' + '\r\n')
        reply = client.read_until('Password: '******'Password: '******'somepass' + '\r\n')
        reply = client.read_until('Invalid username/password', 5)
        self.assertTrue('Invalid username/password' in reply)
        server.stop()

    def cb(self, socket, command, option):
        return
Esempio n. 8
0
class SshTests(unittest.TestCase):
    def setUp(self):
        self.reportingRelay = ReportingRelay()
        self.reportingRelay.start()

    def tearDown(self):
        self.reportingRelay.stop()

    def test_basic_login(self):
        options = {'port': 0}
        sut = SSH(options)
        server = StreamServer(('127.0.0.1', 0), sut.handle_session)
        server.start()

        client = SSHClient()
        client.set_missing_host_key_policy(AutoAddPolicy())
        with self.assertRaises(AuthenticationException):
            client.connect('127.0.0.1', server.server_port, 'someuser',
                           'somepassword')

        server.stop()
Esempio n. 9
0
class Pop3Tests(unittest.TestCase):
    def setUp(self):
        self.reportingRelay = ReportingRelay()
        self.reportingRelay.start()

    def tearDown(self):
        self.reportingRelay.stop()

    def test_initial_session(self):
        """Tests if the basic parts of the session is filled correctly"""

        options = {'port': 110, 'protocol_specific_data': {'max_attempts': 3}}
        sut = Pop3(options)

        # dont really care about the socket at this point (None...)
        # TODO: mock the socket!
        try:
            sut.handle_session(None, ['192.168.1.200', 12000])
        except AttributeError:
            # because socket is not set
            pass

            # TODO: Bind to SERVER_RELAY and assert that we get messages as expected
            # self.assertEqual(0, len(sut.sessions))
            # session = sut.sessions.values()[0]
            # self.assertEqual('pop3', session.protocol)
            # self.assertEquals('192.168.1.200', session.source_ip)
            # self.assertEqual(12000, session.source_port)

    def test_login(self):
        """Testing different login combinations"""

        login_sequences = [
            # invalid login, invalid password
            (('USER wakkwakk', '+OK User accepted'), ('PASS wakkwakk', '-ERR Authentication failed.')),
            # PASS without user
            (('PASS bond', '-ERR No username given.'),),
            # Try to run a TRANSACITON state command in AUTHORIZATION state
            (('RETR', '-ERR Unknown command'),),
        ]

        options = {'port': 110, 'protocol_specific_data': {'max_attempts': 3}, 'users': {'james': 'bond'}}
        sut = Pop3(options)

        server = StreamServer(('127.0.0.1', 0), sut.handle_session)
        server.start()

        for sequence in login_sequences:
            client = gevent.socket.create_connection(('127.0.0.1', server.server_port))

            fileobj = client.makefile()

            # skip banner
            fileobj.readline()

            for pair in sequence:
                client.sendall(pair[0] + "\r\n")
                response = fileobj.readline().rstrip()
                self.assertEqual(response, pair[1])

        server.stop()
Esempio n. 10
0
class ZmqTests(unittest.TestCase):
    def setUp(self):
        self.test_running = True
        self.zmq_server_listning_event = gevent.event.Event()
        self.testing_queue = gevent.queue.Queue()
        self.reportingRelay = ReportingRelay()
        self.reportingRelay.start()

    def tearDown(self):
        self.test_running = False
        self.reportingRelay.stop()

    def test_connect(self):
        """Tests that we can connect and send data to a zmq puller"""

        # start dummy ZMQ pull server
        gevent.spawn(self._start_zmq_puller)
        self.zmq_server_listning_event.wait(5)

        # our local zmq logger
        zmq_url = 'tcp://localhost:{0}'.format(self.zmq_tcp_port)
        client_public_key = "N[DC7+%FKdW3pJUPnaCwWxt-0/jo5Lrq&U28-GG}"
        client_secret_key = "Gwt%C0a8J/:9Jy$qpDNTy8wRzlnRD-HT8H>u7F{B"
        server_public_key = "^4b:-bZ8seRC+m2p(sg{7{skOuK*jInNeH^/Le}Q"
        zmqLogger = ZmqLogger(zmq_url, client_public_key, client_secret_key, server_public_key)
        zmqLogger.start()

        # inject some data into the logging relay singleton
        self.reportingRelay.queueLogData({'somekey': 'somedata'})

        # wait until the zmq server put something into the local testing queue
        received_data = self.testing_queue.get(5)
        received_data = received_data.split(' ', 1)
        topic, message = received_data[0], jsonapi.loads(received_data[1])

        self.assertEqual(topic, ZmqMessageTypes.HERALDING_AUTH_LOG.value)
        self.assertIn('somekey', message)
        self.assertEqual(message['somekey'], 'somedata')

    def _start_zmq_puller(self):
        context = zmq.Context()

        # Authenticator runs in different greenlet.
        auth = GreenThreadAuthenticator(context)
        auth.start()
        auth.allow('127.0.0.1')
        auth.configure_curve(domain='*', location='heralding/tests/zmq_public_keys')

        # Bind our mock zmq pull server
        socket = context.socket(zmq.PULL)
        socket.curve_secretkey = "}vxNPm8lOJT1yvqu7-A<m<w>7OZ1ok<d?Qbq+a?5"
        socket.curve_server = True
        self.zmq_tcp_port = socket.bind_to_random_port('tcp://*', min_port=40000, max_port=50000, max_tries=10)

        # Poll and wait for data from test client
        poller = zmq.Poller()
        poller.register(socket, zmq.POLLIN)

        # Need to notify test client that the server is ready
        self.zmq_server_listning_event.set()

        while self.test_running:
            socks = dict(poller.poll())
            if socket in socks and socks[socket] == zmq.POLLIN:
                data = socket.recv()
                self.testing_queue.put(data)
        socket.close()
Esempio n. 11
0
class Pop3Tests(unittest.TestCase):
    def setUp(self):
        self.reportingRelay = ReportingRelay()
        self.reportingRelay.start()

    def tearDown(self):
        self.reportingRelay.stop()

    def test_initial_session(self):
        """Tests if the basic parts of the session is filled correctly"""

        options = {'port': 110, 'protocol_specific_data': {'max_attempts': 3}}
        sut = Pop3(options)

        # dont really care about the socket at this point (None...)
        # TODO: mock the socket!
        try:
            sut.handle_session(None, ['192.168.1.200', 12000])
        except AttributeError:
            # because socket is not set
            pass

            # TODO: Bind to SERVER_RELAY and assert that we get messages as expected
            # self.assertEqual(0, len(sut.sessions))
            # session = sut.sessions.values()[0]
            # self.assertEqual('pop3', session.protocol)
            # self.assertEquals('192.168.1.200', session.source_ip)
            # self.assertEqual(12000, session.source_port)

    def test_login(self):
        """Testing different login combinations"""

        login_sequences = [
            # invalid login, invalid password
            (('USER wakkwakk', '+OK User accepted'),
             ('PASS wakkwakk', '-ERR Authentication failed.')),
            # PASS without user
            (
                ('PASS bond', '-ERR No username given.'), ),
            # Try to run a TRANSACITON state command in AUTHORIZATION state
            (
                ('RETR', '-ERR Unknown command'), ),
        ]

        options = {
            'port': 110,
            'protocol_specific_data': {
                'max_attempts': 3
            },
            'users': {
                'james': 'bond'
            }
        }
        sut = Pop3(options)

        server = StreamServer(('127.0.0.1', 0), sut.handle_session)
        server.start()

        for sequence in login_sequences:
            client = gevent.socket.create_connection(
                ('127.0.0.1', server.server_port))

            fileobj = client.makefile()

            # skip banner
            fileobj.readline()

            for pair in sequence:
                client.sendall(pair[0] + "\r\n")
                response = fileobj.readline().rstrip()
                self.assertEqual(response, pair[1])

        server.stop()
Esempio n. 12
0
class SmtpTests(unittest.TestCase):
    def setUp(self):
        self.reportingRelay = ReportingRelay()
        self.reportingRelay.start()

    def tearDown(self):
        self.reportingRelay.stop()

    def test_connection(self):
        """ Tries to connect and run a EHLO command. Very basic test.
        """

        # Use uncommon port so that we can run test even if the Honeypot is running.
        options = {
            'enabled': 'True',
            'port': 0,
            'protocol_specific_data': {
                'banner': 'test'
            },
            'users': {
                'test': 'test'
            },
        }
        cap = smtp.smtp(options)
        srv = StreamServer(('0.0.0.0', 0), cap.handle_session)
        srv.start()

        smtp_ = smtplib.SMTP('127.0.0.1',
                             srv.server_port,
                             local_hostname='localhost',
                             timeout=15)
        smtp_.ehlo()
        smtp_.quit()
        srv.stop()

    def test_AUTH_CRAM_MD5_reject(self):
        """ Makes sure the server rejects all invalid login attempts that use the
            CRAM-MD5 Authentication method.
        """

        options = {
            'enabled': 'True',
            'port': 0,
            'protocol_specific_data': {
                'banner': 'Test'
            },
            'users': {
                'someguy': 'test'
            }
        }
        cap = smtp.smtp(options)
        srv = StreamServer(('0.0.0.0', 0), cap.handle_session)
        srv.start()

        def encode_cram_md5(challenge, user, password):
            challenge = base64.decodestring(challenge)
            response = user + ' ' + hmac.HMAC(password, challenge).hexdigest()
            return base64.b64encode(response)

        smtp_ = smtplib.SMTP('127.0.0.1',
                             srv.server_port,
                             local_hostname='localhost',
                             timeout=15)
        _, resp = smtp_.docmd('AUTH', 'CRAM-MD5')
        code, resp = smtp_.docmd(encode_cram_md5(resp, 'test', 'test'))
        # For now, the server's going to return a 535 code.
        self.assertEqual(code, 535)
        srv.stop()

    def test_AUTH_PLAIN_reject(self):
        """ Makes sure the server rejects all invalid login attempts that use the PLAIN Authentication method.
        """
        options = {
            'enabled': 'True',
            'port': 0,
            'protocol_specific_data': {
                'banner': 'Test'
            },
            'users': {
                'someguy': 'test'
            }
        }

        cap = smtp.smtp(options)
        srv = StreamServer(('0.0.0.0', 0), cap.handle_session)
        srv.start()

        smtp_ = smtplib.SMTP('127.0.0.1',
                             srv.server_port,
                             local_hostname='localhost',
                             timeout=15)
        arg = '\0%s\0%s' % ('test', 'test')
        code, resp = smtp_.docmd('AUTH', 'PLAIN ' + base64.b64encode(arg))
        self.assertEqual(code, 535)
        srv.stop()

    def test_AUTH_LOGIN_reject(self):
        """ Makes sure the server rejects all invalid login attempts that use the LOGIN Authentication method.
        """

        options = {
            'enabled': 'True',
            'port': 0,
            'protocol_specific_data': {
                'banner': 'Test'
            },
            'users': {
                'someguy': 'test'
            }
        }

        cap = smtp.smtp(options)
        srv = StreamServer(('0.0.0.0', 0), cap.handle_session)
        srv.start()

        smtp_ = smtplib.SMTP('127.0.0.1',
                             srv.server_port,
                             local_hostname='localhost',
                             timeout=15)
        smtp_.docmd('AUTH', 'LOGIN')
        smtp_.docmd(base64.b64encode('test'))
        code, resp = smtp_.docmd(base64.b64encode('test'))
        self.assertEqual(code, 535)
        srv.stop()
Esempio n. 13
0
class SmtpTests(unittest.TestCase):
    def setUp(self):
        self.reportingRelay = ReportingRelay()
        self.reportingRelay.start()

    def tearDown(self):
        self.reportingRelay.stop()

    def test_connection(self):
        """ Tries to connect and run a EHLO command. Very basic test.
        """

        # Use uncommon port so that we can run test even if the Honeypot is running.
        options = {'enabled': 'True', 'port': 0, 'protocol_specific_data': {'banner': 'test'},
                   'users': {'test': 'test'},}
        cap = smtp.smtp(options)
        srv = StreamServer(('0.0.0.0', 0), cap.handle_session)
        srv.start()

        smtp_ = smtplib.SMTP('127.0.0.1', srv.server_port, local_hostname='localhost', timeout=15)
        smtp_.ehlo()
        smtp_.quit()
        srv.stop()

    def test_AUTH_CRAM_MD5_reject(self):
        """ Makes sure the server rejects all invalid login attempts that use the
            CRAM-MD5 Authentication method.
        """

        options = {'enabled': 'True', 'port': 0, 'protocol_specific_data': {'banner': 'Test'},
                   'users': {'someguy': 'test'}}
        cap = smtp.smtp(options)
        srv = StreamServer(('0.0.0.0', 0), cap.handle_session)
        srv.start()

        def encode_cram_md5(challenge, user, password):
            challenge = base64.decodestring(challenge)
            response = user + ' ' + hmac.HMAC(password, challenge).hexdigest()
            return base64.b64encode(response)

        smtp_ = smtplib.SMTP('127.0.0.1', srv.server_port, local_hostname='localhost', timeout=15)
        _, resp = smtp_.docmd('AUTH', 'CRAM-MD5')
        code, resp = smtp_.docmd(encode_cram_md5(resp, 'test', 'test'))
        # For now, the server's going to return a 535 code.
        self.assertEqual(code, 535)
        srv.stop()

    def test_AUTH_PLAIN_reject(self):
        """ Makes sure the server rejects all invalid login attempts that use the PLAIN Authentication method.
        """
        options = {'enabled': 'True', 'port': 0, 'protocol_specific_data': {'banner': 'Test'},
                   'users': {'someguy': 'test'}}

        cap = smtp.smtp(options)
        srv = StreamServer(('0.0.0.0', 0), cap.handle_session)
        srv.start()

        smtp_ = smtplib.SMTP('127.0.0.1', srv.server_port, local_hostname='localhost', timeout=15)
        arg = '\0%s\0%s' % ('test', 'test')
        code, resp = smtp_.docmd('AUTH', 'PLAIN ' + base64.b64encode(arg))
        self.assertEqual(code, 535)
        srv.stop()

    def test_AUTH_LOGIN_reject(self):
        """ Makes sure the server rejects all invalid login attempts that use the LOGIN Authentication method.
        """

        options = {'enabled': 'True', 'port': 0, 'protocol_specific_data': {'banner': 'Test'},
                   'users': {'someguy': 'test'}}

        cap = smtp.smtp(options)
        srv = StreamServer(('0.0.0.0', 0), cap.handle_session)
        srv.start()

        smtp_ = smtplib.SMTP('127.0.0.1', srv.server_port, local_hostname='localhost', timeout=15)
        smtp_.docmd('AUTH', 'LOGIN')
        smtp_.docmd(base64.b64encode('test'))
        code, resp = smtp_.docmd(base64.b64encode('test'))
        self.assertEqual(code, 535)
        srv.stop()
Esempio n. 14
0
class ZmqTests(unittest.TestCase):
    def setUp(self):
        self.test_running = True
        self.zmq_server_listning_event = gevent.event.Event()
        self.testing_queue = gevent.queue.Queue()
        self.reportingRelay = ReportingRelay()
        self.reportingRelay.start()

    def tearDown(self):
        self.test_running = False
        self.reportingRelay.stop()

    def test_connect(self):
        """Tests that we can connect and send data to a zmq puller"""

        # start dummy ZMQ pull server
        gevent.spawn(self._start_zmq_puller)
        self.zmq_server_listning_event.wait(5)

        # our local zmq logger
        zmq_url = 'tcp://localhost:{0}'.format(self.zmq_tcp_port)
        client_public_key = "N[DC7+%FKdW3pJUPnaCwWxt-0/jo5Lrq&U28-GG}"
        client_secret_key = "Gwt%C0a8J/:9Jy$qpDNTy8wRzlnRD-HT8H>u7F{B"
        server_public_key = "^4b:-bZ8seRC+m2p(sg{7{skOuK*jInNeH^/Le}Q"
        zmqLogger = ZmqLogger(zmq_url, client_public_key, client_secret_key,
                              server_public_key)
        zmqLogger.start()

        # inject some data into the logging relay singleton
        self.reportingRelay.queueLogData({'somekey': 'somedata'})

        # wait until the zmq server put something into the local testing queue
        received_data = self.testing_queue.get(5)
        received_data = received_data.split(' ', 1)
        topic, message = received_data[0], jsonapi.loads(received_data[1])

        self.assertEqual(topic, ZmqMessageTypes.HERALDING_AUTH_LOG.value)
        self.assertIn('somekey', message)
        self.assertEqual(message['somekey'], 'somedata')

    def _start_zmq_puller(self):
        context = zmq.Context()

        # Authenticator runs in different greenlet.
        auth = GreenThreadAuthenticator(context)
        auth.start()
        auth.allow('127.0.0.1')
        auth.configure_curve(domain='*',
                             location='heralding/tests/zmq_public_keys')

        # Bind our mock zmq pull server
        socket = context.socket(zmq.PULL)
        socket.curve_secretkey = "}vxNPm8lOJT1yvqu7-A<m<w>7OZ1ok<d?Qbq+a?5"
        socket.curve_server = True
        self.zmq_tcp_port = socket.bind_to_random_port('tcp://*',
                                                       min_port=40000,
                                                       max_port=50000,
                                                       max_tries=10)

        # Poll and wait for data from test client
        poller = zmq.Poller()
        poller.register(socket, zmq.POLLIN)

        # Need to notify test client that the server is ready
        self.zmq_server_listning_event.set()

        while self.test_running:
            socks = dict(poller.poll())
            if socket in socks and socks[socket] == zmq.POLLIN:
                data = socket.recv()
                self.testing_queue.put(data)
        socket.close()