使用Masscan扫描器进行信息搜集

news2024/9/25 7:22:23

Masscan 是一款极为高效的端口扫描工具,以其卓越的扫描速度和大规模扫描能力而著称。该工具不仅支持 TCP 和 UDP 协议的扫描,还允许用户根据需求灵活指定多个目标和端口。Masscan 通过采用先进的网络性能优化技术,充分利用操作系统的资源和多核处理能力,实现了极高的扫描效率和吞吐量。其强大的性能使它能在短时间内扫便互联网的每个角落。使用 Masscan,用户可以迅速了解目标主机的服务状态和潜在漏洞,并且工具提供多种灵活的输出格式和报告,便于后续的分析和处理。

源代码编译

由于该扫描器的底层采用了 Npcap 接口实现,因此在使用扫描器之前,用户需要先下载并安装Npcap库。安装完成后,用户需要下载Masscan的源代码,可以点击masscan-1.3.2.zip下载版本。

我们以下载源代码为例,下载好以后将其解压缩至任意位置。其中masscan-1.3.2/vs10目录下为Windows平台下的解决方案,读者可以使用Visual Studio打开该项目。在打开后会让读者升级项目此时点击升级即可,当升级结束后若直接对项目进行编译则会出现错误提示。
在这里插入图片描述
此时,读者可打开微软针对编译器的说明网站,由于笔者使用的是Visual Studio 2013则其对应的_MSC_VER为1800,读者只需要记录下这个编号。

在这里插入图片描述

接着,读者可在解决方案管理器内找到misc目录,并打开string_s.h头文件,打开后定位到第58行并将其中的1900替换为1800并保存文件,至此再次点击编译生成即可。当生成结束后会在其bin目录下得到masscan.exe扫描器成品。

在这里插入图片描述

使用扫描器探测

使用Masscan扫描常见的TCPUDP端口,可以在命令中直接指定。但默认情况下只会扫描TCP端口,若要扫描UDP端口则需要额外的参数配置。不过,Masscan 对于UDP扫描的支持并不如TCP扫描那样全面,建议在需要进行深入的UDP扫描时使用Nmap等工具。

我们通过使用-p参数来执行扫描常见的TCP端口,此处进扫描的端口包括 FTP(21)、SSH(22)、Telnet(23)、SMTP(25)、DNS(53)、HTTP(80)、POP3(110)、NetBIOS(139)、IMAP(143)、HTTPS(443)、SMB(445)、RDP(3389)。使用U来指定扫描UDP端口,此处扫描的端口包括DNS(53)、NTP(123)、SNMP(161),在扫描时我们通过使用0.0.0.0/8来指定网段。使用-oJ指定将扫描结果生成为JSON格式的报告,当然也可使用-oX指定生成XML报告。

masscan -p21,22,23,25,53,80,110,139,143,443,445,3389,U:53,U:123,U:161 0.0.0.0/8 -oJ output.json

若要扫描整个互联网则需要通过--exclude 255.255.255.255来指明。如下命令所示,通过0.0.0.0/0指定扫描全网段,并通过-p参数指定仅扫描HTTP(80)及HTTPS(443),执行命令后则会对整个互联网中的所有Web服务器进行探测,并输出为output_all.json格式的报告。

masscan -p80,443 0.0.0.0/0 --exclude 255.255.255.255 -oJ output_all.json

运用GeoIP2数据库解析

GeoIP2 是由MaxMind提供的一套地理位置数据库和API,用于将IP地址映射到地理位置信息。GeoIP2 数据库可以提供关于IP地址的详细地理信息,如国家、城市、经纬度、时区、自治系统(AS)等。其被广泛应用于各类需要地理位置数据的场景,如内容定制、安全、广告投放和数据分析等。

GeoIP2数据包含两部分内容,首先读者需要使用pip install geoip2来安装Python版本的接口,其次读者还需要自行下载对应的GeoLite2 database 数据库文件。

解析扫描结果

在之前我们通过使用Masscan扫描器扫描了世界范围内的所有Web服务器存活状态,并将扫描结果存储为了output_all.json格式的JSON文件中,接下来我们将通过使用Python解析这个数据库文件,并输出解析到的结果。

