Exemplo n.º 1
0
    def nmap_dns_brute_script(self,
                              target,
                              dns_brute="--script dns-brute.nse"):
        """
        Perform nmap scan using the dns-brute script

        :param: target can be IP or domain
        :param: default is the default top port

        nmap -oX - nmmapper.com --script dns-brute.nse
        """
        self.target = target
        parser = NmapCommandParser(None)

        dns_brute_args = "{target}  {default}".format(target=target,
                                                      default=dns_brute)

        dns_brute_command = self.default_command() + dns_brute_args
        dns_brute_shlex = shlex.split(
            dns_brute_command)  # prepare it for popen

        # Run the command and get the output
        output = self.run_command(dns_brute_shlex)

        # Begin parsing the xml response
        xml_root = self.get_xml_et(output)
        subdomains = parser.filter_subdomains(xml_root)
        return subdomains
Exemplo n.º 2
0
    def scan_top_ports(self, host, default=10, args=None):
        """
        Perform nmap's top ports scan

        :param: host can be IP or domain
        :param: default is the default top port

        This top port requires root previledges
        """
        parser  = NmapCommandParser(None)

        if(default > self.maxport):
            raise ValueError("Port can not be greater than default 65389")
        self.host = host

        if(args):
            assert(isinstance(args, str)), "Expected string got {0} instead".format(type(args))

        top_port_args = " {host} --top-ports {default}".format(host=host, default=default)
        scan_command = self.default_command() + top_port_args
        if(args):
            scan_command += " {0}".format(args)
        scan_shlex = shlex.split(scan_command)

        # Run the command and get the output
        output = self.run_command(scan_shlex)
        if not output:
            # Probaby and error was raise
            raise ValueError("Unable to perform requested command")

        # Begin parsing the xml response
        xml_root = self.get_xml_et(output)
        self.top_ports = parser.filter_top_ports(xml_root)
        return self.top_ports
Exemplo n.º 3
0
    def __init__(self, path=None):
        super(NmapHostDiscovery, self).__init__(path=path)

        self.port_scan_only = "-Pn"
        self.no_port_scan = "-sn"
        self.arp_discovery = "-PR"
        self.disable_dns = "-n"
        self.parser  = NmapCommandParser(None)
Exemplo n.º 4
0
    def __init__(self, path=None):
        super(NmapScanTechniques, self).__init__(path=path)

        self.sync_scan = "-sS"
        self.tcp_connt = "-sT"
        self.fin_scan = "-sF"
        self.ping_scan = "-sP"
        self.idle_scan = "-sL"
        self.udp_scan = "-sU"
        self.parser  = NmapCommandParser(None)
Exemplo n.º 5
0
    def __init__(self, path=None):
        """
        Module initialization

        :param path: Path where nmap is installed on a user system. On linux system it's typically on /usr/bin/nmap.
        """

        self.nmaptool = path if path else get_nmap_path()
        self.default_args = "{nmap}  {outarg}  -  "
        self.maxport = 65389
        self.target = ""
        self.top_ports = dict()
        self.parser = NmapCommandParser(None)
Exemplo n.º 6
0
    def nmap_ping_scan(self, host):
        """
        Scan host using nmaps' ping scan

        @cmd nmap -sP 192.168.178.1
        """
        ping_scan = " {host} {default}".format(host=host, default=self.ping_scan)
        ping_scan_command = self.default_command() + ping_scan
        ping_scan_shlex = shlex.split(ping_scan_command) # prepare it
        parser  = NmapCommandParser(None)

        output = self.run_command(ping_scan_shlex)
        xml_root = self.get_xml_et(output)
        ping_results = parser.parse_nmap_pingscan(xml_root)
        return ping_results
Exemplo n.º 7
0
    def nmap_idle_scan(self, host):
        """
        Using nmap idle_scan

        @cmd nmap -sL 192.168.178.1
        """
        idle_scan = " {host} {default}".format(host=host, default=self.idle_scan)
        idle_scan_command = self.default_command() + idle_scan
        idle_scan_shlex = shlex.split(idle_scan_command) # prepare it
        parser  = NmapCommandParser(None)

        # Use the ping scan parser
        output = self.run_command(idle_scan_shlex)
        xml_root = self.get_xml_et(output)
        idle_results = parser.parse_nmap_pingscan(xml_root)
        return idle_results
