python编写 masscan+nmap主机及端口信息收集工具

文章目录

      • 0x00 masscan使用
        • linux安装
        • 扫描选项
        • 注意事项
      • 0x01 nmap 使用
        • linux(debian)安装
        • window安装
        • 扫描选项
      • 0x02 masscan结合nmap进行端口扫描
        • masscan 获取主机和端口
        • nmap扫描主机端口服务详情
        • 扫描结果写入文件
        • 最终代码
      • 0x03 参考

0x00 masscan使用

linux安装

git clone https://github.com/robertdavidgraham/masscan 
make

扫描选项

masscan -iL target.txt -p 1-65535 -oJ result.json --rate 2000 -v

-iL 从文件中获取扫描目标

-p 指定参数

-oJ 结果以json形式存入文件

–rate 速率、每秒发送包的个数

-v 显示扫描过程信息

注意事项

-oJ 保存的json数据文件不是完整的json格式,最后多了一个逗号,直接用来json解析会出错。如下

[
{   "ip": "192.168.168.2",   "timestamp": "1586288135", "ports": [ {"port": 12310,"proto": "tcp", "status": "open", "reason": "syn-ack", "ttl": 250} ] },
{   "ip": "192.168.168.1",   "timestamp": "1586288135", "ports": [ {"port": 12310,"proto": "tcp", "status": "open", "reason": "syn-ack", "ttl": 250} ] },
]


0x01 nmap 使用

linux(debian)安装

apt-get install nmap

window安装

下载安装即可,注意加入系统环境变量

扫描选项

nmap -iL target.txt -p 1-65535  -sV  -v -oX result.txt

-iL 从文件中获取扫描目标

-p 扫描端口

-sV 扫描端口的服务及版本

-oX 将结果保存好xml格式的文件中

-v 显示过程

0x02 masscan结合nmap进行端口扫描

masscan主机发现速度极快,但是端口扫描准确性不高。

nmap端口扫描准确较高,但扫描速度较快。

因此可以先使用masscan获取存活主机和开放的端口,然后使用nmap扫描指定主机的端口。对于端口开放的web应用还可以获取其网站主题。以下使用python语言编写。

masscan 获取主机和端口

import subprocess
import json

def my_Masscan(targetFilePath):
	msg = "proxychains masscan -iL " + targetFilePath + " -p 1-65535  -oJ masscan.json --rate 2000"

	result = subprocess.run(msg,shell=True,text=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE)
	print(result.returncode)
	print(result.stdout)

	info = {
     } #scaned information

	if not result.returncode:
		with open('masscan.json','r+') as f: # repair the json
			for line in f.readlines():
				if  line.startswith("{"):
					portInfo = json.loads(line.strip()[:-1])
					ip = portInfo["ip"]
					port = portInfo["ports"][0]["port"]
					portALLInfo = portInfo["ports"]
					#print(ip,port,portALLInfo)

					if ip not in info:
						info[ip] = {
     }
					if "ports_masscan" not in info[ip]:
						info[ip]["ports_masscan"] = {
     }
	
					info[ip]["ports_masscan"][port] = portALLInfo
					
	
	#print(info)
	return info

函数返回的字典格式为{”192.x.x.x“: {”ports_masscan“: {21:{…}}}}

–rate参数,建议不要设置太高,否则无任何结果。

nmap扫描主机端口服务详情

import nmap  #pip3 install python_nmap
import os


