├── README.md └── nmap_port_scan_withmasscan.py /README.md: -------------------------------------------------------------------------------- 1 | 20230728优化,改为基于python3开发,增加了网站标题展示 2 | 3 | 【设计思路】 4 | 5 | 用Nmap做全网端全端口安全监控,用于探测内网或外网大量ip,可极大提升扫描速度 6 | 7 | 1、使用masscan把ip端口扫描出来后,保存为json格式 8 | 9 | 2、将IP和端口提取,输入到nmap中扫描,使用多进程方法扫描 10 | 11 | 3、如果是http的,同时检测Web站点标题并打印展示 12 | 13 | 14 | 【用法】 15 | 16 | 1、安装python库 17 | 18 | pip install python-libnmap 19 | 20 | pip install chardet 21 | 22 | pip install requests 23 | 24 | 2、安装masscan 25 | 26 | github上下载masscan 编译安装 27 | 28 | 修改代码中的masscan的路径,在第17行 29 | 30 | 2、在该python文件的同文件夹下,创建文件scan_ip.txt,可以是IP或ip段,一行行分割 31 | 32 | 如 33 | 34 | 10.0.1.0/24 35 | 36 | 10.2.1.11 37 | 38 | 3、执行 39 | 40 | python nmap_port_scan_withmasscan.py 41 | 42 | 可以看到输出的结果 43 | 44 | 45 | 4、注意要点 46 | 47 | masscan扫描比较消耗带宽,扫描准确性与速度是有矛盾的,一般建议扫描速度参数 --rate 的范围为5000-20000 48 | 49 | 可以自行调整 数字越高扫描越快,但丢包多了、准确性就降低了,我这里为10000 50 | 51 | 数值太高会把带宽打满,特别是内网扫描的时候 要注意 52 | 53 | 54 | -------------------------------------------------------------------------------- /nmap_port_scan_withmasscan.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | from libnmap.process import NmapProcess 3 | from libnmap.parser import NmapParser 4 | import time 5 | import multiprocessing 6 | import os 7 | import json 8 | import requests 9 | import chardet 10 | import re 11 | 12 | # 处理端口状态 13 | global_port_states =['open'] 14 | # 使用masscan扫描,存储扫描结果,以作为nmap扫描的输入源 15 | if os.path.exists('test_json4.json'): 16 | os.remove('test_json4.json') 17 | os.system('/Users/larry/Program/masscan/bin/masscan -iL scan_ip.txt -p1-65535 -oJ test_json4.json --rate 10000') 18 | 19 | # 定义函数,用于进行扫描 20 | def do_nmap_scan(scan_ip_list, scan_port): 21 | # nmap自定义UA,避免被WAF检测到 22 | nmap_proc = NmapProcess(scan_ip_list, options='-sT -sV -p ' + str(scan_port) + ' -script-args http.useragent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36"') 23 | nmap_proc.run() 24 | nmap_repot = NmapParser.parse(nmap_proc.stdout) 25 | for host in nmap_repot.hosts: 26 | for serv in host.services: 27 | if serv.state in global_port_states: 28 | if serv.service == "http": 29 | scan_url = 'http://' + host.address + ':' + str(serv.port) 30 | Title(scan_url) 31 | else: 32 | print('scan_host is %s,scan result is %s|%s|%s|%s|%s' \ 33 | % (host.address, str(serv.port), serv.protocol, serv.state, serv.service, serv.banner)) 34 | 35 | 36 | 37 | # 获取网站标题 38 | def Title(scan_url_port): 39 | try: 40 | r = requests.get(scan_url_port, timeout=5, verify=False, stream=True) 41 | # 获取网站的页面编码 42 | if 'Content-Length' in r.headers.keys() and int(r.headers['Content-Length']) > 50000: 43 | print('[*]主机 ' + scan_url_port + ' 端口服务为:' + '大文件') 44 | else: 45 | r_detectencode = chardet.detect(r.content) 46 | actual_encode = r_detectencode['encoding'] 47 | response = re.findall(u'(.*?)', r.content.decode(actual_encode), re.S) 48 | if response == []: 49 | pass 50 | else: 51 | # 将页面解码为utf-8,获取中文标题 52 | res = response[0] 53 | banner = r.headers['server'] 54 | print( 55 | scan_url_port + '\t' + "".join(banner.split()) + '\t' + ''.join(res.split()) + '\t' + str( 56 | r.status_code) + '\t' + str(len(r.content))) 57 | 58 | except Exception as e: 59 | pass 60 | 61 | 62 | # 定义扫描开始时间 63 | time_start = time.time() 64 | 65 | 66 | if __name__ == "__main__": 67 | # 引入多进程 68 | pool = multiprocessing.Pool(8) 69 | with open('test_json4.json', 'r') as file: 70 | str1 = file.read() 71 | #str2 = str1[:-4] + str1[-3:] 72 | data = json.loads(str1) 73 | for i in range(len(data)): 74 | scan_ip_list = data[i]['ip'] 75 | scan_port = data[i]['ports'][0]['port'] 76 | pool.apply_async(do_nmap_scan, args=(str(scan_ip_list), scan_port,)) 77 | pool.close() 78 | pool.join() 79 | print('扫描时间为%s秒' % (time.time() - time_start)) 80 | --------------------------------------------------------------------------------