Exemplo n.º 1
0
    def setUp(self):
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(None)

        self.reporting_relay = ReportingRelay()
        self.reporting_relay_task = self.loop.run_in_executor(
            None, self.reporting_relay.start)
Exemplo n.º 2
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()
Exemplo n.º 3
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()
Exemplo 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()  # NOQA
        except ftplib.error_perm:
            pass
        srv.stop()
Exemplo n.º 5
0
    def add_auth_attempt(self, _type, **kwargs):
        self.login_attempts += 1
        entry = {
            'timestamp': datetime.utcnow(),
            'session_id': self.id,
            'auth_id': uuid.uuid4(),
            'source_ip': self.source_ip,
            'souce_port': self.source_port,
            'destination_ip': heralding.honeypot.Honeypot.public_ip,
            'destination_port': self.destination_port,
            'protocol': self.protocol,
            'username': None,
            'password': None
        }
        if 'username' in kwargs:
            entry['username'] = kwargs['username']
        if 'password' in kwargs:
            entry['password'] = kwargs['password']

        ReportingRelay.queueLogData(entry)
        self.activity()
        logger.debug(
            '{0} authentication attempt from {1}:{2}. Credentials: {3}'.format(
                self.protocol, self.source_ip, self.source_port,
                json.dumps(kwargs)))
Exemplo n.º 6
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()
Exemplo n.º 7
0
    def add_auth_attempt(self, _type, **kwargs):
        
        # constructs dict to transmitted right away.
        entry = {'timestamp': datetime.utcnow(),
                 'session_id': str(self.id),
                 'auth_id': str(uuid.uuid4()),
                 'source_ip': self.source_ip,
                 'source_port': self.source_port,
                 'destination_ip': self.destination_ip,
                 'destination_port': self.destination_port,
                 'protocol': self.protocol,
                 'username': None,
                 'password': None
                 }
        if 'username' in kwargs:
            entry['username'] = kwargs['username']
        if 'password' in kwargs:
            entry['password'] = kwargs['password']
        ReportingRelay.logAuthAttempt(entry)

        # add to internal dict used for reporting when the session ends
        self.auth_attempts.append({
            'timestamp': entry['timestamp'].strftime('%Y-%m-%d %H:%M:%S.%f'),
            'username': entry['username'],
            'password': entry['password'],
        })

        self.activity()
        logger.debug('%s authentication attempt from %s:%s. Auth mechanism: %s, session id %s '
                     'Credentials: %s', self.protocol, self.source_ip,
                     self.source_port, _type, self.id, json.dumps(kwargs))
Exemplo n.º 8
0
    def add_auth_attempt(self, _type, **kwargs):
        self.login_attempts += 1
        entry = {
            'timestamp': datetime.utcnow(),
            'session_id': self.id,
            'auth_id': uuid.uuid4(),
            'source_ip': self.source_ip,
            'source_port': self.source_port,
            'destination_ip': heralding.honeypot.Honeypot.public_ip,
            'destination_port': self.destination_port,
            'protocol': self.protocol,
            'username': None,
            'password': None
        }
        if 'username' in kwargs:
            entry['username'] = kwargs['username']
        if 'password' in kwargs:
            entry['password'] = kwargs['password']

        ReportingRelay.logAuthAttempt(entry)

        self.activity()
        logger.debug(
            '%s authentication attempt from %s:%s. Auth mechanism: %s, session id %s '
            'Credentials: %s', self.protocol, self.source_ip, self.source_port,
            _type, self.id, json.dumps(kwargs))
Exemplo n.º 9
0
    def end_session(self):
        if not self.session_ended:
            self.session_ended = True
            self.connected = False
            entry = self.get_session_info(True)

            ReportingRelay.logSessionInfo(entry)
            logger.debug('Session with session id %s ended', self.id)
Exemplo n.º 10
0
    def end_session(self):
        if not self.session_ended:
            self.session_ended = True
            self.connected = False
            entry = self.get_session_info(True)

            ReportingRelay.logSessionInfo(entry)
            logger.debug('Session with session id %s ended', self.id)
Exemplo n.º 11
0
class TelnetTests(unittest.TestCase):
    def setUp(self):
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(None)

        self.reporting_relay = ReportingRelay()
        self.reporting_relay_task = self.loop.run_in_executor(None, self.reporting_relay.start)

    def tearDown(self):
        self.reporting_relay.stop()
        # We give reporting_relay a chance to be finished
        self.loop.run_until_complete(self.reporting_relay_task)

        self.server.close()
        self.loop.run_until_complete(self.server.wait_closed())

        self.loop.run_until_complete(cancel_all_pending_tasks(self.loop))
        self.loop.close()

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

        def telnet_login():
            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(b'Username: '******'Username: '******'someuser' + b'\r\n')
            reply = client.read_until(b'Password: '******'Password: '******'somepass' + b'\r\n')
            reply = client.read_until(b'\n', 5)
            self.assertTrue(b'\n' in reply)

            client.close()

        options = {'enabled': 'True', 'port': 2503, 'protocol_specific_data': {'max_attempts': 3},
                   'users': {'test': 'test'}}
        telnet_cap = telnet.Telnet(options, self.loop)

        server_coro = asyncio.start_server(telnet_cap.handle_session, '0.0.0.0', 2503, loop=self.loop)
        self.server = self.loop.run_until_complete(server_coro)

        telnet_task = self.loop.run_in_executor(None, telnet_login)
        self.loop.run_until_complete(telnet_task)

    def cb(self, socket, command, option):
        return
Exemplo n.º 12
0
class FtpTests(unittest.TestCase):
    def setUp(self):
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(None)

        self.reporting_relay = ReportingRelay()
        self.reporting_relay_task = self.loop.run_in_executor(
            None, self.reporting_relay.start)

    def tearDown(self):
        self.reporting_relay.stop()
        # We give reporting_relay a chance to be finished
        self.loop.run_until_complete(self.reporting_relay_task)

        self.server.close()
        self.loop.run_until_complete(self.server.wait_closed())

        self.loop.close()

    def test_login(self):
        """Testing different login combinations"""
        def ftp_login():
            ftp_client = FTP()
            ftp_client.connect('127.0.0.1', 8888, 1)
            # expect perm exception
            try:
                ftp_client.login('james', 'bond')
                _ = ftp_client.getresp()  # NOQA
            except ftplib.error_perm:
                ftp_client.quit()

        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, self.loop)

        server_coro = asyncio.start_server(ftp_capability.handle_session,
                                           '0.0.0.0',
                                           8888,
                                           loop=self.loop)
        self.server = self.loop.run_until_complete(server_coro)

        ftp_task = self.loop.run_in_executor(None, ftp_login)
        self.loop.run_until_complete(ftp_task)
