当前位置: 首页 > 工具软件 > MASSCAN > 使用案例 >

Python编写masscan+nmap的主机和端口信息收集工具

钱华晖
2023-12-01

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} ] },
]


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 显示过程

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)

 

 类似资料: