示例#1
0
文件: ports.py 项目: rydzykje/aucote
    async def prepare_args(self, nodes):
        """
        Prepare args for command execution

        Args:
            nodes (list): nodes from scanning

        Returns:
            list

        """
        args = list(cfg['tools.masscan.args'])

        rate = self.scan_rate()

        args.extend(['--rate', rate])

        include_ports = NmapTool.list_to_ports_string(
            tcp=self.tcp and cfg['portdetection.tcp.ports.include'],
            udp=self.udp and cfg['portdetection.udp.ports.include'])

        exclude_ports = NmapTool.list_to_ports_string(
            tcp=self.tcp and cfg['portdetection.tcp.ports.exclude'],
            udp=self.udp and cfg['portdetection.udp.ports.exclude'])

        if not include_ports:
            raise StopCommandException("No ports for scan")
        args.extend(['--ports', include_ports])

        if exclude_ports:
            args.extend(['--exclude-ports', exclude_ports])

        args.extend([str(node.ip) for node in nodes])

        return args
示例#2
0
    def setUp(self):
        super(NmapToolTest, self).setUp()
        self.exploit = Exploit(exploit_id=1,
                               name='test_name',
                               risk_level=RiskLevel.NONE)

        self.exploit2 = Exploit(exploit_id=2,
                                name='test_name',
                                risk_level=RiskLevel.HIGH)

        self.exploit_conf_args = Exploit(exploit_id=3)
        self.exploit_conf_args.name = 'test_name2'
        self.exploit_conf_args.risk_level = RiskLevel.HIGH

        self.config = {
            'scripts': {
                'test_name': {
                    'args': 'test_args'
                },
                'test_name2': {
                    'args': MagicMock()
                }
            }
        }

        self.cfg = {
            'tools': {
                'nmap': {
                    'disable_scripts': [],
                },
                'common': {
                    'rate': 1337,
                    'http': {
                        'useragent': 'test_useragent'
                    }
                }
            },
            'config_filename': ''
        }

        self.exploits = [self.exploit, self.exploit2]
        self.port = Port(number=13,
                         transport_protocol=TransportProtocol.TCP,
                         node=Node(node_id=1,
                                   ip=ipaddress.ip_address('127.0.0.1')))

        self.port.scan = Scan(start=14, end=13)
        self.port.protocol = 'test_service'

        self.aucote = MagicMock(storage=Storage(":memory:"))
        self.context = ScanContext(aucote=self.aucote,
                                   scanner=MagicMock(scan=Scan()))
        self.nmap_tool = NmapTool(context=self.context,
                                  exploits=self.exploits,
                                  port=self.port,
                                  config=self.config)
示例#3
0
    async def _scan_ports(self, scan_only, ports):

        port_range_allow = NmapTool.ports_from_list(tcp=cfg['portdetection.tcp.ports.include'],
                                                    udp=cfg['portdetection.udp.ports.include'])

        port_range_deny = NmapTool.ports_from_list(tcp=cfg['portdetection.tcp.ports.exclude'],
                                                   udp=cfg['portdetection.udp.ports.exclude'])

        ports = [port for port in ports if port.in_range(port_range_allow) and not port.in_range(port_range_deny)]

        self.context.add_task(Executor(context=self.context, nodes=[], ports=ports, scan_only=scan_only),
                              manager=TaskManagerType.QUICK)