Exemplo n.º 13
0
class MySQLTests(unittest.TestCase):

  def setUp(self):
    self.loop = asyncio.new_event_loop()
    asyncio.set_event_loop(None)

    self.reporting_relay = ReportingRelay()
    self.reporting_relay_task = self.loop.run_in_executor(
        None, self.reporting_relay.start)

  def tearDown(self):
    self.reporting_relay.stop()
    # We give reporting_relay a chance to be finished
    self.loop.run_until_complete(self.reporting_relay_task)

    self.server.close()
    self.loop.run_until_complete(self.server.wait_closed())

    self.loop.run_until_complete(cancel_all_pending_tasks(self.loop))
    self.loop.close()

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

    def mysql_login():
      try:
        pymysql.connect(
            host="0.0.0.0",
            port=8306,
            user="******",
            password="******",
            db="testdb")
      except pymysql.err.OperationalError as e:
        return e
      return None

    options = {'enabled': 'True', 'port': 8306}
    mysql_cap = mysql.MySQL(options, self.loop)

    server_coro = asyncio.start_server(
        mysql_cap.handle_session, '0.0.0.0', 8306, loop=self.loop)
    self.server = self.loop.run_until_complete(server_coro)

    mysql_task = self.loop.run_in_executor(None, mysql_login)
    login_exception = self.loop.run_until_complete(mysql_task)

    self.assertIsInstance(login_exception, pymysql.err.OperationalError)
    self.assertEqual(
        str(login_exception),
        '(1045, "Access denied for user \'tuser\'@\'127.0.0.1\' (using password: YES)")'
    )

  def cb(self, socket, command, option):
    return
Exemplo n.º 14
0
class VncTests(unittest.TestCase):
    def setUp(self):
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(None)

        self.reporting_relay = ReportingRelay()
        self.reporting_relay_task = self.loop.run_in_executor(
            None, self.reporting_relay.start)

    def tearDown(self):
        self.reporting_relay.stop()
        # We give reporting_relay a chance to be finished
        self.loop.run_until_complete(self.reporting_relay_task)

        self.server.close()
        self.loop.run_until_complete(self.server.wait_closed())

        self.loop.close()

    def test_vnc_authentication(self):
        async def vnc_auth():
            reader, writer = await asyncio.open_connection('127.0.0.1',
                                                           8888,
                                                           loop=self.loop)
            # server rfb version
            _ = await reader.readline()
            writer.write(RFB_VERSION)

            # available auth methods
            _ = await reader.read(1024)
            writer.write(VNC_AUTH)

            # challenge
            _ = await reader.read(1024)
            # Pretending, that we encrypt received challenge with DES and send back the result.
            client_response = os.urandom(16)
            writer.write(client_response)

            # security result
            _ = await reader.read(1024)

        options = {'enabled': 'True', 'port': 8888, 'timeout': 30}
        capability = Vnc(options, self.loop)

        server_coro = asyncio.start_server(capability.handle_session,
                                           '0.0.0.0',
                                           8888,
                                           loop=self.loop)
        self.server = self.loop.run_until_complete(server_coro)

        self.loop.run_until_complete(vnc_auth())
Exemplo n.º 15
0
class MySQLTests(unittest.TestCase):
    def setUp(self):
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(None)

        self.reporting_relay = ReportingRelay()
        self.reporting_relay_task = self.loop.run_in_executor(None, self.reporting_relay.start)

    def tearDown(self):
        self.reporting_relay.stop()
        # We give reporting_relay a chance to be finished
        self.loop.run_until_complete(self.reporting_relay_task)

        self.server.close()
        self.loop.run_until_complete(self.server.wait_closed())

        self.loop.run_until_complete(cancel_all_pending_tasks(self.loop))
        self.loop.close()

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

        def mysql_login():
            try:
                pymysql.connect(host="0.0.0.0",
                                port=8306,
                                user="******",
                                password="******",
                                db="testdb")
            except pymysql.err.OperationalError as e:
                return e
            return None

        options = {'enabled': 'True', 'port': 8306}
        mysql_cap = mysql.MySQL(options, self.loop)

        server_coro = asyncio.start_server(
            mysql_cap.handle_session, '0.0.0.0', 8306, loop=self.loop)
        self.server = self.loop.run_until_complete(server_coro)

        mysql_task = self.loop.run_in_executor(None, mysql_login)
        login_exception = self.loop.run_until_complete(mysql_task)

        self.assertIsInstance(login_exception, pymysql.err.OperationalError)
        self.assertEqual(
            str(login_exception),
            '(1045, "Access denied for user \'tuser\'@\'127.0.0.1\' (using password: YES)")'
        )

    def cb(self, socket, command, option):
        return
Exemplo n.º 16
0
class Socks5Tests(unittest.TestCase):
    def setUp(self):
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(None)

        self.reporting_relay = ReportingRelay()
        self.reporting_relay_task = self.loop.run_in_executor(
            None, self.reporting_relay.start)

    def tearDown(self):
        self.reporting_relay.stop()
        # We give reporting_relay a chance to be finished
        self.loop.run_until_complete(self.reporting_relay_task)

        self.server.close()
        self.loop.run_until_complete(self.server.wait_closed())

        self.loop.close()

    def test_socks_authentication(self):
        async def socks_auth():
            reader, writer = await asyncio.open_connection('127.0.0.1',
                                                           8888,
                                                           loop=self.loop)

            # Greeting to the server. version+authmethod number+authmethod
            client_greeting = socks.SOCKS_VERSION + b"\x01" + socks.AUTH_METHOD
            writer.write(client_greeting)

            # Receive version+chosen authmethod
            _ = await reader.read(2)

            # Send credentials.
            # version+username len+username+password len+password
            credentials = b"\x05\x08username\x08password"
            writer.write(credentials)

            # Receive authmethod+\xff
            res = await reader.read(2)
            self.assertEqual(res, socks.AUTH_METHOD + socks.SOCKS_FAIL)

        options = {'enabled': 'True', 'port': 8888, 'timeout': 30}
        capability = socks.Socks5(options, self.loop)

        server_coro = asyncio.start_server(capability.handle_session,
                                           '127.0.0.1',
                                           8888,
                                           loop=self.loop)
        self.server = self.loop.run_until_complete(server_coro)
        self.loop.run_until_complete(socks_auth())