def my_Nmap(info):
	host = info['host']
	arguments = info['arguments']
	scan = nmap.PortScanner()
	scan_result = scan.scan(hosts=host,arguments=arguments)
	all_hosts = scan.all_hosts()
	print(scan.command_line())

	info = {}

	for host in all_hosts:
		hostname = scan_result['scan'][host]['hostnames'][0]['name'] #主机名,可能有很多主机名此处取第一个
		address = scan_result['scan'][host]['addresses']['ipv4']    #主机ip地址
		status = scan_result['scan'][host]['status']['state'] #主机状态 up或者down

		if "up" not in status:
			continue

		info[host] = {"ports_nmap":{}}	
		
		
		ports_count = 0
		tcp_ports = []
		udp_ports = []
		ip_ports = []
		ctp_ports = []

		all_protocols = scan[host].all_protocols()
		for protocol in all_protocols:
			tcp_ports = scan[host].all_tcp() #所有tcp端口列表
			udp_ports = scan[host].all_udp() #
			ip_ports = scan[host].all_ip() #
			sctp_ports = scan[host].all_sctp() #

		ports_count = len(tcp_ports) + len(udp_ports) + len(ip_ports) + len(sctp_ports)

		if ports_count > 500:
			print("warning: there may be have a waf behind the host ",host)
		else:
           
			for tcp_port in tcp_ports:
				tcp_port_info = scan[host]['tcp'][tcp_port]
				tcp_port_state = scan[host]['tcp'][tcp_port]['state'] #状态
				tcp_port_name = tcp_port_info['name'] #协议名
				tcp_port_product = tcp_port_info['product'] #服务产品
				tcp_port_version = tcp_port_info['version'] #服务版本
				tcp_port_extrainfo = tcp_port_info['extrainfo']  #额外信息
				tcp_port_cpe = tcp_port_info['cpe'] #通用平台枚举,nmap对识别出来的软件、操作系统、硬件等的一种命名格式。
				info[host]["ports_nmap"]["ports"] = {tcp_port:tcp_port_info}		
			
	print(info)
	return info

扫描结果写入文件

import subprocess
import json
import nmap  #pip3 install python_nmap
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor 
import os
import openpyxl # pip3 install openpyxl



def my_Masscan(targetFilePath):
	msg = "proxychains masscan -iL " + targetFilePath + " -p 1-65535  -oJ masscan.json --rate 20000"
	print(msg)
	#msg = "tree /"
	
	result = subprocess.run(msg,shell=True,text=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE)
	print(result.returncode)
	print(result.stdout)

	info = {
     } #scaned information

	if not result.returncode:
		with open('masscan.json','r+') as f: # repair the json
			for line in f.readlines():
				if  line.startswith("{"):
					portInfo = json.loads(line.strip()[:-1])
					ip = portInfo["ip"]
					port = portInfo["ports"][0]["port"]
					portALLInfo = portInfo["ports"]
					#print(ip,port,portALLInfo)

					if ip not in info:
						info[ip] = {
     }
					if "ports_masscan" not in info[ip]:
						info[ip]["ports_masscan"] = {
     }
	
					info[ip]["ports_masscan"][port] = portALLInfo
					
	
	#print(info)
	return info
	

	
def my_Nmap(info):
	host = info['host']
	arguments = info['arguments']
	scan = nmap.PortScanner()
	scan_result = scan.scan(hosts=host,arguments=arguments)
	all_hosts = scan.all_hosts()
	print(scan.command_line())

	info = {
     }

	for host in all_hosts:
		hostname = scan_result['scan'][host]['hostnames'][0]['name'] #主机名,可能有很多主机名此处取第一个
		address = scan_result['scan'][host]['addresses']['ipv4']    #主机ip地址
		status = scan_result['scan'][host]['status']['state'] #主机状态 up或者down

		if "up" not in status:
			continue

		
		info[host] = {
     "ports_nmap":{
     }}	
		
		
		ports_count = 0
		tcp_ports = []
		udp_ports = []
		ip_ports = []
		ctp_ports = []

		all_protocols = scan[host].all_protocols()
		for protocol in all_protocols:
			tcp_ports = scan[host].all_tcp() #所有tcp端口列表
			udp_ports = scan[host].all_udp() #
			ip_ports = scan[host].all_ip() #
			sctp_ports = scan[host].all_sctp() #

		ports_count = len(tcp_ports) + len(udp_ports) + len(ip_ports) + len(sctp_ports)

		if ports_count > 100:
			print("warning: there may be have a waf behind the host ",host)
		else:
                        
			for tcp_port in tcp_ports:
				tcp_port_info = scan[host]['tcp'][tcp_port]
				tcp_port_state = scan[host]['tcp'][tcp_port]['state']
				tcp_port_name = tcp_port_info['name']
				tcp_port_product = tcp_port_info['product']
				tcp_port_version = tcp_port_info['version']
				tcp_port_extrainfo = tcp_port_info['extrainfo']
				tcp_port_cpe = tcp_port_info['cpe'] #通用平台枚举,nmap对识别出来的软件、操作系统、硬件等的一种命名格式。
				info[host]["ports_nmap"]["ports"] = {
     tcp_port:tcp_port_info}

		
		
	#print(info)
	dealInfo(info)
	return info
						
		

