Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
masscan — TCP端口扫描器,异步发送SYN数据包,可在5分钟内扫描整个互联网。 | Kitploit
工具/GitHubGitHub/robertdavidgraham/masscan
侦察网络映射端口扫描信息收集渗透测试
GitHubrobertdavidgraham/masscan

masscan

TCP端口扫描器,异步发送SYN数据包,可在5分钟内扫描整个互联网。

查看仓库
25.9k3.2k3个月前Kitploit 审核通过

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

unittests

MASSCAN: 大规模IP端口扫描器

这是一个互联网规模的端口扫描器。它可以在5分钟内扫描整个互联网,从单台机器以每秒1000万个数据包的速率进行传输。

其用法(参数、输出)与最著名的端口扫描器 nmap 类似。如有疑问,可以尝试其中的某些功能——它支持对大量机器进行广泛扫描,但不支持对单台机器进行深度扫描。

内部采用异步传输方式,类似于 scanrand、unicornscan 和 ZMap 等端口扫描器。它更加灵活,允许任意端口和地址范围。

注意:masscan 使用自己的临时 TCP/IP 协议栈。任何超出简单端口扫描的操作都可能与本地 TCP/IP 协议栈发生冲突。这意味着你需要使用 --src-ip 选项从不同的 IP 地址运行,或者使用 --src-port 配置 masscan 使用的源端口,然后配置内部防火墙(如 pf 或 iptables)将这些端口与操作系统的其余部分隔离。

本工具是免费的,但请考虑为其开发捐款: 比特币钱包地址:1MASSCANaHUiyTtR3bJ2sLGuMw5kDBaj4T

构建

在 Debian/Ubuntu 上,操作大致如下。除了 C 编译器(如 gcc 或 clang)外,它实际上没有任何依赖。

root@kitploit:~
sudo apt-get --assume-yes install git make gcc
git clone https://github.com/robertdavidgraham/masscan
cd masscan
make

这会将程序放在 masscan/bin 子目录中。要安装它(在 Linux 上),请运行:

root@kitploit:~
make install

源代码包含大量小文件,因此通过多线程构建可以大大加快速度。但在树莓派上这需要超过 2GB 内存(并且会崩溃),所以你可能要使用较小的数字,比如 -j4,而不是所有可能的线程。

root@kitploit:~
make -j