Exemplo n.º 17
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
Exemplo n.º 18
0
class Pop3Tests(unittest.TestCase):
    def setUp(self):
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(None)

        self.reporting_relay = ReportingRelay()
        self.reporting_relay_task = self.loop.run_in_executor(None, self.reporting_relay.start)

    def tearDown(self):
        self.reporting_relay.stop()
        # We give reporting_relay a chance to be finished
        self.loop.run_until_complete(self.reporting_relay_task)

        self.server.close()
        self.loop.run_until_complete(self.server.wait_closed())

        self.loop.run_until_complete(cancel_all_pending_tasks(self.loop))

        self.loop.close()

    def test_login(self):
        """Testing different login combinations"""
        async def pop3_login():
            login_sequences = [
                # invalid login, invalid password
                (('USER wakkwakk', b'+OK User accepted'), ('PASS wakkwakk', b'-ERR Authentication failed.')),
                # PASS without user
                (('PASS bond', b'-ERR No username given.'),),
                # Try to run a TRANSACITON state command in AUTHORIZATION state
                (('RETR', b'-ERR Unknown command'),),
            ]
            for sequence in login_sequences:
                reader, writer = await asyncio.open_connection('127.0.0.1', 8888,
                                                               loop=self.loop)
                # skip banner
                await reader.readline()

                for pair in sequence:
                    writer.write(bytes(pair[0] + "\r\n", 'utf-8'))
                    response = await reader.readline()
                    self.assertEqual(response.rstrip(), pair[1])

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

        server_coro = asyncio.start_server(sut.handle_session, '0.0.0.0', 8888, loop=self.loop)
        self.server = self.loop.run_until_complete(server_coro)

        self.loop.run_until_complete(pop3_login())
Exemplo n.º 19
0
class PostgreSQLTests(unittest.TestCase):
    def setUp(self):
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(None)

        self.reporting_relay = ReportingRelay()
        self.reporting_relay_task = self.loop.run_in_executor(
            None, self.reporting_relay.start)

    def tearDown(self):
        self.reporting_relay.stop()
        # We give reporting_relay a chance to be finished
        self.loop.run_until_complete(self.reporting_relay_task)

        self.server.close()
        self.loop.run_until_complete(self.server.wait_closed())

        self.loop.run_until_complete(cancel_all_pending_tasks(self.loop))
        self.loop.close()

    def test_invalid_login(self):
        """Tests if postgres server responds correctly to a invalid login attempt."""
        def postgresql_login():
            try:
                psycopg2.connect("postgres://*****:*****@0.0.0.0:2504/")
            except psycopg2.OperationalError as e:
                return e
            return None

        options = {'enabled': 'True', 'port': 2504}
        postgresql_cap = postgresql.PostgreSQL(options, self.loop)

        server_coro = asyncio.start_server(postgresql_cap.handle_session,
                                           '0.0.0.0',
                                           2504,
                                           loop=self.loop)
        self.server = self.loop.run_until_complete(server_coro)

        postgresql_task = self.loop.run_in_executor(None, postgresql_login)
        login_exception = self.loop.run_until_complete(postgresql_task)

        self.assertIsInstance(login_exception, psycopg2.OperationalError)
        self.assertEqual(
            str(login_exception),
            'FATAL:  password authentication failed for user "scott"\n')

    def cb(self, socket, command, option):
        return
Exemplo n.º 20
0
class Socks5Tests(unittest.TestCase):
    def setUp(self):
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(None)

        self.reporting_relay = ReportingRelay()
        self.reporting_relay_task = self.loop.run_in_executor(None, self.reporting_relay.start)

    def tearDown(self):
        self.reporting_relay.stop()
        # We give reporting_relay a chance to be finished
        self.loop.run_until_complete(self.reporting_relay_task)

        self.server.close()
        self.loop.run_until_complete(self.server.wait_closed())

        self.loop.close()

    def test_socks_authentication(self):
        async def socks_auth():
            reader, writer = await asyncio.open_connection('127.0.0.1', 8888,
                                                           loop=self.loop)

            # Greeting to the server. version+authmethod number+authmethod
            client_greeting = socks.SOCKS_VERSION + b"\x01" + socks.AUTH_METHOD
            writer.write(client_greeting)

            # Receive version+chosen authmethod
            _ = await reader.read(2)

            # Send credentials.
            # version+username len+username+password len+password
            credentials = b"\x05\x08username\x08password"
            writer.write(credentials)

            # Receive authmethod+\xff
            res = await reader.read(2)
            self.assertEqual(res, socks.AUTH_METHOD + socks.SOCKS_FAIL)

        options = {'enabled': 'True', 'port': 8888, 'timeout': 30}
        capability = socks.Socks5(options, self.loop)

        server_coro = asyncio.start_server(capability.handle_session, '127.0.0.1',
                                           8888, loop=self.loop)
        self.server = self.loop.run_until_complete(server_coro)
        self.loop.run_until_complete(socks_auth())
Exemplo n.º 21
0
class VncTests(unittest.TestCase):
    def setUp(self):
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(None)

        self.reporting_relay = ReportingRelay()
        self.reporting_relay_task = self.loop.run_in_executor(None, self.reporting_relay.start)

    def tearDown(self):
        self.reporting_relay.stop()
        # We give reporting_relay a chance to be finished
        self.loop.run_until_complete(self.reporting_relay_task)

        self.server.close()
        self.loop.run_until_complete(self.server.wait_closed())

        self.loop.close()

    def test_vnc_authentication(self):
        async def vnc_auth():
            reader, writer = await asyncio.open_connection('127.0.0.1', 8888,
                                                           loop=self.loop)
            # server rfb version
            _ = await reader.readline()
            writer.write(RFB_VERSION)

            # available auth methods
            _ = await reader.read(1024)
            writer.write(VNC_AUTH)

            # challenge
            _ = await reader.read(1024)
            # Pretending, that we encrypt received challenge with DES and send back the result.
            client_response = os.urandom(16)
            writer.write(client_response)

            # security result
            _ = await reader.read(1024)

        options = {'enabled': 'True', 'port': 8888, 'timeout': 30}
        capability = Vnc(options, self.loop)

        server_coro = asyncio.start_server(capability.handle_session, '0.0.0.0', 8888, loop=self.loop)
        self.server = self.loop.run_until_complete(server_coro)

        self.loop.run_until_complete(vnc_auth())
Exemplo n.º 22
0
class SshTests(unittest.TestCase):
    def setUp(self):
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(None)

        self.reporting_relay = ReportingRelay()
        self.reporting_relay_task = self.loop.run_in_executor(
            None, self.reporting_relay.start)

    def tearDown(self):
        self.reporting_relay.stop()
        # We give reporting_relay a chance to be finished
        self.loop.run_until_complete(self.reporting_relay_task)

        self.server.close()
        self.loop.run_until_complete(self.server.wait_closed())

        self.loop.close()

    def test_basic_login(self):
        async def run_client():
            async with asyncssh.connect('localhost',
                                        port=8888,
                                        username='******',
                                        password='******',
                                        known_hosts=None,
                                        loop=self.loop) as _:
                pass

        ssh_key_file = 'ssh.key'
        SSH.generate_ssh_key(ssh_key_file)

        options = {'enabled': 'True', 'port': 8888}
        server_coro = asyncssh.create_server(lambda: SSH(options, self.loop),
                                             '0.0.0.0',
                                             8888,
                                             server_host_keys=['ssh.key'],
                                             loop=self.loop)
        self.server = self.loop.run_until_complete(server_coro)

        try:
            self.loop.run_until_complete(run_client())
        except asyncssh.Error:
            pass