Exemplo n.º 8
0
    def nmap_fin_scan(self, host):
        """
        Perform scan using nmap's fin scan

        @cmd nmap -sF 192.168.178.1
        """
        fin_scan = " {host} {default}".format(host=host, default=self.fin_scan)
        fin_scan_command = self.default_command() + fin_scan
        fin_scan_shlex = shlex.split(fin_scan_command) # prepare it
        parser  = NmapCommandParser(None)

        # Use the ping scan parser
        output = self.run_command(fin_scan_shlex)
        xml_root = self.get_xml_et(output)
        fin_results = parser.parse_nmap_idlescan(xml_root)
        return fin_results
Exemplo n.º 9
0
    def nmap_subnet_scan(self, subnet, arg="-p-"): # requires root
        """
        nmap -oX - nmmapper.com --script dns-brute.nse
        NOTE: Requires root
        """
        self.host = subnet
        parser  = NmapCommandParser(None)

        command_args = "{host}  {default}".format(host=subnet, default=arg)
        command = self.default_command() + command_args
        dns_brute_shlex = shlex.split(command) # prepare it for popen
        output = self.run_command(dns_brute_shlex)
        xml_root = self.get_xml_et(output)

        host_discovered = parser.parse_nmap_subnetscan(xml_root)
        return host_discovered
Exemplo n.º 10
0
    def nmap_list_scan(self, subnet, arg="-sL"): # requires root
        """
        The list scan is a degenerate form of host discovery that simply lists each host of the network(s)
        specified, without sending any packets to the target hosts.

        NOTE: /usr/bin/nmap  -oX  -  192.168.178.1/24  -sL
        """
        self.host = subnet
        parser  = NmapCommandParser(None)

        command_args = "{host}  {default}".format(host=subnet, default=arg)
        command = self.default_command() + command_args
        dns_brute_shlex = shlex.split(command) # prepare it for popen

        output = self.run_command(dns_brute_shlex)
        xml_root = self.get_xml_et(output)

        host_discovered = parser.parse_nmap_listscan(xml_root)
        return host_discovered
Exemplo n.º 11
0
    def nmap_syn_scan(self, host, args=None):
        """
        Perform syn scan on this given
        host

        @cmd nmap -sS 192.168.178.1
        """
        parser  = NmapCommandParser(None)

        sync_scan = " {host} {default}".format(host=host, default=self.sync_scan)
        sync_scan_command = self.default_command() + sync_scan
        if(args):
            sync_scan_command += " {0}".format(args)
        sync_scan_shlex = shlex.split(sync_scan_command) # prepare it

        # Use the top_port_parser
        output = self.run_command(sync_scan_shlex)
        xml_root = self.get_xml_et(output)
        self.top_ports = parser.filter_top_ports(xml_root)
        return self.top_ports
Exemplo n.º 12
0
    def nmap_disable_dns(self, host, args=None):
        """
        Scan host using the nmap tcp connect

        @cmd nmap -PR 192.168.178.1
        """
        parser  = NmapCommandParser(None)

        if(args):
            assert(isinstance(args, str)), "Expected string got {0} instead".format(type(args))

        scancommand = " {host} {default}".format(host=host, default=self.arp_discovery)
        scan_command = self.default_command() + scancommand
        if(args):
            scan_command += " {0}".format(args)
        scan_shlex = shlex.split(scan_command) # prepare it

        # Use the top_port_parser
        output = self.run_command(scan_shlex)
        xml_root = self.get_xml_et(output)
        tcp_results = parser.filter_top_ports(xml_root)
        return tcp_results