示例#4
0
    async def prepare_args(self, nodes):
        args = ['-Pn']

        rate = self.scan_rate()

        if rate == '0':
            raise StopCommandException(
                "Cancel scan due to low throttling rate")

        if self.ipv6:
            args.append('-6')

        if self.tcp:
            args.extend([
                '-sS', '--host-timeout',
                str(parse_period(str(cfg['portdetection.tcp.host_timeout'])))
            ])

        if self.udp:
            if cfg['portdetection.udp.defeat_icmp_ratelimit']:
                args.extend(('--min-rate', rate, '--defeat-icmp-ratelimit'))

            args.extend(('-sU', '--max-retries',
                         str(cfg['portdetection.udp.max_retries'])))

        scripts_dir = cfg['tools.nmap.scripts_dir']

        if scripts_dir:
            args.extend(["--datadir", scripts_dir])

        include_ports = NmapTool.list_to_ports_string(
            tcp=self.tcp and cfg['portdetection.tcp.ports.include'],
            udp=self.udp and cfg['portdetection.udp.ports.include'])

        exclude_ports = NmapTool.list_to_ports_string(
            tcp=self.tcp and cfg['portdetection.tcp.ports.exclude'],
            udp=self.udp and cfg['portdetection.udp.ports.exclude'])

        if not include_ports:
            raise StopCommandException("No ports for scan")
        args.extend(['-p', include_ports])

        if exclude_ports:
            args.extend(['--exclude-ports', exclude_ports])

        args.extend(('--max-rate', rate))

        args.extend([str(node.ip) for node in nodes])
        return args
示例#5
0
    def test_custom_args_dns_srv_enum(self, cfg):
        cfg._cfg = self.cfg
        cfg._cfg['tools']['nmap']['domains'] = ['test.host', 'test.host2']
        expected = [
            'dns-srv-enum.domain=test.host', 'dns-srv-enum.domain=test.host2'
        ]

        self.assertEqual(NmapTool.custom_args_dns_srv_enum(), expected)
示例#6
0
    def test_list_to_ports(self):
        tcp = [14, '16-18']
        udp = [87, '34-36']
        sctp = [19, '25-28']

        expected = 'T:14,16-18,U:87,34-36,S:19,25-28'
        result = NmapTool.list_to_ports_string(tcp=tcp, udp=udp, sctp=sctp)

        self.assertEqual(result, expected)
示例#7
0
    def test_custom_args_dns_check_zone(self, cfg):
        cfg._cfg = self.cfg
        cfg._cfg['tools']['nmap']['domains'] = ['test.host', 'test.host2']
        expected = [
            'dns-check-zone.domain=test.host',
            'dns-check-zone.domain=test.host2'
        ]

        self.assertEqual(NmapTool.custom_args_dns_check_zone(), expected)
示例#8
0
    def test_custom_args_dns_zone_transfer(self, cfg):
        cfg._cfg = self.cfg
        cfg._cfg['tools']['nmap']['domains'] = ['test.host', 'test.host2']
        expected = [
            'dns-zone-transfer.domain=test.host',
            'dns-zone-transfer.domain=test.host2'
        ]

        self.assertEqual(NmapTool.custom_args_dns_zone_transfer(), expected)
示例#9
0
    def test_custom_args_http_domino_enum_passwords(self, cfg):
        cfg._cfg = self.cfg
        cfg._cfg['tools']['nmap']['domino-http'] = {
            "username": "******",
            "password": "******"
        }
        expected = "domino-enum-passwords.username='******',domino-enum-passwords.password=test_passwd"

        self.assertEqual(NmapTool.custom_args_http_domino_enum_passwords(),
                         expected)
示例#10
0
    def test_ports_from_list(self):
        tcp = ['14', '16-18']
        udp = ['87', '34-36']
        sctp = ['19', '25-28']

        expected = {
            TransportProtocol.TCP: {14, 16, 17, 18},
            TransportProtocol.UDP: {87, 34, 35, 36},
            TransportProtocol.SCTP: {19, 25, 26, 27, 28}
        }

        result = NmapTool.ports_from_list(tcp=tcp, udp=udp, sctp=sctp)
        self.assertEqual(result, expected)
示例#11
0
    async def scan_ports(self, nodes):
        include_ports = NmapTool.ports_from_list(
            tcp=cfg['portdetection.tcp.ports.include']).get(
                TransportProtocol.TCP)
        exclude_ports = NmapTool.ports_from_list(
            tcp=cfg['portdetection.tcp.ports.exclude']).get(
                TransportProtocol.TCP)

        ports = list(include_ports - exclude_ports)

        task = {str(node.ip): ports_to_string(set(ports)) for node in nodes}

        try:
            found_ports = await self.portscan.send(task)
        except PortscanError as exception:
            log.error("Error during performing scan: %s", exception)
            found_ports = {}

        return list({
            Port(number=port,
                 node=node,
                 transport_protocol=TransportProtocol.TCP)
            for node in nodes for port in found_ports.get(str(node.ip), [])
        })