def dealInfo(info): #write  a xls file.
        print(info)
        hosts = list(info.keys())
        host = hosts[0]
        ports = info[host]["ports_nmap"]["ports"]
        
        
        

        
        if not os.path.exists("./tmp"):
                os.mkdir("./tmp")
        if not os.path.exists("./tmp/"+ host + ".xlsx"):
                workbook = openpyxl.Workbook()
                worksheet = workbook.active
                worksheet.title = "host info"
		
                column = ["ip","port","state","name","product","version","cpe","extrainfo"]
                for i in range(len(column)):
                        worksheet.cell(1,i+1,column[i])

        
                ports_list = list(ports.keys())
                print(ports_list)
                for j in range(len(ports_list)):
                        ip = host
                        port = ports_list[j]
                        for k in range(len(column)):
                                if column[k] == "ip":
                                        worksheet.cell(j+2,k+1,ip)
                                elif column[k] == "port":
                                        worksheet.cell(j+2,k+1,port)
                                        
                                else:
                                        worksheet.cell(j+2,k+1,ports[port][column[k]])
                
                workbook.save(filename="./tmp/"+ host + ".xlsx")
        else:
                print("File exist, eidting")

                
	

if __name__ == "__main__":
	targetFilePath = "target.txt"
	info = my_Masscan(targetFilePath)
	hosts = []
	for host,ports in info.items():
		hosts.append(host)
	
	thread_pool = ThreadPoolExecutor(20)
	if not os.path.exists("./tmp"):
		os.makedirs("./tmp")
	for host in hosts:
		info = {
     }
		arguments = '-sV -T4 -p 1-65535'
		info['host'] = host.strip()
		info['arguments'] = arguments
		thread_pool.submit(my_Nmap,info)




最终代码

import subprocess
import json
import nmap  #pip3 install python_nmap
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor 
import os
import openpyxl # pip3 install openpyxl



def my_Masscan(targetFilePath):
	msg = "masscan -iL " + targetFilePath + " -p 1-65535  -oJ masscan.json --rate 20000"
	print(msg)
	#msg = "tree /"
	
	result = subprocess.run(msg,shell=True,text=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE)
	print(result.returncode)
	print(result.stdout)

	info = {
     } #scaned information

	if not result.returncode:
		with open('masscan.json','r+') as f: # repair the json
			for line in f.readlines():
				if  line.startswith("{"):
					portInfo = json.loads(line.strip()[:-1])
					ip = portInfo["ip"]
					port = portInfo["ports"][0]["port"]
					portALLInfo = portInfo["ports"]
					#print(ip,port,portALLInfo)

					if ip not in info:
						info[ip] = {
     }
					if "ports_masscan" not in info[ip]:
						info[ip]["ports_masscan"] = {
     }
	
					info[ip]["ports_masscan"][port] = portALLInfo
					
	
	print(info)
	return info
	

	