封装parse_scan_results函数,该函数接收一个扫描结果,并将该扫描结果解析为一个列表嵌套字典的格式,其中包含了基本的扫描信息,例如主机IP地址、扫描时间、端口号、TTL值等,并返回这个列表给调用者。

import json
from datetime import datetime, timezone
import geoip2.database

"""
    解析扫描结果文件,并返回一个包含字典的列表。

    :param filename: 包含扫描结果的 JSON 文件路径
    :return: 一个包含解析结果的列表,每个元素是一个字典
"""
def parse_scan_results(filename):
    results_list = []

    # 从文件中读取 JSON 数据
    with open(filename, 'r') as file:
        data = json.load(file)

    # 提取所需的信息并保存到列表中
    for result in data:
        ip = result['ip']
        timestamp = int(result['timestamp'])
        # 转换时间戳为具体时间
        readable_time = datetime.fromtimestamp(timestamp, timezone.utc).strftime('%Y-%m-%d %H:%M:%S')

        for port_info in result['ports']:
            port = port_info['port']
            ttl = port_info['ttl']
            # 将结果保存到字典中
            result_dict = {
                'IP地址': ip,
                '扫描时间': readable_time,
                '端口': port,
                'TTL': ttl
            }
            results_list.append(result_dict)

    return results_list

封装get_geo_info函数,该函数通过使用GeoIP2数据库,打开并查询IP地址的详细位置信息,并将该信息转换为一个字典格式返回给调用者。

"""
    通过 GeoIP2 数据库查询 IP 地址的地理信息。

    :param ip_address: 需要查询的 IP 地址
    :param db_path: GeoIP2 数据库文件的路径
    :return: 包含地理信息的字典
"""
def get_geo_info(ip_address, db_path):
    try:
        # 打开 GeoIP2 数据库
        reader = geoip2.database.Reader(db_path)

        # 查询 IP 地址的地理信息
        response = reader.city(ip_address)

        # 提取所需的地理信息
        geo_info = {
            '国家': response.country.name,
            '国家ISO代码': response.country.iso_code,
            '省份': response.subdivisions.most_specific.name,
            '省份ISO代码': response.subdivisions.most_specific.iso_code,
            '城市': response.city.name,
            '邮政编码': response.postal.code,
            '纬度': response.location.latitude,
            '经度': response.location.longitude,
            '时区': response.location.time_zone,
            '精度半径': response.location.accuracy_radius,
            '大洲': response.continent.name,
            '大洲代码': response.continent.code
        }

        # 关闭数据库
        reader.close()
        return geo_info

    except FileNotFoundError:
        # print(f"数据库文件 {db_path} 未找到。")
        return {}
    except geoip2.errors.AddressNotFoundError:
        # print(f"IP 地址 {ip_address} 未找到地理信息。")
        return {}
    except Exception as e:
        # print(f"出现错误: {e}")
        return {}

封装combine_scan_geo_info函数,用于将结合扫描结果和地理信息,生成包含完整信息的列表嵌套字典。封装format_combined_results函数,用于 格式化解析后的扫描结果和地理信息,并返回一个包含字典的列表。

"""
    结合扫描结果和地理信息,生成包含完整信息的列表嵌套字典。

    :param scan_results: 扫描结果列表
    :param db_path: GeoIP2 数据库文件的路径
    :return: 包含完整信息的列表,每个元素是一个字典
"""
def combine_scan_geo_info(scan_results, db_path):
    combined_results = []

    for result in scan_results:
        ip = result['IP地址']
        geo_info = get_geo_info(ip, db_path)
        combined_result = {**result, **geo_info}
        combined_results.append(combined_result)

    return combined_results