Exemplo n.º 13
0
class NmapHostDiscovery(Nmap):
    """
    This object will perform host discovery

    1) Only port scan    (-Pn)
    2) Only host discover    (-sn)
    3) Arp discovery on a local network  (-PR)
    4) Disable DNS resolution    (-n)
    """
    def __init__(self, path=None):
        super(NmapHostDiscovery, self).__init__(path=path)

        self.port_scan_only = "-Pn"
        self.no_port_scan = "-sn"
        self.arp_discovery = "-PR"
        self.disable_dns = "-n"
        self.parser  = NmapCommandParser(None)


    def scan_command(self, scan_type, target, args):
        def tpl(i):
            scan_template = {
                1:self.port_scan_only,
                2:self.no_port_scan,
                3:self.arp_discovery,
                4:self.disable_dns
            }

            return scan_template.get(i)
        
        for i in range (1, 5):
            if scan_type == tpl(i):
                scan = " {target} {default}".format(target=target, default=scan_type)
                scan_type_command = self.default_command() + scan

                if(args):
                    scan_type_command += " {0}".format(args)
                
                scan_shlex = shlex.split(scan_type_command)

                # Use the ping scan parser
                output = self.run_command(scan_shlex)
                xml_root = self.get_xml_et(output)

        return xml_root

    def nmap_portscan_only(self, target, args=None):
        """
        Scan target using the nmap tcp connect

        @cmd nmap -Pn 192.168.178.1
        """
        xml_root = self.scan_command(self.port_scan_only, target=target, args=args)

        tcp_results = self.parser.filter_top_ports(xml_root)
        return tcp_results

    def nmap_no_portscan(self, target, args=None):
        """
        Scan target using the nmap tcp connect

        @cmd nmap -sn 192.168.178.1
        """
        if(args):
            assert(isinstance(args, str)), "Expected string got {0} instead".format(type(args))
        xml_root = self.scan_command(self.no_port_scan, target=target, args=args)

        tcp_results = self.parser.parse_noportscan(xml_root)
        return tcp_results

    def nmap_arp_discovery(self, target, args=None):
        """
        Scan target using the nmap tcp connect

        @cmd nmap -PR 192.168.178.1
        """
        if(args):
            assert(isinstance(args, str)), "Expected string got {0} instead".format(type(args))

        xml_root = self.scan_command(self.arp_discovery, target=target, args=args)

        tcp_results = self.parser.filter_top_ports(xml_root)
        return tcp_results

    def nmap_disable_dns(self, target, args=None):
        """
        Scan target using the nmap tcp connect

        @cmd nmap -n 192.168.178.1
        """
        if(args):
            assert(isinstance(args, str)), "Expected string got {0} instead".format(type(args))

        xml_root = self.scan_command(self.disable_dns, target=target, args=args)

        tcp_results = self.parser.filter_top_ports(xml_root)
        return tcp_results