Exemplo n.º 23
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()
Exemplo n.º 24
0
class FtpTests(unittest.TestCase):
    def setUp(self):
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(None)

        self.reporting_relay = ReportingRelay()
        self.reporting_relay_task = self.loop.run_in_executor(None, self.reporting_relay.start)

    def tearDown(self):
        self.reporting_relay.stop()
        # We give reporting_relay a chance to be finished
        self.loop.run_until_complete(self.reporting_relay_task)

        self.server.close()
        self.loop.run_until_complete(self.server.wait_closed())

        self.loop.close()

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

        def ftp_login():
            ftp_client = FTP()
            ftp_client.connect('127.0.0.1', 8888, 1)
            # expect perm exception
            try:
                ftp_client.login('james', 'bond')
                _ = ftp_client.getresp()  # NOQA
            except ftplib.error_perm:
                ftp_client.quit()

        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, self.loop)

        server_coro = asyncio.start_server(ftp_capability.handle_session, '0.0.0.0', 8888, loop=self.loop)
        self.server = self.loop.run_until_complete(server_coro)

        ftp_task = self.loop.run_in_executor(None, ftp_login)
        self.loop.run_until_complete(ftp_task)
Exemplo n.º 25
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
Exemplo n.º 26
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()
Exemplo n.º 27
0
class HttpTests(unittest.TestCase):
    def setUp(self):
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(None)

        self.reporting_relay = ReportingRelay()
        self.reporting_relay_task = self.loop.run_in_executor(
            None, self.reporting_relay.start)

    def tearDown(self):
        self.reporting_relay.stop()
        # We give reporting_relay a chance to be finished
        self.loop.run_until_complete(self.reporting_relay_task)

        self.server.close()
        self.loop.run_until_complete(self.server.wait_closed())

        self.loop.close()

    def test_connection(self):
        """ Tests if the capability is up, and sending
            HTTP 401 (Unauthorized) headers.
        """
        def http_request():
            client = httpclient.HTTPConnection('127.0.0.1', 8888)
            client.request('GET', '/')
            response = client.getresponse()
            self.assertEqual(response.status, 401)

        options = {'enabled': 'True', 'port': 8888, 'users': {'test': 'test'}}
        http_cap = http.Http(options, self.loop)

        server_coro = asyncio.start_server(http_cap.handle_session,
                                           '0.0.0.0',
                                           8888,
                                           loop=self.loop)
        self.server = self.loop.run_until_complete(server_coro)

        http_task = self.loop.run_in_executor(None, http_request)
        self.loop.run_until_complete(http_task)
Exemplo n.º 28
0
    def add_auth_attempt(self, _type, **kwargs):
        self.login_attempts += 1
        entry = {'timestamp': datetime.utcnow(),
                 'session_id': self.id,
                 'auth_id': uuid.uuid4(),
                 'source_ip': self.source_ip,
                 'souce_port': self.source_port,
                 'destination_port': self.destination_port,
                 'protocol': self.protocol,
                 'username': None,
                 'password': None
                 }
        if 'username' in kwargs:
            entry['username'] = kwargs['username']
        if 'password' in kwargs:
            entry['password'] = kwargs['password']

        ReportingRelay.queueLogData(entry)
        self.activity()
        logger.debug('{0} authentication attempt from {1}:{2}. Credentials: {3}'.format(self.protocol, self.source_ip,
                                                                                        self.source_port,
                                                                                        json.dumps(kwargs)))
Exemplo n.º 29
0
    def add_auth_attempt(self, _type, **kwargs):

        # constructs dict to transmitted right away.
        entry = {
            'timestamp': datetime.utcnow(),
            'session_id': str(self.id),
            'auth_id': str(uuid.uuid4()),
            'source_ip': self.source_ip,
            'source_port': self.source_port,
            'destination_ip': self.destination_ip,
            'destination_port': self.destination_port,
            'protocol': self.protocol,
            'username': None,
            'password': None,
            'password_hash': None
        }
        if 'username' in kwargs:
            entry['username'] = kwargs['username']
        if 'password' in kwargs:
            entry['password'] = kwargs['password']
        if 'password_hash' in kwargs:
            entry['password_hash'] = kwargs['password_hash']
        ReportingRelay.logAuthAttempt(entry)

        # add to internal dict used for reporting when the session ends
        self.auth_attempts.append({
            'timestamp':
            entry['timestamp'].strftime('%Y-%m-%d %H:%M:%S.%f'),
            'username':
            entry['username'],
            'password':
            entry['password'],
        })

        self.activity()
        logger.debug(
            '%s authentication attempt from %s:%s. Auth mechanism: %s, session id %s '
            'Credentials: %s', self.protocol, self.source_ip, self.source_port,
            _type, self.id, json.dumps(kwargs))
Exemplo n.º 30
0
class SshTests(unittest.TestCase):
    def setUp(self):
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(None)

        self.reporting_relay = ReportingRelay()
        self.reporting_relay_task = self.loop.run_in_executor(None, self.reporting_relay.start)

    def tearDown(self):
        self.reporting_relay.stop()
        # We give reporting_relay a chance to be finished
        self.loop.run_until_complete(self.reporting_relay_task)

        self.server.close()
        self.loop.run_until_complete(self.server.wait_closed())

        self.loop.close()

    def test_basic_login(self):
        async def run_client():
            async with asyncssh.connect('localhost', port=8888,
                                        username='******', password='******',
                                        known_hosts=None, loop=self.loop) as _:
                pass

        ssh_key_file = 'ssh.key'
        SSH.generate_ssh_key(ssh_key_file)

        options = {'enabled': 'True', 'port': 8888}
        server_coro = asyncssh.create_server(lambda: SSH(options, self.loop), '0.0.0.0', 8888,
                                             server_host_keys=['ssh.key'], loop=self.loop)
        self.server = self.loop.run_until_complete(server_coro)

        try:
            self.loop.run_until_complete(run_client())
        except asyncssh.Error:
            pass
Exemplo n.º 31
0
class HttpTests(unittest.TestCase):
    def setUp(self):
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(None)

        self.reporting_relay = ReportingRelay()
        self.reporting_relay_task = self.loop.run_in_executor(None, self.reporting_relay.start)

    def tearDown(self):
        self.reporting_relay.stop()
        # We give reporting_relay a chance to be finished
        self.loop.run_until_complete(self.reporting_relay_task)

        self.server.close()
        self.loop.run_until_complete(self.server.wait_closed())

        self.loop.close()

    def test_connection(self):
        """ Tests if the capability is up, and sending
            HTTP 401 (Unauthorized) headers.
        """
        def http_request():
            client = httpclient.HTTPConnection('127.0.0.1', 8888)
            client.request('GET', '/')
            response = client.getresponse()
            self.assertEqual(response.status, 401)

        options = {'enabled': 'True', 'port': 8888, 'users': {'test': 'test'}}
        http_cap = http.Http(options, self.loop)

        server_coro = asyncio.start_server(http_cap.handle_session, '0.0.0.0', 8888, loop=self.loop)
        self.server = self.loop.run_until_complete(server_coro)

        http_task = self.loop.run_in_executor(None, http_request)
        self.loop.run_until_complete(http_task)
