今天在使用python-nmap来进行扫描入库的时候发现https端口硬生生的给判断成了http
仔细测试了好几次都是这样子。后来果断的不服气,仔细看了下扫描的参数。发现python-nmap调用的时候会强制加上-ox -这个参数
正常扫描是
nmap 45.33.49.119 -p T:443 -Pn -sV --script=banner
然而经过python-nmap以后就是
nmap -oX - 45.33.49.119 -p T:443 -Pn -sV --script=banner <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE nmaprun> <?xml-stylesheet href="file:///usr/local/bin/../share/nmap/nmap.xsl" type="text/xsl"?> <!-- Nmap 7.12 scan initiated Thu Sep 1 00:02:07 2016 as: nmap -oX - -p T:443 -Pn -sV --script=banner 45.33.49.119 --> <nmaprun scanner="nmap" args="nmap -oX - -p T:443 -Pn -sV --script=banner 45.33.49.119" start="1472659327" startstr="Thu Sep 1 00:02:07 2016" version="7.12" xmloutputversion="1.04"> <scaninfo type="connect" protocol="tcp" numservices="1" services="443"/> <verbose level="0"/> <debugging level="0"/> <host starttime="1472659328" endtime="1472659364"><status state="up" reason="user-set" reason_ttl="0"/> <address addr="45.33.49.119" addrtype="ipv4"/> <hostnames> <hostname name="ack.nmap.org" type="PTR"/> </hostnames> <ports><port protocol="tcp" portid="443"><state state="open" reason="syn-ack" reason_ttl="0"/><service name="http" product="Apache httpd" version="2.4.6" extrainfo="(CentOS)" tunnel="ssl" method="probed" conf="10"><cpe>cpe:/a:apache:http_server:2.4.6</cpe></service><script id="http-server-header" output="Apache/2.4.6 (CentOS)"><elem>Apache/2.4.6 (CentOS)</elem> </script></port> </ports> <times srtt="191238" rttvar="191238" to="956190"/> </host> <runstats><finished time="1472659364" timestr="Thu Sep 1 00:02:44 2016" elapsed="36.65" summary="Nmap done at Thu Sep 1 00:02:44 2016; 1 IP address (1 host up) scanned in 36.65 seconds" exit="success"/><hosts up="1" down="0" total="1"/> </runstats> </nmaprun> |
经过格式化以后看到的内容是
其中的一个参数tunnel.但是看了下https://bitbucket.org/xael/python-nmap/raw/8ed37a2ac20d6ef26ead60d36f739f4679fcdc3e/nmap/nmap.py这里的内容。发现没有与之关联的。
for dport in dhost.findall('ports/port'): # protocol proto = dport.get('protocol') # port number converted as integer port = int(dport.get('portid')) # state of the port state = dport.find('state').get('state') # reason reason = dport.find('state').get('reason') # name, product, version, extra info and conf if any name = product = version = extrainfo = conf = cpe = '' for dname in dport.findall('service'): name = dname.get('name') if dname.get('product'): product = dname.get('product') if dname.get('version'): version = dname.get('version') if dname.get('extrainfo'): extrainfo = dname.get('extrainfo') if dname.get('conf'): conf = dname.get('conf') for dcpe in dname.findall('cpe'): cpe = dcpe.text # store everything if not proto in list(scan_result['scan'][host].keys()): scan_result['scan'][host][proto] = {} scan_result['scan'][host][proto][port] = {'state': state, 'reason': reason, 'name': name, 'product': product, 'version': version, 'extrainfo': extrainfo, 'conf': conf, 'cpe': cpe} |
试想下如果把 name 以及 tunnel 取出来同时匹配不就好了。于是对此进行修改。410-440行
name = product = version = extrainfo = conf = cpe = tunnel ='' for dname in dport.findall('service'): name = dname.get('name') if dname.get('product'): product = dname.get('product') if dname.get('version'): version = dname.get('version') if dname.get('extrainfo'): extrainfo = dname.get('extrainfo') if dname.get('conf'): conf = dname.get('conf') if dname.get('tunnel'): tunnel = dname.get('tunnel') for dcpe in dname.findall('cpe'): cpe = dcpe.text # store everything if not proto in list(scan_result['scan'][host].keys()): scan_result['scan'][host][proto] = {} scan_result['scan'][host][proto][port] = {'state': state, 'reason': reason, 'name': name, 'product': product, 'version': version, 'extrainfo': extrainfo, 'conf': conf, 'tunnel':tunnel, 'cpe': cpe} |
还有在654-670行里面增加我们添加的 tunnel
csv_ouput = csv.writer(fd, delimiter=';') csv_header = [ 'host', 'hostname', 'hostname_type', 'protocol', 'port', 'name', 'state', 'product', 'extrainfo', 'reason', 'version', 'conf', 'tunnel', 'cpe' ] |
然后我们import这个文件。在获取的内容里面进行判断.如果 name 为 http 的同时 tunnel 为 ssl ,则判断为https
for targetHost in scanner.all_hosts(): if scanner[targetHost].state() == 'up' and scanner[targetHost]['tcp']: for targetport in scanner[targetHost]['tcp']: #print(scanner[targetHost]['tcp'][int(targetport)]) if scanner[targetHost]['tcp'][int(targetport)]['state'] == 'open' and scanner[targetHost]['tcp'][int(targetport)]['product']!='tcpwrapped': if scanner[targetHost]['tcp'][int(targetport)]['name']=='http' and scanner[targetHost]['tcp'][int(targetport)]['tunnel'] == 'ssl': scanner[targetHost]['tcp'][int(targetport)]['name'] = 'https' else: scanner[targetHost]['tcp'][int(targetport)]['name'] = scanner[targetHost]['tcp'][int(targetport)]['name'] print(domain+'\t'+targetHosts+'\t'+str(targetport) + '\t' + scanner[targetHost]['tcp'][int(targetport)]['name'] + '\t' + scanner[targetHost]['tcp'][int(targetport)]['product']+scanner[targetHost]['tcp'][int(targetport)]['version']) #if scanner[targetHost]['tcp'][int(targetport)]['name'] in ["https","http"]: |
改造后的文件扫描结果