"""
    格式化解析后的扫描结果和地理信息,返回一个包含字典的列表。

    :param results_list: 包含扫描结果和地理信息的列表,每个元素是一个字典
    :return: 格式化后的结果列表
"""
def format_combined_results(results_list):
    formatted_results = []

    for result in results_list:
        formatted_result = {
            "IP地址": result.get("IP地址", ""),
            "扫描时间": result.get("扫描时间", ""),
            "端口": result.get("端口", ""),
            "TTL": result.get("TTL", ""),
            "国家": result.get("国家", ""),
            "国家ISO代码": result.get("国家ISO代码", ""),
            "省份": result.get("省份", ""),
            "省份ISO代码": result.get("省份ISO代码", ""),
            "城市": result.get("城市", ""),
            "邮政编码": result.get("邮政编码", ""),
            "纬度": result.get("纬度", ""),
            "经度": result.get("经度", ""),
            "时区": result.get("时区", ""),
            "精度半径": result.get("精度半径", ""),
            "大洲": result.get("大洲", ""),
            "大洲代码": result.get("大洲代码", "")
        }
        formatted_results.append(formatted_result)
    return formatted_results

封装analyze_ip_distribution函数,该函数用于分析IP地址的地理分布情况,统计每个国家的IP地址数量,并返回详细信息。

"""
    分析 IP 地址的地理分布情况,统计每个国家的 IP 地址数量,并返回详细信息。

    :param results_list: 包含扫描结果和地理信息的列表,每个元素是一个字典
    :return: 包含国家、IP 列表和 IP 数量的列表,每个元素是一个字典
"""
def analyze_ip_distribution(results_list):
    country_distribution = {}

    for result in results_list:
        country = result.get("国家", "未知")
        ip_address = result.get("IP地址", "")

        if country not in country_distribution:
            country_distribution[country] = {"国家": country, "IP列表": [], "数量": 0}

        country_distribution[country]["IP列表"].append(ip_address)
        country_distribution[country]["数量"] += 1

    # 将字典转换为列表
    country_distribution_list = list(country_distribution.values())

    return country_distribution_list
绘制全球IP数量分布

通过调用analyze_ip_distribution函数,我们还可以进一步分析这个扫描结果,获取到不同国家的IP地址信息,及所在国家的IP数量等,代码如下所示;

if __name__ == "__main__":
    # 文件名
    filename = './output_all.json'
    db_path = './GeoLite2-City.mmdb'

    # 解析扫描结果
    scan_results = parse_scan_results(filename)

    # 结合扫描结果和地理信息
    combined_results = combine_scan_geo_info(scan_results, db_path)

    # 格式化结果
    formatted_results = format_combined_results(combined_results)

    # 分析 IP 地址的地理分布情况
    ip_distribution = analyze_ip_distribution(formatted_results)

    # 打印分析结果
    for country_info in ip_distribution:
        print(f"国家: {country_info['国家']}, IP数量: {country_info['数量']}, IP列表: {country_info['IP列表']}")

运行上述代码,则可获取到不同国家的IP分布信息,如下图所示;因扫描仅进行了一小部分,则当前解析结果并不全面,仅用于研究代码案例。

在这里插入图片描述

接着通过使用pyecharts库,我们根据IP地址数量及国家分布,绘制一个数量分布柱状图,实现代码如下所示;

from pyecharts.charts import Bar
from pyecharts import options as opts

if __name__ == "__main__":
    # 文件名
    filename = './output_all.json'
    db_path = './GeoLite2-City.mmdb'

    # 解析扫描结果
    scan_results = parse_scan_results(filename)

    # 结合扫描结果和地理信息
    combined_results = combine_scan_geo_info(scan_results, db_path)

    # 格式化结果
    formatted_results = format_combined_results(combined_results)

    # 分析 IP 地址的地理分布情况
    ip_distribution = analyze_ip_distribution(formatted_results)

    # 过滤掉国家为美国的数据
    filtered_ip_distribution = [country_info for country_info in ip_distribution if country_info["国家"] != "United States"]

    # 提取国家和IP数量
    countries = [country_info["国家"] for country_info in filtered_ip_distribution]
    ip_counts = [country_info["数量"] for country_info in filtered_ip_distribution]

    # 创建柱状图
    bar = Bar()
    bar.add_xaxis(countries)
    bar.add_yaxis("IP数量", ip_counts)
    bar.set_global_opts(
        title_opts=opts.TitleOpts(title="全球IP数量分布(不包括美国)"),
        xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=45)),
        yaxis_opts=opts.AxisOpts(name="IP数量")
    )

    # 渲染图表为HTML文件
    bar.render("ip_distribution.html")