虽然 Linux 是主要目标平台,但代码在许多其他系统(Windows、macOS 等)上也运行良好。以下是一些额外的构建信息:

  • Windows w/ Visual Studio:使用 VS10 项目
  • Windows w/ MinGW:只需输入 make
  • Windows w/ cygwin:无法工作
  • Mac OS X /w XCode:使用 XCode4 项目
  • Mac OS X /w 命令行:只需输入 make
  • FreeBSD:输入 gmake
  • 其他:尝试直接编译所有文件,cc src/*.c -o bin/masscan

在 macOS 上,x86 二进制文件在 ARM 模拟下似乎也能以相同速度运行。

用法

用法类似于 nmap。扫描某个网段的特定端口:

root@kitploit:~
# masscan -p80,8000-8100 10.0.0.0/8 2603:3001:2d00:da00::/112

这将:

  • 扫描 10.x.x.x 子网和 2603:3001:2d00:da00::x 子网
  • 在两个子网上扫描端口 80 以及 8000 到 8100 的范围,总共 102 个端口
  • 将输出打印到 <stdout>,可重定向到文件

要查看完整选项列表,请使用 --echo 功能。这会转储当前配置并退出。该输出可作为输入重新输入程序:

root@kitploit:~
# masscan -p80,8000-8100 10.0.0.0/8 2603:3001:2d00:da00::/112 --echo > xxx.conf
# masscan -c xxx.conf --rate 1000

Banner 检查

Masscan 不仅能检测端口是否开放。它还能完成 TCP 连接并与该端口的应用程序进行交互,以获取简单的“横幅”(banner)信息。

Masscan 支持以下协议的 banner 检查:

  • FTP
  • HTTP
  • IMAP4
  • memcached
  • POP3
  • SMTP
  • SSH
  • SSL
  • SMBv1
  • SMBv2
  • Telnet
  • RDP
  • VNC

问题在于 masscan 包含自己的 TCP/IP 协议栈,与运行它的系统分离。当本地系统收到来自探测目标的 SYN-ACK 时,它会用 RST 数据包回复,在 masscan 获取 banner 之前切断连接。

防止这种情况最简单的方法是为 masscan 分配一个独立的 IP 地址。示例如下:

root@kitploit:~
# masscan 10.0.0.0/8 -p80 --banners --source-ip 192.168.1.200
  # masscan 2a00:1450:4007:810::/112 -p80 --banners --source-ip 2603:3001:2d00:da00:91d7:b54:b498:859d

你选择的地址必须在本地子网上,且未被其他系统使用。Masscan 会警告你犯了错,但你可能会扰乱其他机器的通信几分钟,所以请小心。

在某些情况下(例如 WiFi),这不可行。这时你可以将 masscan 使用的端口加入防火墙。这会阻止本地 TCP/IP 协议栈看到数据包,但 masscan 仍然能看到,因为它绕过了本地协议栈。在 Linux 上,操作如下:

root@kitploit:~
# iptables -A INPUT -p tcp --dport 61000 -j DROP
# masscan 10.0.0.0/8 -p80 --banners --source-port 61000

你可能希望选择不与 Linux 可能选择的源端口范围冲突的端口。你可以通过查看以下文件来了解 Linux 使用的范围并重新配置该范围:

root@kitploit:~
/proc/sys/net/ipv4/ip_local_port_range

在最新版本的 Kali Linux(2018年8月)中,该范围是 32768 到 60999,因此你应该选择低于 32768 或高于 61000 的端口。

设置 iptables 规则只持续到下次重启。你需要查找如何根据你的发行版保存配置,例如使用 iptables-save 和/或 iptables-persistent。

在 Mac OS X 和 BSD 上,步骤类似。要找出避免的范围,请使用如下命令:

root@kitploit:~
# sysctl net.inet.ip.portrange.first net.inet.ip.portrange.last

在 FreeBSD 和旧版 macOS 上,使用 ipfw 命令:

root@kitploit:~
# sudo ipfw add 1 deny tcp from any to any 40000 in
# masscan 10.0.0.0/8 -p80 --banners --source-port 40000

在新版 macOS 和 OpenBSD 上,使用 pf 数据包过滤工具。编辑文件 /etc/pf.conf 添加如下一行:

root@kitploit:~
block in proto tcp from any to any port 40000:40015

然后启用防火墙,运行命令:

root@kitploit:~
# pfctl -E    

如果防火墙已经在运行,则重新启动或使用以下命令重新加载规则:

root@kitploit:~
# pfctl -f /etc/pf.conf

Windows 不会响应 RST 数据包,因此这些技术都不必要。不过,masscan 仍然设计为最好使用自己的 IP 地址运行,因此即使不是严格必要,也请尽可能以这种方式运行。

其他检查(如 --heartbleed 检查,它只是 banner 检查的一种形式)也需要同样的处理。

如何扫描整个互联网

虽然对小规模内部网络有用,但该程序实际上是针对整个互联网设计的。可能类似于这样:

root@kitploit:~
# masscan 0.0.0.0/0 -p0-65535

扫描整个互联网是有害的。一方面,部分互联网对扫描反应不好。另一方面,有些站点会跟踪扫描并将你加入黑名单,导致你被防火墙阻挡在有用的互联网部分之外。因此,你需要排除很多范围。要黑名单或排除范围,请使用以下语法:

root@kitploit:~
# masscan 0.0.0.0/0 -p0-65535 --excludefile exclude.txt

这只会将结果打印到命令行。你可能希望将结果保存到文件。因此,你需要类似这样的命令:

root@kitploit:~
# masscan 0.0.0.0/0 -p0-65535 -oX scan.xml

这会将结果保存为 XML 文件,方便你将结果导入数据库等。

但是,这仅以默认速率 100 数据包/秒运行,扫描互联网将花费很长时间。你需要加速,如下所示:

root@kitploit:~
# masscan 0.0.0.0/0 -p0-65535 --max-rate 100000

这将速率提高到 100,000 数据包/秒,扫描整个互联网(排除除外)大约需要每个端口 10 小时(如果扫描所有端口,则需要 655,360 小时)。

关于此命令需要注意的一点是,所有这些选项都与 nmap 兼容。此外,还会为你自动设置与 nmap 兼容的“隐形”选项:-sS -Pn -n --randomize-hosts --send-eth。同样,XML 文件的格式也受到 nmap 的启发。当然,存在许多差异,因为程序的异步性质导致了对该问题的根本不同处理方式。

上面的命令行有点繁琐。与其将所有内容放在命令行上,不如将其存储在文件中。上面的设置如下所示:

root@kitploit:~
# My Scan
rate =  100000.00
output-format = xml
output-status = all
output-filename = scan.xml
ports = 0-65535
range = 0.0.0.0-255.255.255.255
excludefile = exclude.txt

要使用此配置文件,请使用 -c:

root@kitploit:~
# masscan -c myscan.conf

当你重复扫描时,这也会使事情变得更容易。

默认情况下,masscan 首先加载配置文件 /etc/masscan/masscan.conf。后面的任何配置参数都会覆盖该默认配置文件中的参数。我在那里设置了我的 "excludefile" 参数,这样我就永远不会忘记它。它会自动生效。

获取输出

默认情况下,masscan 生成相当大的文本文件,但很容易将它们转换为任何其他格式。支持五种输出格式:

  1. xml:只需使用参数 -oX <filename>。 或使用参数 --output-format xml 和 --output-filename <filename>。

  2. binary:这是 masscan 内置格式。它生成更小的文件,这样当我扫描互联网时,我的磁盘不会填满。不过它们需要解析。命令行选项 --readscan 可以读取二进制扫描文件。使用 --readscan 配合 -oX 选项可以生成结果文件的 XML 版本。

  3. grepable:这是 Nmap -oG 输出的实现,可以轻松被命令行工具解析。只需使用参数 -oG <filename>。或使用参数 --output-format grepable 和 --output-filename <filename>。

  4. json:以 JSON 格式保存结果。只需使用参数 -oJ <filename>。或使用参数 --output-format json 和 --output-filename <filename>。

  5. list:这是一个简单的列表,每行包含一个主机和端口对。只需使用参数 -oL <filename>。或使用参数 和 。格式为:

与 Nmap 的比较

在合理的情况下,我们尽力使程序对 nmap 用户感到熟悉,尽管它根本不同。Masscan 针对大量机器的广泛范围扫描进行了调优,而 nmap 则针对单台机器或小范围的密集扫描而设计。

两个重要的区别是:

  • 没有默认扫描端口,你必须指定 -p <ports>
  • 目标主机是 IP 地址或简单的范围,不是 DNS 名称,也不是 nmap 可以使用的古怪子网范围(如 10.0.0-255.0-255)。

你可以认为 masscan 永久启用了以下设置:

  • -sS:只进行 SYN 扫描(目前如此,将来可能会改变)
  • -Pn:不先 ping 主机,这是异步操作的基础
  • -n:不进行 DNS 解析
  • --randomize-hosts:始终完全随机化扫描,你无法更改
  • --send-eth:使用原始 libpcap 发送

如果你想要更多与 nmap 兼容的设置列表,请使用以下命令:

root@kitploit:~
# masscan --nmap

传输速率(重要!!)

此程序非常快速地发送数据包。在 Windows 或虚拟机上,它可以达到 300,000 数据包/秒。在 Linux(无虚拟化)上,它将达到 160 万数据包/秒。这足以熔化大多数网络。

请注意,它只会熔化你自己的网络。它会随机化目标 IP 地址,因此不应压倒任何远程网络。

默认情况下,速率设置为 100 数据包/秒。要将速率提高到一百万,请使用类似 --rate 1000000 的命令。

在扫描 IPv4 互联网时,你会扫描许多子网,因此即使有大量数据包发出,每个目标子网只会收到少量传入数据包。

然而,在 IPv6 扫描中,你往往会专注于单个包含数十亿地址的目标子网。因此,你的默认行为会压垮目标网络。网络在 masscan 生成的负载下经常崩溃。

设计

本节描述程序的主要设计问题。

代码布局

文件 main.c 包含 main() 函数,正如你所料。它还包含 transmit_thread() 和 receive_thread() 函数。这些函数被故意展平并添加了详细注释,这样你可以通过逐行逐步执行每个函数来阅读程序的设计。

异步

这是一种异步设计。换句话说,它对 nmap 而言,就像 nginx Web 服务器对 Apache 一样。它有独立的发送和接收线程,彼此大致独立。与 scanrand、unicornscan 和 ZMap 中的设计相同。

由于是异步的,它的运行速度取决于底层数据包传输允许的速度。

随机化

Masscan 与其他扫描器的一个关键区别在于它随机化目标的方式。

基本原则是有一个从零开始的单一索引变量,每次探测递增 1。在 C 代码中,这表示为:

root@kitploit:~
for (i = 0; i < range; i++) {
    scan(i);
}

我们必须将索引转换为 IP 地址。假设你想扫描所有“私有”IP 地址。那将是以下范围表:

root@kitploit:~
192.168.0.0/16
10.0.0.0/8
172.16.0.0/12

在此示例中,前 64k 索引附加到 192.168.x.x 形成目标地址。然后,接下来的 1600 万个索引附加到 10.x.x.x。该范围内的剩余索引应用于 172.16.x.x。

在这个例子中,我们只有三个范围。在扫描整个互联网时,我们实际上有超过 100 个范围。这是因为你必须黑名单或排除许多子范围。这将所需的范围分割成数百个较小的范围。

这导致了代码中最慢的部分之一。我们每秒传输 1000 万个数据包,并且必须为每个探测将索引变量转换为 IP 地址。我们通过在少量内存中进行“二分查找”来解决这个问题。在这个数据包速率下,缓存效率开始主导算法效率。理论上有很多更高效的技术,但它们都需要如此多的内存以至于在实践中更慢。

我们将从索引转换为 IP 地址的函数称为 pick() 函数。在使用中,它看起来像:

root@kitploit:~
for (i = 0; i < range; i++) {
    ip = pick(addresses, i);
    scan(ip);
}

Masscan 不仅支持 IP 地址范围,还支持端口范围。这意味着我们需要从索引变量中同时选择一个 IP 地址和一个端口。这相当直接:

root@kitploit:~
range = ip_count * port_count;
for (i = 0; i < range; i++) {
    ip   = pick(addresses, i / port_count);
    port = pick(ports,     i % port_count);
    scan(ip, port);
}

这导致了代码中另一个昂贵的部分。在 x86 CPU 上,除法/取模指令大约需要 90 个时钟周期,或 30 纳秒。当以每秒 1000 万个数据包的速率传输时,每个数据包只有 100 纳秒。我看不到任何更好的优化方法。幸运的是,两个这样的操作可以同时执行,因此像上面那样执行两个操作并不比执行一个更昂贵。

实际上,上述性能问题有一些简单的优化,但都依赖于 i++,即索引变量在扫描过程中逐个递增的事实。实际上,我们需要随机化这个变量。我们需要随机化扫描的 IP 地址顺序,否则我们会猛烈冲击那些不具备这种速度能力的目标网络。我们需要将流量均匀分布到目标上。

我们随机化的方法就是加密索引变量。根据定义,加密是随机的,并在原始索引变量和输出之间创建一一对应关系。这意味着当我们线性遍历范围时,输出的 IP 地址是完全随机的。在代码中,这看起来像:

root@kitploit:~
range = ip_count * port_count;
for (i = 0; i < range; i++) {
    x = encrypt(i);
    ip   = pick(addresses, x / port_count);
    port = pick(ports,     x % port_count);
    scan(ip, port);
}

这也有很大的代价。由于范围是不可预测的大小,而不是一个整齐的 2 的幂,我们不能使用廉价的二进制技术如 AND (&) 和 XOR (^)。相反,我们必须使用昂贵的操作如 MODULUS (%)。在我当前的基准测试中,加密变量需要 40 纳秒。

这种架构允许许多很酷的功能。例如,它支持“分片”(shards)。你可以设置 5 台机器,每台完成扫描的 1/5 或 range / shard_count。分片可以是多台机器,也可以是同一台机器上的多个网络适配器,甚至(如果你愿意)是同一网络适配器上的多个 IP 源地址。

或者,你可以对加密函数使用 'seed' 或 'key',这样每次扫描都会得到不同的顺序,例如 x = encrypt(seed, i)。

我们还可以通过退出程序来暂停扫描,只需记住 i 的当前值,然后稍后重新启动。我在开发过程中经常这样做。我发现互联网扫描出现问题,就按 停止扫描,修复 bug 后重新启动。

另一个功能是重传/重试。数据包有时会在互联网上丢失,因此你可以背靠背发送两个数据包。但是,丢弃一个数据包的东西可能会丢弃紧随其后的数据包。因此,你希望在大约 1 秒后发送副本。这很简单。我们已经有了一个 'rate' 变量,即我们发送的每秒数据包数,因此重传函数只需使用 i + rate 作为索引。总有一天,我会对互联网进行研究,并以这种方式区分“背靠背”、“1 秒”、“10 秒”和“1 分钟”重传,看看丢弃有什么不同。

C10 可扩展性

异步技术被称为解决“c10k 问题”的方法。Masscan 是为下一个级别的可扩展性设计的,即“C10M 问题”。

C10M 解决方案是绕过内核。Masscan 中有三种主要的绕过内核方式:

  • 自定义网络驱动
  • 用户态 TCP 栈
  • 用户态同步

Masscan 可以使用 PF_RING DNA 驱动。该驱动直接将数据包从用户态内存 DMA 到网络驱动,无需内核参与。这使得软件(即使是慢速 CPU)能够以硬件允许的最大速率传输数据包。如果你在一台计算机上安装 8 块 10 Gbps 网卡,这意味着它可以以每秒 1 亿个数据包的速率传输。

Masscan 有自己内置的 TCP 栈,用于从 TCP 连接中获取 banner。这意味着它可以轻松支持 1000 万个并发 TCP 连接,当然前提是计算机有足够的内存。

Masscan 没有“互斥锁”。现代互斥锁(又名 futex)大部分是用户态的,但它们有两个问题。第一个问题是它们会导致缓存行在 CPU 之间快速来回反弹。第二个问题是当存在争用时,它们会执行系统调用进入内核,这会影响性能。在程序快速路径上的互斥锁严重限制了可扩展性。相反,Masscan 使用“环”(rings)来同步事物,例如当接收线程中的用户态 TCP 栈需要发送数据包而不干扰发送线程时。

可移植性该代码在 Linux、Windows 和 Mac OS X 上运行良好。所有重要部分都使用标准 C(C90)编写。因此,它可以使用 Microsoft 的编译器在 Visual Studio 上编译,在 Mac OS X 上使用 Clang/LLVM 编译器,在 Linux 上使用 GCC 编译。

Windows 和 Mac 系统对数据包发送的优化有限,仅能达到约 300,000 数据包/秒,而 Linux 可以做到 1,500,000 数据包/秒。这可能已经超出您的需求。

安全代码

本项目针对漏洞提供赏金,更多信息请参阅 VULNINFO.md 文件。

本项目使用安全函数,如 safe_strcpy(),而非不安全的 strcpy() 等函数。

本项目包含自动化单元回归测试(make regress)。

兼容性

为了确保输入/输出与 nmap 相似——每个进行端口扫描的人(或应该)都熟悉它——我们投入了大量精力。

IPv6 与 IPv4 共存

Masscan 支持 IPv6,但未提供特殊模式,两者同时受支持。(没有 -6 选项——IPv6 始终可用)。

在 masscan 用法的任何示例中,只需将 IPv6 地址放在您看到 IPv4 地址的位置。您可以在同一次扫描中同时包含 IPv4 和 IPv6 地址。输出会在相同位置包含相应地址,没有特殊标记。

请记住,IPv6 地址空间非常大。您可能不想扫描大范围,除非是子网中通过 DHCPv6 分配的前 64k 个地址。

相反,您可能更希望扫描从其他来源获取的大型地址列表,这些地址存储在文件中(--include-file filename.txt)。与其他地方一样,此文件可以包含 IPv4 和 IPv6 地址的列表。我使用的测试文件包含 800 万个地址。这种大小的文件在启动时读取需要额外几秒钟(masscan 会在扫描前对地址进行排序并去除重复项)。

请记住,masscan 包含自己的网络栈。因此,运行 masscan 的本地机器不需要启用 IPv6——尽管本地网络需要能够路由 IPv6 数据包。

PF_RING

要突破 200 万数据包/秒,您需要 Intel 10-gbps 以太网适配器和 来自 ntop 的“PF_RING ZC” 专用驱动。Masscan 无需重新编译即可使用 PF_RING。要使用 PF_RING,您需要构建以下组件:

  • libpfring.so(安装在 /usr/lib/libpfring.so)
  • pf_ring.ko(他们的内核驱动)
  • ixgbe.ko(他们的 Intel 10-gbps 以太网驱动版本)

您不需要构建他们的 libpcap.so 版本。

当 Masscan 检测到适配器名称类似 zc:enp1s0 而非 enp1s0 时,它会自动切换到 PF_RING ZC 模式。

更详细的讨论请参阅 PoC||GTFO 0x15。

回归测试

项目包含内建单元测试:

root@kitploit:~
$ make test
bin/masscan --selftest
selftest: success!

这会测试代码中许多棘手的部分。建议在构建后执行此测试。

性能测试

要测试性能,请对临时地址运行类似以下命令,以避免使本地路由器过载:

root@kitploit:~
$ bin/masscan 0.0.0.0/4 -p80 --rate 100000000 --router-mac 66-55-44-33-22-11

虚假的 --router-mac 将数据包限制在本地网络段内,以免它们发往互联网。

您还可以在“离线”模式下测试,即程序在没有发送开销时的运行速度:

root@kitploit:~
$ bin/masscan 0.0.0.0/4 -p80 --rate 100000000 --offline

第二个基准测试大致显示了程序在使用 PF_RING(几乎无开销)时的运行速度。

顺便提一下,随机化算法大量使用了“整数算术”——CPU 上一种长期缓慢的操作。现代 CPU 将此计算的速度提升了一倍,使 masscan 更快。

作者

该工具由 Robert Graham 创建: 电子邮件:[email protected] 推特:@ErrataRob

许可证

版权所有 (c) 2013 Robert David Graham

此程序是自由软件:您可以重新分发和/或修改它,但必须遵守由自由软件基金会发布的 GNU Affero 通用公共许可证第 3 版的规定。

分发此程序的目的是希望它有用,但不提供任何担保;甚至没有对适销性或特定用途适用性的暗示担保。更多详情请参阅 GNU Affero 通用公共许可证。

您应该已随此程序收到一份 GNU Affero 通用公共许可证副本。如果没有,请访问 https://www.gnu.org/licenses/。

下载工具
--output-format list
--output-filename <filename>
root@kitploit:~
<port state> <protocol> <port number> <IP address> <POSIX timestamp>  
open tcp 80 XXX.XXX.XXX.XXX 1390380064