Exemplo n.º 32
0
class ImapTests(unittest.TestCase):
    def setUp(self):
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(None)

        self.reporting_relay = ReportingRelay()
        self.reporting_relay_task = self.loop.run_in_executor(
            None, self.reporting_relay.start)

    def tearDown(self):
        self.reporting_relay.stop()
        # We give reporting_relay a chance to be finished
        self.loop.run_until_complete(self.reporting_relay_task)

        self.server.close()
        self.loop.run_until_complete(self.server.wait_closed())

        self.loop.close()

    def test_LOGIN(self):
        """Testing different login combinations using simple login auth mechanism."""
        def imap_login():
            login_sequences = [('kajoj_admin', 'thebestpassword'),
                               ('\"kajoj_admin\"', 'the best password')]

            imap_obj = imaplib.IMAP4('127.0.0.1', port=8888)
            for sequence in login_sequences:
                with self.assertRaises(imaplib.IMAP4.error) as error:
                    imap_obj.login(sequence[0], sequence[1])
                imap_exception = error.exception
                self.assertEqual(imap_exception.args[0],
                                 b'Authentication failed')
            imap_obj.logout()

        options = {
            'enabled': 'True',
            'port': 143,
            'timeout': 30,
            'protocol_specific_data': {
                'max_attempts': 3,
                'banner': '* OK IMAP4rev1 Server Ready'
            }
        }
        capability = Imap(options, self.loop)
        server_coro = asyncio.start_server(capability.handle_session,
                                           '0.0.0.0',
                                           8888,
                                           loop=self.loop)
        self.server = self.loop.run_until_complete(server_coro)

        imap_task = self.loop.run_in_executor(None, imap_login)
        self.loop.run_until_complete(imap_task)

    def test_AUTHENTICATE_PLAIN(self):
        """Testing different login combinations using plain auth mechanism."""
        def imap_authenticate():
            # imaplib in Python 3.5.3 and higher returns str representation of auth failure
            # But imaplib in Python 3.5.2 and lower returns bytes.
            # This is a sad hack to get around this problem.
            pyversion = sys.version_info[:3]
            if pyversion < (3, 5, 3):
                auth_failure_msg = b'Authentication failed'
            else:
                auth_failure_msg = 'Authentication failed'
            login_sequences = [
                ('\0kajoj_admin\0thebestpassword', auth_failure_msg),
                ('\0пайтон\0наилучшийпароль', auth_failure_msg),
                ('kajoj_admin\0the best password',
                 'AUTHENTICATE command error: BAD [b\'invalid command\']')
            ]

            imap_obj = imaplib.IMAP4('127.0.0.1', port=8888)
            for sequence in login_sequences:
                with self.assertRaises(imaplib.IMAP4.error) as error:
                    imap_obj.authenticate('PLAIN', lambda x: sequence[0])
                imap_exception = error.exception
                self.assertEqual(imap_exception.args[0], sequence[1])
            imap_obj.logout()

        options = {
            'enabled': 'True',
            'port': 143,
            'timeout': 30,
            'protocol_specific_data': {
                'max_attempts': 3,
                'banner': '* OK IMAP4rev1 Server Ready'
            }
        }
        capability = Imap(options, self.loop)

        server_coro = asyncio.start_server(capability.handle_session,
                                           '0.0.0.0',
                                           8888,
                                           loop=self.loop)
        self.server = self.loop.run_until_complete(server_coro)

        imap_task = self.loop.run_in_executor(None, imap_authenticate)
        self.loop.run_until_complete(imap_task)
Exemplo n.º 33
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()
Exemplo n.º 34
0
    def start(self):
        """ Starts services. """

        if 'public_ip_as_destination_ip' in self.config and self.config[
                'public_ip_as_destination_ip'] is True:
            asyncio.ensure_future(self._record_and_lookup_public_ip(),
                                  loop=self.loop)

        # setup hash cracker's wordlist
        if self.config['hash_cracker']['enabled']:
            self.setup_wordlist()

        # start activity logging
        if 'activity_logging' in self.config:
            if 'file' in self.config['activity_logging'] and self.config[
                    'activity_logging']['file']['enabled']:
                auth_log = self.config['activity_logging']['file'][
                    'authentication_log_file']
                session_csv_log = self.config['activity_logging']['file'][
                    'session_csv_log_file']
                session_json_log = self.config['activity_logging']['file'][
                    'session_json_log_file']
                file_logger = FileLogger(session_csv_log, session_json_log,
                                         auth_log)
                self.file_logger_task = self.loop.run_in_executor(
                    None, file_logger.start)
                self.file_logger_task.add_done_callback(
                    common.on_unhandled_task_exception)
                self._loggers.append(file_logger)

            if 'syslog' in self.config['activity_logging'] and self.config[
                    'activity_logging']['syslog']['enabled']:
                sys_logger = SyslogLogger()
                self.sys_logger_task = self.loop.run_in_executor(
                    None, sys_logger.start)
                self.sys_logger_task.add_done_callback(
                    common.on_unhandled_task_exception)
                self._loggers.append(sys_logger)

            if 'hpfeeds' in self.config['activity_logging'] and self.config[
                    'activity_logging']['hpfeeds']['enabled']:
                session_channel = self.config['activity_logging']['hpfeeds'][
                    'session_channel']
                auth_channel = self.config['activity_logging']['hpfeeds'][
                    'auth_channel']
                host = self.config['activity_logging']['hpfeeds']['host']
                port = self.config['activity_logging']['hpfeeds']['port']
                ident = self.config['activity_logging']['hpfeeds']['ident']
                secret = self.config['activity_logging']['hpfeeds']['secret']
                hpfeeds_logger = HpFeedsLogger(session_channel, auth_channel,
                                               host, port, ident, secret)
                self.hpfeeds_logger_task = self.loop.run_in_executor(
                    None, hpfeeds_logger.start)
                self.hpfeeds_logger_task.add_done_callback(
                    common.on_unhandled_task_exception)

            if 'curiosum' in self.config['activity_logging'] and self.config[
                    'activity_logging']['curiosum']['enabled']:
                port = self.config['activity_logging']['curiosum']['port']
                curiosum_integration = CuriosumIntegration(port)
                self.hpfeeds_logger_task = self.loop.run_in_executor(
                    None, curiosum_integration.start)
                self.hpfeeds_logger_task.add_done_callback(
                    common.on_unhandled_task_exception)

        bind_host = self.config['bind_host']
        listen_ports = []
        for c in heralding.capabilities.handlerbase.HandlerBase.__subclasses__(
        ):
            cap_name = c.__name__.lower()
            if cap_name in self.config['capabilities']:
                if not self.config['capabilities'][cap_name]['enabled']:
                    continue
                port = self.config['capabilities'][cap_name]['port']
                listen_ports.append(port)
                # carve out the options for this specific service
                options = self.config['capabilities'][cap_name]
                # capabilities are only allowed to append to the session list
                cap = c(options, self.loop)
                try:
                    # # Convention: All capability names which end in 's' will be wrapped in ssl.
                    if cap_name.endswith('s'):
                        pem_file = '{0}.pem'.format(cap_name)
                        self.create_cert_if_not_exists(cap_name, pem_file)
                        ssl_context = self.create_ssl_context(pem_file)
                        server_coro = asyncio.start_server(cap.handle_session,
                                                           bind_host,
                                                           port,
                                                           loop=self.loop,
                                                           ssl=ssl_context)
                    elif cap_name == 'ssh':
                        # Since dicts and user-defined classes are mutable, we have
                        # to save ssh class and ssh options somewhere.
                        ssh_options = options
                        SshClass = c
                        self.SshClass = SshClass

                        ssh_key_file = 'ssh.key'
                        SshClass.generate_ssh_key(ssh_key_file)

                        banner = ssh_options['protocol_specific_data'][
                            'banner']
                        SshClass.change_server_banner(banner)

                        server_coro = asyncssh.create_server(
                            lambda: SshClass(ssh_options, self.loop),
                            bind_host,
                            port,
                            server_host_keys=[ssh_key_file],
                            login_timeout=cap.timeout)
                    elif cap_name == 'rdp':
                        pem_file = '{0}.pem'.format(cap_name)
                        self.create_cert_if_not_exists(cap_name, pem_file)
                        server_coro = asyncio.start_server(cap.handle_session,
                                                           bind_host,
                                                           port,
                                                           loop=self.loop)
                    else:
                        server_coro = asyncio.start_server(cap.handle_session,
                                                           bind_host,
                                                           port,
                                                           loop=self.loop)

                    server = self.loop.run_until_complete(server_coro)
                    logger.debug('Adding %s capability with options: %s',
                                 cap_name, options)
                    self._servers.append(server)
                except Exception as ex:
                    error_message = "Could not start {0} server on port {1}. Error: {2}".format(
                        c.__name__, port, ex)
                    logger.error(error_message)
                    raise ex
                else:
                    logger.info('Started %s capability listening on port %s',
                                c.__name__, port)
        ReportingRelay.logListenPorts(listen_ports)