Exemplo n.º 14
0
class Nmap(object):
    """
    This nmap class allows us to use the nmap port scanner tool from within python
    by calling nmap3.Nmap()
    """
    def __init__(self, path=None):
        """
        Module initialization

        :param path: Path where nmap is installed on a user system. On linux system it's typically on /usr/bin/nmap.
        """

        self.nmaptool = path if path else get_nmap_path()
        self.default_args = "{nmap}  {outarg}  -  "
        self.maxport = 65389
        self.target = ""
        self.top_ports = dict()
        self.parser  = NmapCommandParser(None)
        self.raw_ouput = None
        self.as_root = False

    def require_root(self, required=True):
        """
        Call this method to add "sudo" in front of nmap call
        """
        self.as_root = required
        
    def default_command(self):
        """
        Returns the default nmap command
        that will be chained with all others
        eg nmap -oX -
        """
        if self.as_root:
            return self.default_command_privileged()

        return self.default_args.format(nmap=self.nmaptool, outarg="-oX")
    
    def default_command_privileged(self):
        """
        Commands that require root privileges
        """
        if OS_TYPE == 'win32':
            # Elevate privileges and return nmap command
            # For windows now is not fully supported so just return the default
            return self.default_command() 
        else:
            return self.default_args.format(nmap="sudo "+self.nmaptool, outarg="-oX")

    def nmap_version(self):
        """
        Returns nmap version and build details
        """
        # nmap version output is not available in XML format (eg. -oX -)
        output = self.run_command([self.nmaptool, '--version'])
        version_data = {}
        for line in output.splitlines():
            if line.startswith('Nmap version '):
                version_string = line.split(' ')[2]
                version_data['nmap'] = tuple([int(_) for _ in version_string.split('.')])
            elif line.startswith('Compiled with:'):
                compiled_with = line.split(':')[1].strip()
                version_data['compiled_with'] = tuple(compiled_with.split(' '))
            elif line.startswith('Compiled without:'):
                compiled_without = line.split(':')[1].strip()
                version_data['compiled_without'] = tuple(compiled_without.split(' '))
            elif line.startswith('Available nsock engines:'):
                nsock_engines = line.split(':')[1].strip()
                version_data['nsock_engines'] = tuple(nsock_engines.split(' '))
        return version_data

    # Unique method for repetitive tasks - Use of 'target' variable instead of 'host' or 'subnet' - no need to make difference between 2 strings that are used for the same purpose
    def scan_command(self, target, arg, args):
        self.target == target
        
        command_args = "{target}  {default}".format(target=target, default=arg)
        scan_command = self.default_command() + command_args
        if(args):
            scan_command += " {0}".format(args)

        scan_shlex = shlex.split(scan_command)

        output = self.run_command(scan_shlex)
        xml_root = self.get_xml_et(output)

        return xml_root


    def scan_top_ports(self, target, default=10, args=None):
        """
        Perform nmap's top ports scan

        :param: target can be IP or domain
        :param: default is the default top port

        This top port requires root previledges
        """
        if(default > self.maxport):
            raise ValueError("Port can not be greater than default 65389")
        self.target = target

        if(args):
            assert(isinstance(args, str)), "Expected string got {0} instead".format(type(args))

        top_port_args = " {target} --top-ports {default}".format(target=target, default=default)
        scan_command = self.default_command() + top_port_args
        if(args):
            scan_command += " {0}".format(args)
        scan_shlex = shlex.split(scan_command)

        # Run the command and get the output
        output = self.run_command(scan_shlex)
        if not output:
            # Probaby and error was raise
            raise ValueError("Unable to perform requested command")

        # Begin parsing the xml response
        xml_root = self.get_xml_et(output)
        self.top_ports = self.parser.filter_top_ports(xml_root)
        return self.top_ports

    def nmap_dns_brute_script(self, target, dns_brute="--script dns-brute.nse"):
        """
        Perform nmap scan using the dns-brute script

        :param: target can be IP or domain
        :param: default is the default top port

        nmap -oX - nmmapper.com --script dns-brute.nse
        """
        self.target = target

        dns_brute_args = "{target}  {default}".format(target=target, default=dns_brute)

        dns_brute_command = self.default_command() + dns_brute_args
        dns_brute_shlex = shlex.split(dns_brute_command) # prepare it for popen

        # Run the command and get the output
        output = self.run_command(dns_brute_shlex)

        # Begin parsing the xml response
        xml_root = self.get_xml_et(output)
        subdomains = self.parser.filter_subdomains(xml_root)
        return subdomains

    def nmap_version_detection(self, target, arg="-sV", args=None):
        """
        Perform nmap scan using the dns-brute script

        :param: target can be IP or domain

        nmap -oX - nmmapper.com --script dns-brute.nse
        """
        xml_root = self.scan_command(target=target, arg=arg, args=args)

        services = self.parser.version_parser(xml_root)
        return services

    # Using of basic options for stealth scan

    def nmap_stealth_scan(self, target, arg="-Pn -sZ", args=None):
        """
        nmap -oX - nmmapper.com -Pn -sZ
        """
        xml_root = self.scan_command(target=target, arg=arg, args=args)
        self.top_ports = self.parser.filter_stealth_scan(xml_root)
        return self.top_ports
        
    def nmap_detect_firewall(self, target, arg="-sA", args=None): # requires root
        """
        nmap -oX - nmmapper.com -sA
        @ TODO
        """
        xml_root = self.scan_command(target=target, arg=arg, args=args)

        # TODO

    def nmap_os_detection(self, target, arg="-O", args=None): # requires root
        """
        nmap -oX - nmmapper.com -O
        NOTE: Requires root
        """
        xml_root = self.scan_command(target=target, arg=arg, args=args)
        os_identified = self.parser.os_identifier_parser(xml_root)
        return os_identified

    def nmap_subnet_scan(self, target, arg="-p-", args=None): # requires root
        """
        nmap -oX - nmmapper.com -p-
        NOTE: Requires root
        """

        xml_root = self.scan_command(target=target, arg=arg, args=args)
        subnet_discovered = self.parser.parse_nmap_subnetscan(xml_root)
        return subnet_discovered

    def nmap_list_scan(self, target, arg="-sL", args=None): # requires root
        """
        The list scan is a degenerate form of target discovery that simply lists each target of the network(s)
        specified, without sending any packets to the target targets.

        NOTE: /usr/bin/nmap  -oX  -  192.168.178.1/24  -sL
        """
        self.target = target
        xml_root = self.scan_command(target=target, arg=arg, args=args)

        hosts_discovered = self.parser.parse_nmap_listscan(xml_root)
        return hosts_discovered

    def run_command(self, cmd):
        """
        Runs the nmap command using popen

        @param: cmd--> the command we want run eg /usr/bin/nmap -oX -  nmmapper.com --top-ports 10
        """
        if (os.path.exists(self.nmaptool)):
            sub_proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            try:
                output, errs = sub_proc.communicate()
            except Exception as e:
                sub_proc.kill()
                raise (e)
            else:
                if 0 != sub_proc.returncode:
                    raise NmapExecutionError('Error during command: "' + ' '.join(cmd) + '"\n\n' + errs.decode('utf8'))

                # Response is bytes so decode the output and return
                return output.decode('utf8').strip()
        else:
            raise NmapNotInstalledError()

    def get_xml_et(self, command_output):
        """
        @ return xml ET
        """
        try:
            self.raw_ouput = command_output
            return ET.fromstring(command_output)
        except ParseError:
            raise NmapXMLParserError()