由于美国地区的IP地址过多,此处为了能展示柱状图效果则忽略美国地区的IP数量,这样能更好地展示柱状图分布,其运行效果如下图所示;

在这里插入图片描述

绘制全球IP位置分布

通过filename传入扫描后的记录信息,并调用GeoLite2-City.mmdb城市数据库文件,将IP地址解析并组合为一个新的扫描结果,通过循环输出给用户。

if __name__ == "__main__":
    # 文件名
    filename = './output_all.json'
    db_path = './GeoLite2-City.mmdb'

    # 解析扫描结果
    scan_results = parse_scan_results(filename)

    # 结合扫描结果和地理信息
    combined_results = combine_scan_geo_info(scan_results, db_path)

    # 格式化结果
    formatted_results = format_combined_results(combined_results)

    # 打印格式化后的结果
    for result in formatted_results:
        print(result)

通过循环的方式依次验证IP地址所对应的数据库信息,读者可以获取到包括IP地址、扫描时间、扫描端口、TTL值、国家、国家ISO代码、省份、省份ISO代码、城市、邮政编码、纬度、经度、时区、精度半径、大洲、大洲代码等信息,如下图所示;

在这里插入图片描述

KML(Keyhole Markup Language)是一种用于表示地理数据的 XML 格式文件。KML 文件通常用于在地理信息系统(GIS)和地理应用(如 Google Earth 和 Google Maps)中显示地理数据。我们可以将扫描到的数据进行归纳,并调用generate_kml_from_results函数提取出所需要的IP地址及经纬度信息,并将其生成为一个独立的KML文件。

def retKML(addr, longitude, latitude):
    # 确保 longitude 和 latitude 为浮点数,如果为 None 或无效值则设置为 0.0
    try:
        longitude = float(longitude)
    except (TypeError, ValueError):
        longitude = 0.0

    try:
        latitude = float(latitude)
    except (TypeError, ValueError):
        latitude = 0.0

    kml = (
        '<Placemark>\n'
        '<name>{}</name>\n'
        '<Point>\n'
        '<coordinates>{:.6f},{:.6f}</coordinates>\n'
        '</Point>\n'
        '</Placemark>\n'
    ).format(addr, longitude, latitude)
    return kml


def generate_kml_from_results(results_list, output_file):
    kmlheader = '<?xml version="1.0" encoding="UTF-8"?>\n<kml xmlns="http://www.opengis.net/kml/2.2">\n<Document>\n'
    kmlfooter = '</Document>\n</kml>\n'

    with open(output_file, "w") as f:
        f.write(kmlheader)

        for result in results_list:
            ip = result.get("IP地址", "")
            longitude = result.get("经度", 0.0)
            latitude = result.get("纬度", 0.0)
            kml_placemark = retKML(ip, longitude, latitude)
            f.write(kml_placemark)

        f.write(kmlfooter)


if __name__ == "__main__":
    # 文件名
    filename = './output_all.json'
    db_path = './GeoLite2-City.mmdb'

    # 解析扫描结果
    scan_results = parse_scan_results(filename)

    # 结合扫描结果和地理信息
    combined_results = combine_scan_geo_info(scan_results, db_path)

    # 格式化结果
    formatted_results = format_combined_results(combined_results)

    # 生成 KML 文件
    output_file = "GoogleEarth.kml"
    generate_kml_from_results(formatted_results, output_file)

通过将KML文件导入到谷歌地图中,我们可以很直观的在地图上进行打点操作,打点后每个国家的详细信息都将被呈现,如下图所示;

在这里插入图片描述

通过拉近一个国家,则可看到每一个打过标记的IP分布位置图,如下所示;

在这里插入图片描述

至此,本次的技术分享就到此结束了。事实上,在获取到IP地址的在线状态后,我们可以继续使用Nmap扫描器对其进行操作系统的鉴别。当鉴别到每一个IP地址的操作系统版本后,我们就可以推测出这个国家所使用的操作系统比例,并以此来衡量每个国家的操作系统普及程度及进一步评估其国家的系统安全系数。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2084072.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