Exemplo n.º 35
0
 def log_start_session(self):
     entry = self.get_session_info(False)
     ReportingRelay.logSessionInfo(entry)
Exemplo n.º 36
0
 def setUp(self):
     self.reportingRelay = ReportingRelay()
     self.reportingRelay.start()
Exemplo n.º 37
0
 def setUp(self):
     self.reportingRelay = ReportingRelay()
     self.reportingRelay.start()
Exemplo n.º 38
0
 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()
Exemplo n.º 39
0
    def setUp(self):
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(None)

        self.reporting_relay = ReportingRelay()
        self.reporting_relay_task = self.loop.run_in_executor(None, self.reporting_relay.start)
Exemplo n.º 40
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()
Exemplo n.º 41
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()
Exemplo n.º 42
0
class ImapTests(unittest.TestCase):
    def setUp(self):
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(None)

        self.reporting_relay = ReportingRelay()
        self.reporting_relay_task = self.loop.run_in_executor(None, self.reporting_relay.start)

    def tearDown(self):
        self.reporting_relay.stop()
        # We give reporting_relay a chance to be finished
        self.loop.run_until_complete(self.reporting_relay_task)

        self.server.close()
        self.loop.run_until_complete(self.server.wait_closed())

        self.loop.close()

    def test_LOGIN(self):
        """Testing different login combinations using simple login auth mechanism."""

        def imap_login():
            login_sequences = [
                ('kajoj_admin', 'thebestpassword'),
                ('\"kajoj_admin\"', 'the best password')
            ]

            imap_obj = imaplib.IMAP4('127.0.0.1', port=8888)
            for sequence in login_sequences:
                with self.assertRaises(imaplib.IMAP4.error) as error:
                    imap_obj.login(sequence[0], sequence[1])
                imap_exception = error.exception
                self.assertEqual(imap_exception.args[0], b'Authentication failed')
            imap_obj.logout()

        options = {'enabled': 'True', 'port': 143, 'timeout': 30,
                   'protocol_specific_data': {'max_attempts': 3,
                                              'banner': '* OK IMAP4rev1 Server Ready'}}
        capability = Imap(options, self.loop)
        server_coro = asyncio.start_server(capability.handle_session, '0.0.0.0', 8888, loop=self.loop)
        self.server = self.loop.run_until_complete(server_coro)

        imap_task = self.loop.run_in_executor(None, imap_login)
        self.loop.run_until_complete(imap_task)

    def test_AUTHENTICATE_PLAIN(self):
        """Testing different login combinations using plain auth mechanism."""

        def imap_authenticate():
            # imaplib in Python 3.5.3 and higher returns str representation of auth failure
            # But imaplib in Python 3.5.2 and lower returns bytes.
            # This is a sad hack to get around this problem.
            pyversion = sys.version_info[:3]
            if pyversion < (3, 5, 3):
                auth_failure_msg = b'Authentication failed'
            else:
                auth_failure_msg = 'Authentication failed'
            login_sequences = [
                ('\0kajoj_admin\0thebestpassword', auth_failure_msg),
                ('\0пайтон\0наилучшийпароль', auth_failure_msg),
                ('kajoj_admin\0the best password', 'AUTHENTICATE command error: BAD [b\'invalid command\']')
            ]

            imap_obj = imaplib.IMAP4('127.0.0.1', port=8888)
            for sequence in login_sequences:
                with self.assertRaises(imaplib.IMAP4.error) as error:
                    imap_obj.authenticate('PLAIN', lambda x: sequence[0])
                imap_exception = error.exception
                self.assertEqual(imap_exception.args[0], sequence[1])
            imap_obj.logout()

        options = {'enabled': 'True', 'port': 143, 'timeout': 30,
                   'protocol_specific_data': {'max_attempts': 3,
                                              'banner': '* OK IMAP4rev1 Server Ready'}}
        capability = Imap(options, self.loop)

        server_coro = asyncio.start_server(capability.handle_session, '0.0.0.0', 8888, loop=self.loop)
        self.server = self.loop.run_until_complete(server_coro)

        imap_task = self.loop.run_in_executor(None, imap_authenticate)
        self.loop.run_until_complete(imap_task)
Exemplo n.º 43
0
 def log_start_session(self):
     entry = self.get_session_info(False)
     ReportingRelay.logSessionInfo(entry)
Exemplo n.º 44
0
 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()