Exemplo n.º 15
0
class NmapScanTechniques(Nmap):
    """
    Extends Nmap to include nmap commands
    with different scan techniques

    This scan techniques include

    1) TCP SYN Scan (-sS)
    2) TCP connect() scan (-sT)
    3) FIN Scan (-sF)
    4) Ping Scan (-sP)
    5) Idle Scan (-sI)
    """

    def __init__(self, path=None):
        super(NmapScanTechniques, self).__init__(path=path)

        self.sync_scan = "-sS"
        self.tcp_connt = "-sT"
        self.fin_scan = "-sF"
        self.ping_scan = "-sP"
        self.idle_scan = "-sL"
        self.udp_scan = "-sU"
        self.parser  = NmapCommandParser(None)

    # Unique method for repetitive tasks - Use of 'target' variable instead of 'host' or 'subnet' - no need to make difference between 2 strings that are used for the same purpose. Creating a scan template as a switcher
    def scan_command(self, scan_type, target, args):
        def tpl(i):
            scan_template = {
                1:self.fin_scan,
                2:self.sync_scan,
                3:self.tcp_connt,
                4:self.ping_scan,
                5:self.idle_scan,
                6:self.udp_scan
            }

            return scan_template.get(i)
        
        for i in range (1, 7):
            if scan_type == tpl(i):
                scan = " {target} {default}".format(target=target, default=scan_type)
                scan_type_command = self.default_command() + scan

                if(args):
                    scan_type_command += " {0}".format(args)
                
                scan_shlex = shlex.split(scan_type_command)

                # Use the ping scan parser
                output = self.run_command(scan_shlex)
                xml_root = self.get_xml_et(output)

        return xml_root


    def nmap_fin_scan(self, target, args=None):
        """
        Perform scan using nmap's fin scan

        @cmd nmap -sF 192.168.178.1

        """
        self.require_root()

        xml_root = self.scan_command(self.fin_scan, target=target, args=args)

        fin_results = self.parser.parse_nmap_idlescan(xml_root)
        return fin_results

    def nmap_syn_scan(self, target, args=None):
        """
        Perform syn scan on this given
        target

        @cmd nmap -sS 192.168.178.1
        """
        self.require_root()
        xml_root = self.scan_command(self.sync_scan, target=target, args=args)
        
        # Use the top_port_parser
        self.top_ports = self.parser.filter_top_ports(xml_root)
        return self.top_ports

    def nmap_tcp_scan(self, target, args=None):
        """
        Scan target using the nmap tcp connect

        @cmd nmap -sT 192.168.178.1
        """
        if(args):
            assert(isinstance(args, str)), "Expected string got {0} instead".format(type(args))

        xml_root = self.scan_command(self.tcp_connt, target=target, args=args)

        tcp_results = self.parser.filter_top_ports(xml_root)
        return tcp_results
        
    def nmap_udp_scan(self, target, args=None):
        """
        Scan target using the nmap tcp connect

        @cmd nmap -sU 192.168.178.1
        """
        self.require_root()

        if(args):
            assert(isinstance(args, str)), "Expected string got {0} instead".format(type(args))

        xml_root = self.scan_command(self.udp_scan, target=target, args=args)

        tcp_results = self.parser.filter_top_ports(xml_root)
        return tcp_results

    def nmap_ping_scan(self, target, args=None):
        """
        Scan target using nmaps' ping scan

        @cmd nmap -sP 192.168.178.1
        """
        xml_root = self.scan_command(self.ping_scan, target=target, args=args)

        ping_results = self.parser.parse_nmap_pingscan(xml_root)
        return ping_results

    def nmap_idle_scan(self, target, args=None):
        """
        Using nmap idle_scan

        @cmd nmap -sL 192.168.178.1
        """
        xml_root = self.scan_command(self.idle_scan, target=target, args=args)

        idle_results = self.parser.parse_nmap_pingscan(xml_root)
        return idle_results