更轻量级的性能测试工具—Apache Bench

之前一直使用的Jmeter进行接口性能测试&#xff0c;但是AB工具是很轻量级、快速开箱即用的。 yum安装 yum install -y httpd-tools 安装完成后&#xff0c;通过 ab -V 命令验证安装情况&#xff0c;如下表示安装成功 通过如下命令可以查看如何使用AB工具: 模拟请求示例&am…

在编程学习中,如何有效地管理时间和避免拖延?

在编程学习中&#xff0c;有效的时间管理和避免拖延是成功的关键因素。以下是一些实用的策略&#xff1a; 1. 明确目标 设定清晰的学习目标&#xff0c;了解你想要达成的技能水平。目标要具体、可衡量、可实现、相关性强、时限性&#xff08;SMART&#xff09;。 2. 制定计划…

19.神经网络 - 线性层及其他层介绍

神经网络 - 线性层及其他层介绍 1.批标准化层–归一化层&#xff08;不难&#xff0c;自学看官方文档&#xff09; Normalization Layers torch.nn — PyTorch 1.10 documentation BatchNorm2d — PyTorch 1.10 documentation 对输入采用Batch Normalization&#xff0c;可…

[AI]从零开始的so-vits-svc webui部署教程(小白向)

一、本次教程是给谁的&#xff1f; 如果你点进了这篇教程&#xff0c;相信你已经知道so-vits-svc是什么了&#xff0c;那么我们这里就不过多讲述了。如果你还不知道so-vits-svc能做什么&#xff0c;可以去b站搜索一下&#xff0c;你大概率会搜索到一些AI合成的音乐&#xff0c;…

SQL 注入之 WAF 绕过

在当今的网络安全环境中&#xff0c;SQL 注入攻击一直是一个严重的威胁&#xff0c;而 Web 应用防火墙&#xff08;WAF&#xff09;则是抵御此类攻击的重要防线。然而&#xff0c;攻击者们不断探索各种方法来绕过 WAF&#xff0c;以实现他们的恶意目的。本文将深入探讨 SQL 注入…

深度学习系列73:使用rapidStructure进行版面分析

1. 概述 项目地址https://github.com/RapidAI/RapidStructure?tabreadme-ov-file 2. 文档方向分类示例 安装$ pip install rapid-orientation import cv2 from rapid_orientation import RapidOrientation orientation_engine RapidOrientation() img cv2.imread(test_im…

SpringAOP-概述+配置文件的形式实现

2.1AOP概述 什么是AOP? AOP全称Aspect Oriented Programming&#xff0c;翻译过来就是&#xff1a;面向切面编程。 AOP是一种编程的规范AOP最早由AOP联盟的组织提出的,制定了一套规范.Spring将AOP思想引入到框架中,必须遵守AOP联盟的规范通过预编译方式或者运行期动态代理实…

投资组合理论中的资本资产定价模型(CAPM)和套利定价理论(APT)的实现案例

一&#xff1a;资本资产定价模型&#xff08;CAPM&#xff09; 资本资产定价模型&#xff08;Capital Asset Pricing Model&#xff0c;简称CAPM&#xff09;是金融学中一个重要的理论模型&#xff0c;用于估算一个投资的预期回报率&#xff0c;并确定投资的风险与预期回报之间…

前端面试题每日一练,测测你对JavaScript生成器和 Array.from 的理解

今天的挑战题目涉及到JavaScript中的生成器函数 (Generator) 和 Array.from 方法的结合使用。我们将利用生成器生成斐波那契数列&#xff0c;并通过 Array.from 创建一个包含前几个斐波那契数的数组。让我们一步步解析这段代码&#xff0c;看看它会输出什么以及为什么。 代码解…

抽奖系统PHP源码开源二开版带完整后台

该程序可以作为活动氛围活动气氛的烘托作用&#xff0c;活动游戏而已&#xff01; 抽奖系统源码是一个以php MySQL进行开发的手机抽奖系统源码。用途&#xff1a;适合做推广营销、直播、粉丝抽奖。 功能介绍&#xff1a; 1、后台可以设置每个抽奖用户的抽奖次数,后台添加设置…