Exemplo n.º 45
0
class RDPTests(unittest.TestCase):
    def create_cert_if_not_exists(self, pem_file):
        if not os.path.isfile(pem_file):
            cert, key = generate_self_signed_cert("US", "None", "None", "None",
                                                  "None", "*", 365, 0)
            with open(pem_file, 'wb') as _pem_file:
                _pem_file.write(cert)
                _pem_file.write(key)

    def rdp_connect(self, ip_addr, port):
        s = socket.socket()
        s.connect((ip_addr, port))
        s.sendall(RDPClient.ConnectionRequestPDU())
        s.recv(1024)

        tls = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1_1)
        tls.sendall(RDPClient.ClientDataPDU())
        tls.recv(4096)

        tls.send(RDPClient.ErectDomainRequest())
        tls.sendall(RDPClient.AttactUserRequest())
        tls.recv(512)

        tls.sendall(RDPClient.ChannelJoinRequest(1007))
        tls.recv(1024)
        tls.sendall(RDPClient.ChannelJoinRequest(1003))
        tls.recv(1024)

        tls.sendall(RDPClient.ClientInfoPDU())
        res = b''
        res = tls.recv(512)

        if res != b'':
            return False
        return True

    def setUp(self):
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(None)

        self.reporting_relay = ReportingRelay()
        self.reporting_relay_task = self.loop.run_in_executor(
            None, self.reporting_relay.start)

    def tearDown(self):
        self.reporting_relay.stop()
        # We give reporting_relay a chance to be finished
        self.loop.run_until_complete(self.reporting_relay_task)

        self.server.close()
        self.loop.run_until_complete(self.server.wait_closed())

        self.loop.run_until_complete(cancel_all_pending_tasks(self.loop))
        self.loop.close()

    def test_invalid_login(self):
        """Tests if rdp server responds correctly to a invalid login attempt."""
        def rdp_login():
            try:
                res = self.rdp_connect('0.0.0.0', 8389)
            except Exception as e:
                print("+++EXCEPTION+++ \n", e)
                return e
            return res

        options = {
            "enabled": "True",
            "port": 3389,
            "protocol_specific_data": {
                "banner": "",
                "cert": {
                    "common_name": "*",
                    "country": "US",
                    "state": "None",
                    "locality": "None",
                    "organization": "None",
                    "organizational_unit": "None",
                    "valid_days": 365,
                    "serial_number": 0
                }
            }
        }
        rdp_cap = rdp.RDP(options, self.loop)
        self.create_cert_if_not_exists('rdp.pem')
        server_coro = asyncio.start_server(rdp_cap.handle_session,
                                           '0.0.0.0',
                                           8389,
                                           loop=self.loop)
        self.server = self.loop.run_until_complete(server_coro)

        rdp_task = self.loop.run_in_executor(None, rdp_login)
        login_res = self.loop.run_until_complete(rdp_task)

        self.assertEqual(True, login_res)
Exemplo n.º 46
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()
Exemplo n.º 47
0
    def start(self):
        """ Starts services. """

        if 'public_ip_as_destination_ip' in self.config and self.config['public_ip_as_destination_ip'] is True:
            asyncio.ensure_future(self._record_and_lookup_public_ip(), loop=self.loop)

        # start activity logging
        if 'activity_logging' in self.config:
            if 'file' in self.config['activity_logging'] and self.config['activity_logging']['file']['enabled']:
                auth_log = self.config['activity_logging']['file']['authentication_log_file']
                session_csv_log = self.config['activity_logging']['file']['session_csv_log_file']
                session_json_log = self.config['activity_logging']['file']['session_json_log_file']
                file_logger = FileLogger(session_csv_log, session_json_log, auth_log)
                self.file_logger_task = self.loop.run_in_executor(None, file_logger.start)
                self.file_logger_task.add_done_callback(common.on_unhandled_task_exception)
                self._loggers.append(file_logger)

            if 'syslog' in self.config['activity_logging'] and self.config['activity_logging']['syslog']['enabled']:
                sys_logger = SyslogLogger()
                self.sys_logger_task = self.loop.run_in_executor(None, sys_logger.start)
                self.sys_logger_task.add_done_callback(common.on_unhandled_task_exception)
                self._loggers.append(sys_logger)

            if 'hpfeeds' in self.config['activity_logging'] and self.config['activity_logging']['hpfeeds']['enabled']:
                session_channel = self.config['activity_logging']['hpfeeds']['session_channel']
                auth_channel = self.config['activity_logging']['hpfeeds']['auth_channel']
                host = self.config['activity_logging']['hpfeeds']['host']
                port = self.config['activity_logging']['hpfeeds']['port']
                ident = self.config['activity_logging']['hpfeeds']['ident']
                secret = self.config['activity_logging']['hpfeeds']['secret']
                hpfeeds_logger = HpFeedsLogger(session_channel, auth_channel, host, port, ident, secret)
                self.hpfeeds_logger_task = self.loop.run_in_executor(None, hpfeeds_logger.start)
                self.hpfeeds_logger_task.add_done_callback(common.on_unhandled_task_exception)

            if 'curiosum' in self.config['activity_logging'] and self.config['activity_logging']['curiosum']['enabled']:
                port = self.config['activity_logging']['curiosum']['port']
                curiosum_integration = CuriosumIntegration(port)
                self.hpfeeds_logger_task = self.loop.run_in_executor(None, curiosum_integration.start)
                self.hpfeeds_logger_task.add_done_callback(common.on_unhandled_task_exception)

        bind_host = self.config['bind_host']
        listen_ports = []
        for c in heralding.capabilities.handlerbase.HandlerBase.__subclasses__():
            cap_name = c.__name__.lower()
            if cap_name in self.config['capabilities']:
                if not self.config['capabilities'][cap_name]['enabled']:
                    continue
                port = self.config['capabilities'][cap_name]['port']
                listen_ports.append(port)
                # carve out the options for this specific service
                options = self.config['capabilities'][cap_name]
                # capabilities are only allowed to append to the session list
                cap = c(options, self.loop)

                try:
                    # # Convention: All capability names which end in 's' will be wrapped in ssl.
                    if cap_name.endswith('s'):
                        pem_file = '{0}.pem'.format(cap_name)
                        self.create_cert_if_not_exists(cap_name, pem_file)
                        ssl_context = self.create_ssl_context(pem_file)
                        server_coro = asyncio.start_server(cap.handle_session, bind_host, port,
                                                           loop=self.loop, ssl=ssl_context)
                    elif cap_name == 'ssh':
                        # Since dicts and user-defined classes are mutable, we have
                        # to save ssh class and ssh options somewhere.
                        ssh_options = options
                        SshClass = c
                        self.SshClass = SshClass

                        ssh_key_file = 'ssh.key'
                        SshClass.generate_ssh_key(ssh_key_file)

                        banner = ssh_options['protocol_specific_data']['banner']
                        SshClass.change_server_banner(banner)

                        server_coro = asyncssh.create_server(lambda: SshClass(ssh_options, self.loop),
                                                             bind_host, port, server_host_keys=[ssh_key_file],
                                                             login_timeout=cap.timeout, loop=self.loop)
                    else:
                        server_coro = asyncio.start_server(cap.handle_session, bind_host, port, loop=self.loop)

                    server = self.loop.run_until_complete(server_coro)
                    logger.debug('Adding %s capability with options: %s', cap_name, options)
                    self._servers.append(server)
                except Exception as ex:
                    error_message = "Could not start {0} server on port {1}. Error: {2}".format(c.__name__, port, ex)
                    logger.error(error_message)
                    self.loop.run_until_complete(common.cancel_all_pending_tasks(self.loop))
                    sys.exit(error_message)
                else:
                    logger.info('Started %s capability listening on port %s', c.__name__, port)
        ReportingRelay.logListenPorts(listen_ports)