def my_Nmap(info):
	host = info['host']
	arguments = info['arguments']
	scan = nmap.PortScanner()
	scan_result = scan.scan(hosts=host,arguments=arguments)
	all_hosts = scan.all_hosts()
	print(scan.command_line())

	info = {
     }

	for host in all_hosts:
		hostname = scan_result['scan'][host]['hostnames'][0]['name'] #主机名,可能有很多主机名此处取第一个
		address = scan_result['scan'][host]['addresses']['ipv4']    #主机ip地址
		status = scan_result['scan'][host]['status']['state'] #主机状态 up或者down

		if "up" not in status:
			continue

		
		info[host] = {
     "ports_nmap":{
     }}	
		
		
		ports_count = 0
		tcp_ports = []
		udp_ports = []
		ip_ports = []
		ctp_ports = []

		all_protocols = scan[host].all_protocols()
		for protocol in all_protocols:
			tcp_ports = scan[host].all_tcp() #所有tcp端口列表
			udp_ports = scan[host].all_udp() #
			ip_ports = scan[host].all_ip() #
			sctp_ports = scan[host].all_sctp() #

		ports_count = len(tcp_ports) + len(udp_ports) + len(ip_ports) + len(sctp_ports)

		if ports_count > 100:
			print("warning: there may be have a waf behind the host ",host)
		else:
                        
			for tcp_port in tcp_ports:
				tcp_port_info = scan[host]['tcp'][tcp_port]
				tcp_port_state = scan[host]['tcp'][tcp_port]['state']
				tcp_port_name = tcp_port_info['name']
				tcp_port_product = tcp_port_info['product']
				tcp_port_version = tcp_port_info['version']
				tcp_port_extrainfo = tcp_port_info['extrainfo']
				tcp_port_cpe = tcp_port_info['cpe'] #通用平台枚举,nmap对识别出来的软件、操作系统、硬件等的一种命名格式。
				info[host]["ports_nmap"]["ports"] = {
     tcp_port:tcp_port_info}

		
		
	#print(info)
	dealInfo(info)
	return info
						
		

def dealInfo(info): #write  a xls file.
        print(info)
        hosts = list(info.keys())
        host = hosts[0]
        ports = info[host]["ports_nmap"]["ports"]
        
        
        

        
        if not os.path.exists("./tmp"):
                os.mkdir("./tmp")
        if not os.path.exists("./tmp/"+ host + ".xlsx"):
                workbook = openpyxl.Workbook()
                worksheet = workbook.active
                worksheet.title = "host info"
		
                column = ["ip","port","state","name","product","version","cpe","extrainfo"]
                for i in range(len(column)):
                        worksheet.cell(1,i+1,column[i])

        
                ports_list = list(ports.keys())
                print(ports_list)
                for j in range(len(ports_list)):
                        ip = host
                        port = ports_list[j]
                        for k in range(len(column)):
                                if column[k] == "ip":
                                        worksheet.cell(j+2,k+1,ip)
                                elif column[k] == "port":
                                        worksheet.cell(j+2,k+1,port)
                                        
                                else:
                                        worksheet.cell(j+2,k+1,ports[port][column[k]])
                
                workbook.save(filename="./tmp/"+ host + ".xlsx")
        else:
                print("File exist, eidting")

                
	

if __name__ == "__main__":
	targetFilePath = "target.txt"
	info = my_Masscan(targetFilePath)
	hosts = []
	for host,ports in info.items():
		hosts.append(host)
	
	thread_pool = ThreadPoolExecutor(20)
	if not os.path.exists("./tmp"):
		os.makedirs("./tmp")
	for host in hosts:
		info = {
     }
		arguments = '-sV -T4 -p 1-65535'
		info['host'] = host.strip()
		info['arguments'] = arguments
		thread_pool.submit(my_Nmap,info)




0x03 参考

Nmap配合Masscan实现高效率扫描资
利用Python读取和修改Excel文件 包括xls文件和xlsx文件)——基于xlrd、xlwt和openpyxl模块
Masscan工具使用
python脚本解析masscan扫描结果

你可能感兴趣的:(Web安全,Python,python)