四川财谷通信息技术有限公司引领抖音小店新风尚

在当今这个数字化时代&#xff0c;电子商务的浪潮以前所未有的速度席卷全球&#xff0c;而短视频平台抖音凭借其庞大的用户基数和强大的流量变现能力&#xff0c;成为了众多商家竞相入驻的新蓝海。在这片充满机遇与挑战的海洋中&#xff0c;四川财谷通信息技术有限公司以其敏锐…

模型 福格行为

系列文章 分享 模型&#xff0c;了解更多&#x1f449; 模型_思维模型目录。BMAP 1 福格行为的应用 1.1 基于福格行为模型的儿童教育应用设计 随着移动互联网的普及&#xff0c;儿童教育应用迅速发展&#xff0c;如何设计出既吸引儿童又能积极促进学习的教育应用成为设计者关…

景芯SoC A72实战反馈

先说结论&#xff1a; 内容非常全面&#xff0c;讲解到位&#xff0c;会有专门的工程师一对一答疑&#xff0c;整个项目跑下来提升非常大&#xff0c;绝对物超所值&#xff01; 一些细节&#xff1a; 本人微电子专业研一在读&#xff0c;有过两次简单的数字芯片流片经历&…

IO进程day04(进程)

目录 进程 1》什么是进程 1> 概念 2> 特点 3> 进程段 4> 进程分类 5> 进程状态 6> 进程状态切换图 7> 进程相关命令 <补充>优先级调度 2》进程函数接口 1> 创建进程 fork() 2> 回收资源 3> 结束进程 4> 获取进程号 3》exe…

《Cloud Native Data Center Networking》(云原生数据中心网络设计)读书笔记 -- 08网络自动化

云原生数据中心和老一代数据中心不同之处在于其核心概念是聚焦于高效运营。网络自动化就是达到此目标的关键因素。 要达到此目的&#xff0c;本章要解决诸如下述的一些问题&#xff1a; 什么是网络自动化以及为什么我们在乎它?为了学习网络自动化&#xff0c;我需要学习编程…

栈OJ题——栈的压入、弹出序列

文章目录 一、题目链接二、解题思路三、解题代码 一、题目链接 栈的压入、弹出序列 题目描述&#xff1a;给定两个整型数组&#xff0c;判断数组2是否是数组1的某一个出栈顺序。该题默认可以边入栈边出栈。 二、解题思路 三、解题代码 但是&#xff0c;上述解题代码中还存在一…

HCIP第一天作业

要求&#xff1a;R1-R2-R3-R4-R5 RIP 100 运行版本2 R6-R7 RIP 200 运行版本1 1.使用合理IP地址规划网络&#xff0c;各自创建环回接口 2.R1创建环回 172.16.1.1/24 172.16.2.1/24 172.16.3.1/24 3.要求R3使用R2访问R1环回 4.减少路由条目数量&#xff0c;R1-R2之间增…

Echarts栅格进度条装饰实现

如下图&#xff0c;如果你的业务需要这么一个饼图&#xff0c;你单纯借助echarts是实现不了如图效果的&#xff0c;你需要借助dom操作&#xff0c;合svg的配合才能实现。 首先饼图部分结束echarts,实现以及通过配置实现你想要的效果。 中间的文字百分比计算需要自己计算&#…

springboot3.x入门系列【5】支持unix sock 套接字服务

目录 一、简介 二、springBoot3.x 套接字的支持 1. 环境要求 2. springboot内置tomcat 2.1 支持unix 设置 unixDomainSocketPath 2.2 windows 下unix服务测试 3. springboot外置tomcat 3.1 tomcat 配置unix socket 套接字 3.2 启动tomcat 服务 3.3 nginx 支持unix…

python中传递任意数量的实参

有时候&#xff0c;你预先不知道函数需要接受多少个实参&#xff0c;好在Python允许函数从调用语句中收集任意数量的实参。 一个*是元组&#xff0c;两个是字典。