Exemplo n.º 48
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()
Exemplo n.º 49
0
class SmtpTests(unittest.TestCase):
    def setUp(self):
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(None)

        self.reporting_relay = ReportingRelay()
        self.reporting_relay_task = self.loop.run_in_executor(
            None, self.reporting_relay.start)

    def tearDown(self):
        self.reporting_relay.stop()
        # We give reporting_relay a chance to be finished
        self.loop.run_until_complete(self.reporting_relay_task)

        self.server.close()
        self.loop.run_until_complete(self.server.wait_closed())

        self.loop.close()

    def test_connection(self):
        """ Tries to connect and run a EHLO command. Very basic test.
        """
        def smtp_connection():
            smtp_ = smtplib.SMTP('127.0.0.1',
                                 8888,
                                 local_hostname='localhost',
                                 timeout=15)
            smtp_.ehlo()
            smtp_.quit()

        # Use uncommon port so that we can run test even if the Honeypot is running.
        options = {
            'enabled': 'True',
            'port': 8888,
            'protocol_specific_data': {
                'banner': 'test'
            },
            'users': {
                'test': 'test'
            },
        }
        smtp_cap = smtp.smtp(options, self.loop)

        server_coro = asyncio.start_server(smtp_cap.handle_session,
                                           '0.0.0.0',
                                           8888,
                                           loop=self.loop)
        self.server = self.loop.run_until_complete(server_coro)

        smtp_task = self.loop.run_in_executor(None, smtp_connection)
        self.loop.run_until_complete(smtp_task)

    def test_AUTH_CRAM_MD5_reject(self):
        """ Makes sure the server rejects all invalid login attempts that use the
            CRAM-MD5 Authentication method.
        """
        def encode_cram_md5(challenge, user, password):
            challenge = base64.decodebytes(challenge)
            response = user + b' ' + bytes(
                hmac.HMAC(password, challenge, digestmod="md5").hexdigest(),
                'utf-8')
            return str(base64.b64encode(response), 'utf-8')

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

        options = {
            'enabled': 'True',
            'port': 8888,
            'protocol_specific_data': {
                'banner': 'Test'
            },
            'users': {
                'someguy': 'test'
            }
        }
        smtp_cap = smtp.smtp(options, self.loop)

        server_coro = asyncio.start_server(smtp_cap.handle_session,
                                           '0.0.0.0',
                                           8888,
                                           loop=self.loop)
        self.server = self.loop.run_until_complete(server_coro)

        smtp_task = self.loop.run_in_executor(None, smtp_auth_cram_md5)
        self.loop.run_until_complete(smtp_task)

    def test_AUTH_PLAIN_reject(self):
        """ Makes sure the server rejects all invalid login attempts that use the PLAIN Authentication method.
        """
        def smtp_auth_plain_reject():
            smtp_ = smtplib.SMTP('127.0.0.1',
                                 8888,
                                 local_hostname='localhost',
                                 timeout=15)
            arg = bytes('\0{0}\0{1}'.format('test', 'test'), 'utf-8')
            code, _ = smtp_.docmd(
                'AUTH', 'PLAIN ' + str(base64.b64encode(arg), 'utf-8'))
            smtp_.quit()
            self.assertEqual(code, 535)

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

        smtp_cap = smtp.smtp(options, self.loop)

        server_coro = asyncio.start_server(smtp_cap.handle_session,
                                           '0.0.0.0',
                                           8888,
                                           loop=self.loop)
        self.server = self.loop.run_until_complete(server_coro)

        smtp_task = self.loop.run_in_executor(None, smtp_auth_plain_reject)
        self.loop.run_until_complete(smtp_task)

    def test_AUTH_LOGIN_reject(self):
        """ Makes sure the server rejects all invalid login attempts that use the LOGIN Authentication method.
        """
        def smtp_auth_login_reject():
            smtp_ = smtplib.SMTP('127.0.0.1',
                                 8888,
                                 local_hostname='localhost',
                                 timeout=15)
            smtp_.docmd('AUTH', 'LOGIN')
            smtp_.docmd(str(base64.b64encode(b'test'), 'utf-8'))
            code, _ = smtp_.docmd(str(base64.b64encode(b'test'), 'utf-8'))
            smtp_.quit()
            self.assertEqual(code, 535)

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

        smtp_cap = smtp.smtp(options, self.loop)

        server_coro = asyncio.start_server(smtp_cap.handle_session,
                                           '0.0.0.0',
                                           8888,
                                           loop=self.loop)
        self.server = self.loop.run_until_complete(server_coro)

        smtp_task = self.loop.run_in_executor(None, smtp_auth_login_reject)
        self.loop.run_until_complete(smtp_task)
Exemplo n.º 50
0
class Pop3Tests(unittest.TestCase):
    def setUp(self):
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(None)

        self.reporting_relay = ReportingRelay()
        self.reporting_relay_task = self.loop.run_in_executor(
            None, self.reporting_relay.start)

    def tearDown(self):
        self.reporting_relay.stop()
        # We give reporting_relay a chance to be finished
        self.loop.run_until_complete(self.reporting_relay_task)

        self.server.close()
        self.loop.run_until_complete(self.server.wait_closed())

        self.loop.run_until_complete(cancel_all_pending_tasks(self.loop))

        self.loop.close()

    def test_login(self):
        """Testing different login combinations"""
        async def pop3_login():
            login_sequences = [
                # invalid login, invalid password
                (('USER wakkwakk', b'+OK User accepted'),
                 ('PASS wakkwakk', b'-ERR Authentication failed.')),
                # PASS without user
                (
                    ('PASS bond', b'-ERR No username given.'), ),
                # Try to run a TRANSACITON state command in AUTHORIZATION state
                (
                    ('RETR', b'-ERR Unknown command'), ),
            ]
            for sequence in login_sequences:
                reader, writer = await asyncio.open_connection('127.0.0.1',
                                                               8888,
                                                               loop=self.loop)
                # skip banner
                await reader.readline()

                for pair in sequence:
                    writer.write(bytes(pair[0] + "\r\n", 'utf-8'))
                    response = await reader.readline()
                    self.assertEqual(response.rstrip(), pair[1])

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

        server_coro = asyncio.start_server(sut.handle_session,
                                           '0.0.0.0',
                                           8888,
                                           loop=self.loop)
        self.server = self.loop.run_until_complete(server_coro)

        self.loop.run_until_complete(pop3_login())
Exemplo n.º 51
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()