1919#
2020#
2121
22- import csv
23- import io
2422import os
25- import re
2623import shlex
2724import subprocess
2825import sys
2926import simplejson as json
3027import argparse
28+ import asyncio
3129from xml .etree import ElementTree as ET
3230from xml .etree .ElementTree import ParseError
33- from nmapparser import NmapCommandParser
34- from utils import get_nmap_path , user_is_root
35- from exceptions import NmapNotInstalledError , NmapXMLParserError , NmapExecutionError
36-
37- #from nmap3.nmapparser import NmapCommandParser
38- #from nmap3.utils import get_nmap_path, user_is_root
39- #from nmap3.exceptions import NmapNotInstalledError, NmapXMLParserError, NmapExecutionError
40-
31+ from nmap3 .nmapparser import NmapCommandParser
32+ from nmap3 .utils import get_nmap_path , user_is_root
33+ from nmap3 .exceptions import NmapNotInstalledError , NmapXMLParserError , NmapExecutionError
4134import xml
4235
4336__author__ = 'Wangolo Joel ([email protected] )' @@ -225,6 +218,7 @@ def nmap_os_detection(self, target, arg="-O", args=None): # requires root
225218 nmap -oX - nmmapper.com -O
226219 NOTE: Requires root
227220 """
221+ print ("Performing some scannins" )
228222 xml_root = self .scan_command (target = target , arg = arg , args = args )
229223 results = self .parser .os_identifier_parser (xml_root )
230224 return results
@@ -272,7 +266,7 @@ def run_command(self, cmd, timeout=None):
272266 return output .decode ('utf8' ).strip ()
273267 else :
274268 raise NmapNotInstalledError ()
275-
269+
276270 def get_xml_et (self , command_output ):
277271 """
278272 @ return xml ET
@@ -283,7 +277,6 @@ def get_xml_et(self, command_output):
283277 except ParseError :
284278 raise NmapXMLParserError ()
285279
286-
287280class NmapScanTechniques (Nmap ):
288281 """
289282 Extends Nmap to include nmap commands
@@ -339,27 +332,26 @@ def tpl(i):
339332
340333 return xml_root
341334
335+ @user_is_root
342336 def nmap_fin_scan (self , target , args = None ):
343337 """
344338 Perform scan using nmap's fin scan
345339
346340 @cmd nmap -sF 192.168.178.1
347341
348342 """
349- self .require_root ()
350-
351343 xml_root = self .scan_command (self .fin_scan , target = target , args = args )
352344 results = self .parser .filter_top_ports (xml_root )
353345 return results
354-
346+
347+ @user_is_root
355348 def nmap_syn_scan (self , target , args = None ):
356349 """
357350 Perform syn scan on this given
358351 target
359352
360353 @cmd nmap -sS 192.168.178.1
361354 """
362- self .require_root ()
363355 xml_root = self .scan_command (self .sync_scan , target = target , args = args )
364356 results = self .parser .filter_top_ports (xml_root )
365357 return results
@@ -375,14 +367,14 @@ def nmap_tcp_scan(self, target, args=None):
375367 xml_root = self .scan_command (self .tcp_connt , target = target , args = args )
376368 results = self .parser .filter_top_ports (xml_root )
377369 return results
378-
370+
371+ @user_is_root
379372 def nmap_udp_scan (self , target , args = None ):
380373 """
381374 Scan target using the nmap tcp connect
382375
383376 @cmd nmap -sU 192.168.178.1
384377 """
385- self .require_root ()
386378
387379 if (args ):
388380 assert (isinstance (args , str )), "Expected string got {0} instead" .format (type (args ))
@@ -410,7 +402,6 @@ def nmap_idle_scan(self, target, args=None):
410402 results = self .parser .filter_top_ports (xml_root )
411403 return results
412404
413-
414405class NmapHostDiscovery (Nmap ):
415406 """
416407 This object will perform host discovery
@@ -501,12 +492,95 @@ def nmap_disable_dns(self, target, args=None):
501492 results = self .parser .filter_top_ports (xml_root )
502493 return results
503494
495+ class NmapAsync (Nmap ):
496+ def __init__ (self , path = None ):
497+ super (NmapAsync , self ).__init__ (path = path )
498+ self .stdout = asyncio .subprocess .PIPE
499+ self .stderr = asyncio .subprocess .PIPE
500+
501+ async def run_command (self , cmd , timeout = None ):
502+ if (os .path .exists (self .nmaptool )):
503+ process = await asyncio .create_subprocess_shell (cmd ,stdout = self .stdout ,stderr = self .stderr )
504+
505+ try :
506+ data , stderr = await process .communicate ()
507+ except Exception as e :
508+ raise (e )
509+ else :
510+ if 0 != process .returncode :
511+ raise NmapExecutionError ('Error during command: "' + ' ' .join (cmd ) + '"\n \n ' + errs .decode ('utf8' ))
512+
513+ # Response is bytes so decode the output and return
514+ return data .decode ('utf8' ).strip ()
515+ else :
516+ raise NmapNotInstalledError ()
517+
518+ async def scan_command (self , target , arg , args = None , timeout = None ):
519+ self .target == target
520+
521+ command_args = "{target} {default}" .format (target = target , default = arg )
522+ scancommand = self .default_command () + command_args
523+ if (args ):
524+ scancommand += " {0}" .format (args )
525+
526+ output = await self .run_command (scancommand , timeout = timeout )
527+ xml_root = self .get_xml_et (output )
504528
529+ return xml_root
530+
531+ async def scan_top_ports (self , target , default = 10 , args = None , timeout = None ):
532+ top_port_args = " {target} --top-ports {default}" .format (target = target , default = default )
533+ command = self .default_command () + top_port_args
534+ if (args ):
535+ command += " {0}" .format (args )
536+
537+ output = await self .run_command (command , timeout = timeout )
538+ if not output :
539+ raise ValueError ("Unable to perform requested command" )
540+
541+ self .top_ports = self .parser .filter_top_ports (self .get_xml_et (output ))
542+ return self .top_ports
543+
544+ async def nmap_dns_brute_script (self , target , dns_brute = "--script dns-brute.nse" , timeout = None ):
545+ self .target = target
546+
547+ dns_brute_args = "{target} {default}" .format (target = target , default = dns_brute )
548+ dns_brute_command = self .default_command () + dns_brute_args
549+
550+ # Run the command and get the output
551+ output = await self .run_command (dns_brute_command , timeout = timeout )
552+ subdomains = self .parser .filter_subdomains (self .get_xml_et (output ))
553+ return subdomains
554+
555+ async def nmap_version_detection (self , target , arg = "-sV" , args = None , timeout = None ):
556+ xml_root = await self .scan_command (target = target , arg = arg , timeout = timeout )
557+ services = self .parser .filter_top_ports (xml_root )
558+ return services
559+
560+ async def nmap_stealth_scan (self , target , arg = "-Pn -sZ" , args = None ):
561+ xml_root = await self .scan_command (target = target , arg = arg , args = args )
562+ self .top_ports = self .parser .filter_top_ports (xml_root )
563+ return self .top_ports
564+
565+ async def nmap_os_detection (self , target , arg = "-O" , args = None ): # requires root
566+ xml_root = await self .scan_command (target = target , arg = arg , args = args )
567+ results = self .parser .os_identifier_parser (xml_root )
568+ return results
569+
570+ async def nmap_subnet_scan (self , target , arg = "-p-" , args = None ): # requires root
571+ xml_root = await self .scan_command (target = target , arg = arg , args = args )
572+ results = self .parser .filter_top_ports (xml_root )
573+ return results
574+
575+ async def nmap_list_scan (self , target , arg = "-sL" , args = None ): # requires root
576+ xml_root = await self .scan_command (target = target , arg = arg , args = args )
577+ results = self .parser .filter_top_ports (xml_root )
578+ return results
579+
505580if __name__ == "__main__" :
506581 parser = argparse .ArgumentParser (prog = "Python3 nmap" )
507582 parser .add_argument ('-d' , '--d' , help = 'Help' , required = True )
508583 args = parser .parse_args ()
509584
510- nmap = Nmap ()
511- result = nmap .scan_top_ports (target = '127.0.0.1' )
512- print (json .dumps (result , indent = 4 , sort_keys = True ))
585+ nmap = NmapAsync ()
586+ asyncio .run (nmap .nmap_version_detection (target = '127.0.0.1' ))
0 commit comments