2929import argparse
3030from xml .etree import ElementTree as ET
3131from xml .etree .ElementTree import ParseError
32- from nmap3 .exceptions import NmapNotInstalledError , NmapXMLParserError
3332from nmap3 .nmapparser import NmapCommandParser
3433from nmap3 .utils import get_nmap_path , user_is_root
35-
34+ from nmap3 . exceptions import NmapNotInstalledError , NmapXMLParserError , NmapExecutionError
3635import xml
3736
38- __author__ = 'Wangolo Joel (info @nmapper.com)'
39- __version__ = '1.4.7 '
37+ __author__ = 'Wangolo Joel (inquiry @nmapper.com)'
38+ __version__ = '1.4.9 '
4039__last_modification__ = '2020/12/10'
4140OS_TYPE = sys .platform
4241
@@ -59,13 +58,23 @@ def __init__(self, path=None):
5958 self .top_ports = dict ()
6059 self .parser = NmapCommandParser (None )
6160 self .raw_ouput = None
61+ self .as_root = False
62+
63+ def require_root (self , required = True ):
64+ """
65+ Call this method to add "sudo" in front of nmap call
66+ """
67+ self .as_root = required
6268
6369 def default_command (self ):
6470 """
6571 Returns the default nmap command
6672 that will be chained with all others
6773 eg nmap -oX -
6874 """
75+ if self .as_root :
76+ return self .default_command_privileged ()
77+
6978 return self .default_args .format (nmap = self .nmaptool , outarg = "-oX" )
7079
7180 def default_command_privileged (self ):
@@ -240,19 +249,22 @@ def run_command(self, cmd):
240249
241250 @param: cmd--> the command we want run eg /usr/bin/nmap -oX - nmmapper.com --top-ports 10
242251 """
243- if (os .path .exists (self .nmaptool )):
244- sub_proc = subprocess .Popen (cmd , stdout = subprocess .PIPE )
252+ if (os .path .exists (self .nmaptool )):
253+ sub_proc = subprocess .Popen (cmd , stdout = subprocess .PIPE , stderr = subprocess . PIPE )
245254 try :
246255 output , errs = sub_proc .communicate ()
247256 except Exception as e :
248257 sub_proc .kill ()
249- raise (e )
258+ raise (e )
250259 else :
260+ if 0 != sub_proc .returncode :
261+ raise NmapExecutionError ('Error during command: "' + ' ' .join (cmd ) + '"\n \n ' + errs .decode ('utf8' ))
262+
251263 # Response is bytes so decode the output and return
252264 return output .decode ('utf8' ).strip ()
253265 else :
254266 raise NmapNotInstalledError ()
255-
267+
256268 def get_xml_et (self , command_output ):
257269 """
258270 @ return xml ET
@@ -318,14 +330,15 @@ def tpl(i):
318330
319331 return xml_root
320332
321-
322333 def nmap_fin_scan (self , target , args = None ):
323334 """
324335 Perform scan using nmap's fin scan
325336
326337 @cmd nmap -sF 192.168.178.1
327338
328339 """
340+ self .require_root ()
341+
329342 xml_root = self .scan_command (self .fin_scan , target = target , args = args )
330343 results = self .parser .filter_top_ports (xml_root )
331344 return results
@@ -337,8 +350,8 @@ def nmap_syn_scan(self, target, args=None):
337350
338351 @cmd nmap -sS 192.168.178.1
339352 """
353+ self .require_root ()
340354 xml_root = self .scan_command (self .sync_scan , target = target , args = args )
341- # Use the top_port_parser
342355 results = self .parser .filter_top_ports (xml_root )
343356 return results
344357
@@ -360,6 +373,8 @@ def nmap_udp_scan(self, target, args=None):
360373
361374 @cmd nmap -sU 192.168.178.1
362375 """
376+ self .require_root ()
377+
363378 if (args ):
364379 assert (isinstance (args , str )), "Expected string got {0} instead" .format (type (args ))
365380 xml_root = self .scan_command (self .udp_scan , target = target , args = args )
@@ -476,12 +491,6 @@ def nmap_disable_dns(self, target, args=None):
476491 results = self .parser .filter_top_ports (xml_root )
477492 return results
478493
479- class NmapScripts (Nmap ):
480- """
481- This will be responsible for the nmap extra scriptin engine
482- """
483- pass
484-
485494if __name__ == "__main__" :
486495 parser = argparse .ArgumentParser (prog = "Python3 nmap" )
487496 parser .add_argument ('-d' , '--d' , help = 'Help' , required = True )
0 commit comments