Exemplo n.º 16
0
class Nmap(object):
    """
    This nmap class allows us to use the nmap port scanner tool from within python
    by calling nmap3.Nmap()
    """
    def __init__(self, path=None):
        """
        Module initialization

        :param path: Path where nmap is installed on a user system. On linux system it's typically on /usr/bin/nmap.
        """

        self.nmaptool = path if path else get_nmap_path()
        self.default_args = "{nmap}  {outarg}  -  "
        self.maxport = 65389
        self.target = ""
        self.top_ports = dict()
        self.parser = NmapCommandParser(None)

    def default_command(self):
        """
        Returns the default nmap command
        that will be chained with all others
        eg nmap -oX -
        """
        return self.default_args.format(nmap=self.nmaptool, outarg="-oX")


# Unique method for repetitive tasks - Use of 'target' variable instead of 'host' or 'subnet' - no need to make difference between 2 strings that are used for the same purpose

    def scan_command(self, target, arg, args):
        self.target == target

        command_args = "{target}  {default}".format(target=target, default=arg)
        scan_command = self.default_command() + command_args
        if (args):
            scan_command += " {0}".format(args)

        scan_shlex = shlex.split(scan_command)

        output = self.run_command(scan_shlex)
        xml_root = self.get_xml_et(output)

        return xml_root

    def scan_top_ports(self, target, default=10, args=None):
        """
        Perform nmap's top ports scan

        :param: target can be IP or domain
        :param: default is the default top port

        This top port requires root previledges
        """
        parser = NmapCommandParser(None)

        if (default > self.maxport):
            raise ValueError("Port can not be greater than default 65389")
        self.target = target

        if (args):
            assert (isinstance(args,
                               str)), "Expected string got {0} instead".format(
                                   type(args))

        top_port_args = " {target} --top-ports {default}".format(
            target=target, default=default)
        scan_command = self.default_command() + top_port_args
        if (args):
            scan_command += " {0}".format(args)
        scan_shlex = shlex.split(scan_command)

        # Run the command and get the output
        output = self.run_command(scan_shlex)
        if not output:
            # Probaby and error was raise
            raise ValueError("Unable to perform requested command")

        # Begin parsing the xml response
        xml_root = self.get_xml_et(output)
        self.top_ports = parser.filter_top_ports(xml_root)
        return self.top_ports

    def nmap_dns_brute_script(self,
                              target,
                              dns_brute="--script dns-brute.nse"):
        """
        Perform nmap scan using the dns-brute script

        :param: target can be IP or domain
        :param: default is the default top port

        nmap -oX - nmmapper.com --script dns-brute.nse
        """
        self.target = target
        parser = NmapCommandParser(None)

        dns_brute_args = "{target}  {default}".format(target=target,
                                                      default=dns_brute)

        dns_brute_command = self.default_command() + dns_brute_args
        dns_brute_shlex = shlex.split(
            dns_brute_command)  # prepare it for popen

        # Run the command and get the output
        output = self.run_command(dns_brute_shlex)

        # Begin parsing the xml response
        xml_root = self.get_xml_et(output)
        subdomains = parser.filter_subdomains(xml_root)
        return subdomains

    def nmap_version_detection(self, target, arg="-sV", args=None):
        """
        Perform nmap scan using the dns-brute script

        :param: target can be IP or domain

        nmap -oX - nmmapper.com --script dns-brute.nse
        """
        xml_root = self.scan_command(target=target, arg=arg, args=args)

        services = self.parser.version_parser(xml_root)
        return services

    # Using of basic options for stealth scan

    def nmap_stealth_scan(self, target, arg="-Pn -sZ", args=None):
        """
        nmap -oX - nmmapper.com -Pn -sZ
        """
        xml_root = self.scan_command(target=target, arg=arg, args=args)
        self.top_ports = self.parser.filter_stealth_scan(xml_root)
        return self.top_ports

    def nmap_detect_firewall(self,
                             target,
                             arg="-sA",
                             args=None):  # requires root
        """
        nmap -oX - nmmapper.com -sA
        @ TODO
        """

        xml_root = self.scan_command(target=target, arg=arg, args=args)

        # TODO

    def nmap_os_detection(self, target, arg="-O", args=None):  # requires root
        """
        nmap -oX - nmmapper.com -O
        NOTE: Requires root
        """

        xml_root = self.scan_command(target=target, arg=arg, args=args)

        os_identified = self.parser.os_identifier_parser(xml_root)
        return os_identified

    def nmap_subnet_scan(self, target, arg="-p-", args=None):  # requires root
        """
        nmap -oX - nmmapper.com -p-
        NOTE: Requires root
        """

        xml_root = self.scan_command(target=target, arg=arg, args=args)

        subnet_discovered = self.parser.parse_nmap_subnetscan(xml_root)
        return subnet_discovered

    def nmap_list_scan(self, target, arg="-sL", args=None):  # requires root
        """
        The list scan is a degenerate form of target discovery that simply lists each target of the network(s)
        specified, without sending any packets to the target targets.

        NOTE: /usr/bin/nmap  -oX  -  192.168.178.1/24  -sL
        """
        self.target = target

        xml_root = self.scan_command(target=target, arg=arg, args=args)

        hosts_discovered = self.parser.parse_nmap_listscan(xml_root)
        return hosts_discovered

    def run_command(self, cmd):
        """
        Runs the nmap command using popen

        @param: cmd--> the command we want run eg /usr/bin/nmap -oX -  nmmapper.com --top-ports 10
        """
        if (os.path.exists(self.nmaptool)):
            sub_proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
            try:
                output, errs = sub_proc.communicate()
            except Exception as e:
                sub_proc.kill()
                raise (e)
            else:
                # Response is bytes so decode the output and return
                return output.decode('utf8').strip()
        else:
            raise NmapNotInstalledError()

    def get_xml_et(self, command_output):
        """
        @ return xml ET
        """
        try:
            return ET.fromstring(command_output)
        except xml.etree.ElementTree.ParseError:
            raise NmapXMLParserError()