示例#12
0
    def test_custom_args_http_useragent(self, cfg):
        cfg._cfg = self.cfg
        expected = "http.useragent='test_useragent'"

        self.assertEqual(NmapTool.custom_args_http_useragent(), expected)
示例#13
0
class NmapToolTest(AsyncTestCase):
    def setUp(self):
        super(NmapToolTest, self).setUp()
        self.exploit = Exploit(exploit_id=1,
                               name='test_name',
                               risk_level=RiskLevel.NONE)

        self.exploit2 = Exploit(exploit_id=2,
                                name='test_name',
                                risk_level=RiskLevel.HIGH)

        self.exploit_conf_args = Exploit(exploit_id=3)
        self.exploit_conf_args.name = 'test_name2'
        self.exploit_conf_args.risk_level = RiskLevel.HIGH

        self.config = {
            'scripts': {
                'test_name': {
                    'args': 'test_args'
                },
                'test_name2': {
                    'args': MagicMock()
                }
            }
        }

        self.cfg = {
            'tools': {
                'nmap': {
                    'disable_scripts': [],
                },
                'common': {
                    'rate': 1337,
                    'http': {
                        'useragent': 'test_useragent'
                    }
                }
            },
            'config_filename': ''
        }

        self.exploits = [self.exploit, self.exploit2]
        self.port = Port(number=13,
                         transport_protocol=TransportProtocol.TCP,
                         node=Node(node_id=1,
                                   ip=ipaddress.ip_address('127.0.0.1')))

        self.port.scan = Scan(start=14, end=13)
        self.port.protocol = 'test_service'

        self.aucote = MagicMock(storage=Storage(":memory:"))
        self.context = ScanContext(aucote=self.aucote,
                                   scanner=MagicMock(scan=Scan()))
        self.nmap_tool = NmapTool(context=self.context,
                                  exploits=self.exploits,
                                  port=self.port,
                                  config=self.config)

    @patch('tools.nmap.tool.NmapVulnParser')
    @patch('tools.nmap.tool.NmapInfoParser')
    @patch('tools.nmap.tool.NmapScript')
    @patch('tools.nmap.tool.NmapPortScanTask')
    @patch('tools.nmap.tool.cfg', new_callable=Config)
    @gen_test
    async def test_call(self, cfg, port_scan_mock, nmap_script,
                        info_scan_script, vuln_scan_script):
        cfg._cfg = self.cfg

        await self.nmap_tool()
        nmap_script.has_calls((call(exploit=self.exploit,
                                    port=self.port,
                                    parser=info_scan_script(),
                                    name='test_name',
                                    args='test_args'),
                               call(exploit=self.exploit2,
                                    port=self.port,
                                    parser=vuln_scan_script(),
                                    name='test_name',
                                    args='test_args')))

        result = port_scan_mock.call_count
        expected = 1

        self.assertEqual(result, expected)

    @patch('tools.nmap.tool.cfg', new_callable=Config)
    @gen_test
    async def test_enable(self, cfg):
        cfg._cfg = self.cfg
        self.exploit2.name = 'test_name2'
        await self.nmap_tool()

        result = self.nmap_tool.aucote.add_async_task.call_count
        expected = 1

        self.assertEqual(result, expected)

    @patch('tools.nmap.tool.cfg', new_callable=Config)
    @gen_test
    async def test_single_mode(self, cfg):
        cfg._cfg = self.cfg
        self.nmap_tool.config['scripts']['test_name']['singular'] = True
        self.exploit2.name = 'test_name2'
        await self.nmap_tool()

        result = self.nmap_tool.aucote.add_async_task.call_count
        expected = 2

        self.assertEqual(result, expected)

    @patch('tools.nmap.tool.NmapVulnParser')
    @patch('tools.nmap.tool.NmapScript')
    @patch('tools.nmap.tool.cfg', new_callable=Config)
    @gen_test
    async def test_configurable_args(self, cfg, nmap_script, vuln_parser):
        cfg._cfg = self.cfg
        self.nmap_tool.exploits = [self.exploit_conf_args]
        self.config['scripts']['test_name2'][
            'args'].return_value = 'dynamic_conf_test'
        await self.nmap_tool()
        nmap_script.assert_called_once_with(exploit=self.exploit_conf_args,
                                            port=self.port,
                                            parser=vuln_parser(),
                                            name='test_name2',
                                            args='dynamic_conf_test')

    @patch('tools.nmap.tool.NmapPortScanTask')
    @patch('tools.nmap.tool.cfg', new_callable=Config)
    @gen_test
    async def test_exploits_with_this_same_scripts_name(
            self, cfg, port_scan_mock):
        """
        Test executing exploits with this same script name
        Args:
            port_scan_mock (MagicMock):

        Returns:

        """
        cfg._cfg = self.cfg

        self.config['scripts']['test_name']['args'] = ['test', 'test2']
        self.nmap_tool._get_tasks = MagicMock()
        self.nmap_tool._get_tasks.return_value = [
            NmapScript(exploit=self.exploit,
                       parser=NmapParser,
                       port=self.port,
                       name='test_name',
                       args='test'),
            NmapScript(exploit=self.exploit,
                       parser=NmapParser,
                       port=self.port,
                       name='test_name',
                       args='test2')
        ]

        await self.nmap_tool()
        self.assertEqual(port_scan_mock.call_count, 2)

    @patch('tools.nmap.tool.cfg', new_callable=Config)
    def test_custom_args_dns_zone_transfer(self, cfg):
        cfg._cfg = self.cfg
        cfg._cfg['tools']['nmap']['domains'] = ['test.host', 'test.host2']
        expected = [
            'dns-zone-transfer.domain=test.host',
            'dns-zone-transfer.domain=test.host2'
        ]

        self.assertEqual(NmapTool.custom_args_dns_zone_transfer(), expected)

    @patch('tools.nmap.tool.cfg', new_callable=Config)
    def test_custom_args_dns_check_zone(self, cfg):
        cfg._cfg = self.cfg
        cfg._cfg['tools']['nmap']['domains'] = ['test.host', 'test.host2']
        expected = [
            'dns-check-zone.domain=test.host',
            'dns-check-zone.domain=test.host2'
        ]

        self.assertEqual(NmapTool.custom_args_dns_check_zone(), expected)

    @patch('tools.nmap.tool.NmapScript')
    @patch('tools.nmap.tool.cfg', new_callable=Config)
    @gen_test
    async def test_improper_configure_args(self, cfg, nmap_script):
        cfg._cfg = self.cfg
        self.nmap_tool.exploits = [self.exploit_conf_args]
        self.config['scripts']['test_name2']['args'].side_effect = KeyError(
            'test.test2')
        await self.nmap_tool()

        self.assertFalse(nmap_script.called)

    @patch('tools.nmap.tool.NmapScript')
    @patch('tools.nmap.tool.cfg', new_callable=Config)
    @gen_test
    async def test_disable_script_by_cfg(self, cfg, nmap_script):
        cfg._cfg = self.cfg
        cfg._cfg['tools']['nmap']['disable_scripts'] = [
            'test_name', 'test_name2'
        ]

        self.nmap_tool.exploits = [self.exploit_conf_args]
        await self.nmap_tool()

        self.assertFalse(nmap_script.called)

    @patch('tools.nmap.tool.NmapScript')
    @patch('tools.nmap.tool.cfg', new_callable=Config)
    @gen_test
    async def test_disable_script_by_internal_cfg(self, cfg, nmap_script):
        cfg._cfg = self.cfg
        self.nmap_tool.exploits = [self.exploit_conf_args]
        self.nmap_tool.config['disable_scripts'] = {'test_name', 'test_name2'}
        await self.nmap_tool()

        self.assertFalse(nmap_script.called)

    @patch('tools.nmap.tool.cfg', new_callable=Config)
    def test_custom_args_dns_srv_enum(self, cfg):
        cfg._cfg = self.cfg
        cfg._cfg['tools']['nmap']['domains'] = ['test.host', 'test.host2']
        expected = [
            'dns-srv-enum.domain=test.host', 'dns-srv-enum.domain=test.host2'
        ]

        self.assertEqual(NmapTool.custom_args_dns_srv_enum(), expected)

    @patch('tools.nmap.tool.cfg', new_callable=Config)
    def test_custom_args_http_domino_enum_passwords(self, cfg):
        cfg._cfg = self.cfg
        cfg._cfg['tools']['nmap']['domino-http'] = {
            "username": "******",
            "password": "******"
        }
        expected = "domino-enum-passwords.username='******',domino-enum-passwords.password=test_passwd"

        self.assertEqual(NmapTool.custom_args_http_domino_enum_passwords(),
                         expected)

    @patch('tools.nmap.tool.cfg', new_callable=Config)
    def test_custom_args_http_useragent(self, cfg):
        cfg._cfg = self.cfg
        expected = "http.useragent='test_useragent'"

        self.assertEqual(NmapTool.custom_args_http_useragent(), expected)

    @patch('tools.nmap.tool.cfg', new_callable=Config)
    def test_custom_service_args(self, cfg):
        cfg._cfg = {'tools': {'nmap': {'disable_scripts': []}}}
        custom_args = MagicMock(return_value="test_arg")
        self.config['services'] = {'test_service': {'args': custom_args}}
        self.nmap_tool.exploits = [self.exploit]

        self.nmap_tool.config = self.config
        result = self.nmap_tool._get_tasks()
        expected = "test_args,test_arg"

        self.assertEqual(len(result), 1)
        self.assertEqual(result[0].args, expected)

    @patch('tools.nmap.tool.cfg', new_callable=Config)
    def test_empty_custom_service_args(self, cfg):
        cfg._cfg = {'tools': {'nmap': {'disable_scripts': []}}}
        self.nmap_tool.config = self.config
        self.nmap_tool.exploits = [self.exploit]

        result = self.nmap_tool._get_tasks()
        expected = "test_args"

        self.assertEqual(len(result), 1)
        self.assertEqual(result[0].args, expected)

    @patch('tools.nmap.tool.cfg', new_callable=Config)
    def test_rate_from_tools_common(self, cfg):
        cfg._cfg = {'tools': {'common': {'rate': 1337}}}
        result = self.nmap_tool.rate
        expected = 1337

        self.assertEqual(result, expected)

    @patch('tools.nmap.tool.cfg', new_callable=Config)
    def test_rate(self, cfg):
        cfg._cfg = {
            'tools': {
                'common': {
                    'rate': 1337
                },
                'nmap': {
                    'rate': 7331
                }
            }
        }
        result = self.nmap_tool.rate
        expected = 7331

        self.assertEqual(result, expected)

    def test_parse_nmap_ports_string(self):
        ports = "T:22,80-82,U:78-80,U:90,S:1-2,18-20"

        expected = {
            TransportProtocol.TCP: {22, 80, 81, 82},
            TransportProtocol.UDP: {78, 79, 80, 90},
            TransportProtocol.SCTP: {1, 2, 18, 19, 20}
        }

        result = self.nmap_tool.parse_nmap_ports(ports)

        self.assertEqual(result, expected)

    def test_ports_from_list(self):
        tcp = ['14', '16-18']
        udp = ['87', '34-36']
        sctp = ['19', '25-28']

        expected = {
            TransportProtocol.TCP: {14, 16, 17, 18},
            TransportProtocol.UDP: {87, 34, 35, 36},
            TransportProtocol.SCTP: {19, 25, 26, 27, 28}
        }

        result = NmapTool.ports_from_list(tcp=tcp, udp=udp, sctp=sctp)
        self.assertEqual(result, expected)

    def test_list_to_ports(self):
        tcp = [14, '16-18']
        udp = [87, '34-36']
        sctp = [19, '25-28']

        expected = 'T:14,16-18,U:87,34-36,S:19,25-28'
        result = NmapTool.list_to_ports_string(tcp=tcp, udp=udp, sctp=sctp)

        self.assertEqual(result, expected)