共计 8580 个字符,预计需要花费 22 分钟才能阅读完成。
【导语】:Masscan 是一个批量端口扫描器,程序运行在单机上,每秒传输 1 千万个数据包,能够在 6 分钟之内扫残缺个互联网。它是迄今为止,速度最快的端口扫描器。
简介
Masscan 的输入输出相似于 nmap,如果对工具的性能将信将疑,能够手动去尝试一把。
该工具应用异步传输,相似于 scanrand、unicornscan 和 ZMap 等扫描器。并且它更加灵便,容许自定义端口和 IP 地址范畴。
留神:masscan 应用它本人的 TCP/IP 栈,可能会和其余的端口扫描器抵触。这意味着,你要么应用 –src-ip 选项来配置一个与本地不同的 IP 地址,要么应用 –src-port 选项来配置 Massscan 应用的源端口。也能够配置外部防火墙(比方 pf 或者 iptables)将操作系统的其余端口墙在里面。
这个工具收费,然而大家的爱心捐助能够帮忙它更好的倒退;比特钱包地址如下:
1MASSCANaHUiyTtR3bJ2sLGuMw5kDBaj4T
我的项目地址:
https://github.com/robertdavi…
构建
在 Debian/Ubuntu,应用如下命令装置:
$ sudo apt-get install git gcc make libpcap-dev
$ git clone https://github.com/robertdavidgraham/masscan
$ cd masscan
$ make
Massscan 程序默认在 masscan/bin 子目录下。如果你想把这个程序安装在零碎的其余中央,例如 /usr/local/bin,须要本人手动复制。
该我的项目由大量的小文件组成,能够应用多线程来实现疾速构建:
$ make -j
尽管 Linux 是该工具的次要运行平台,然而它也能够在其余的操作系统上很好的运行。
上面是一些其余的构建信息:
- Windows w/ Visual Studio: 应用 VS10
- Windows w/ MingGW: 应用 make
- Windows w/ cygwin: 不反对
- Mac OS X /w XCode: 应用 XCode4
- Mac OS X /w cmdline: 应用 make
- FreeBSD: 应用 gmake
- 其余零碎: 尝试把所有的文件一起编译
PF\_RING 驱动装置
如果发包量要超过 20 万 / 秒,须要因特尔的网卡,网卡要求 10Gbps。除此之外,还须要一个驱动,名字叫 PF\_RING ZC。
要想应用 PF\_RING ZC,还须要装置上面的组件:
- libpfring.so (装置在 /usr/lib/libpfring.so)
- pf\_ring.ko (PF-RING 本人的内核驱动)
- ixgbe.ko (因特尔 10-gbps 网卡驱动)
此外,还须要构建 libpcap.so 文件。当 Masscan 探测到网卡为 zc:enp1s0 时,就会主动切换到 PF\_RING ZC 模式。
回归测试
这个工具内嵌自测组件,能够本人进行测试:
$ make regress
bin/masscan --regress
selftest: success!
以上的回归测试涵盖大量的简单代码,你应该在构建后再尝试。
性能测试
为了测试工具性能,能够执行上面的命令:
$ bin/masscan 0.0.0.0/4 -p80 --rate 100000000 --router-mac 66-55-44-33-22-11
选项 –router-mac 虚构进去一个假的路由 mac 地址,所以发送的数据包都在本地,不会跑到互联网上。
你也能够测试 offline 模式,看看在没有网络开销的状况下,这个程序能跑多快:
$ bin/masscan 0.0.0.0/4 -p80 --rate 100000000 --offline
在 offline 模式下,进行性能测试,这个程序就会应用 PF\_RING,简直没有网络开销。
工具的应用
这个工具应用相似 nmap。比方扫描某网段的一些端口:
# masscan -p80,8000-8100 10.0.0.0/8
以上的命令实现上面 3 个事件:
- 扫描 10.x.x.x 子网,一共 160 万地址
- 扫描端口 80,还有 8000-8100 范畴内的端口,一共 102 个
- 扫描后果能够输入到指定文件
应用 –echo,能够看到工具残缺的选项列表。命令会抛出以后配置并退出。这个输入也能够用作程序的输出。
# masscan -p80,8000-8100 10.0.0.0/8 --echo > xxx.conf
# masscan -c xxx.conf --rate 1000
banner 信息获取
Masscan 不仅能够探测端口的凋谢状态,它也能够实现 TCP 连贯以及和对应端口利用之间进行交互。通过跟应用程序交互,能够获取到简略的 banner 信息。
这是因为 masscan 领有本人的 TCP/IP 协定栈,跟程序所在操作系统的协定栈是不同的。当本地零碎接管到被探测指标的 SYN-ACK 包时,它会回应一个 RST 包。然而之前 masscan 为了获取 banner 信息而建设的连贯,会在此时敞开。
解决这个问题最简略的方法就是,为 masscan 指定一个 IP 地址。比方上面的命令:
# masscan 10.0.0.0/8 -p80 --banners --source-ip 192.168.1.200
这个指定的地址必须要在本地地址的子网中,否则不能在其余零碎上应用。
在一些场景中,比方 wifi,这种操作就不起作用了。在这些场景中,你也能够用防火墙来解决下面连贯中断的问题。防火墙会阻止本地的 TCP/IP 栈看到数据包,然而 masscan 依然是能够看到这个数据包的。例如,linux 下:
# iptables -A INPUT -p tcp --dport 61000 -j DROP
# masscan 10.0.0.0/8 -p80 --banners --source-port 61000
你能够通过批改配置文件,来解决 linux 和 masscan 端口抵触的问题。把 linux 应用的端口划定一个范畴:
/proc/sys/net/ipv4/ip_local_port_range
在 2018 年 8 月的 kali 中,这个范畴是 32768 to 60999,因而,抉择的端口应该在这些端口之外。
能够设置一个 iptables 规定,工夫限度到下次机器重启之前。如何保留这个配置取决于你的 linux 发行版。个别是用 iptables-save 或者是 iptables-persistant。
在 Mac OS X 和 BSD 上,也是相似的步骤。能够应用上面的命令来查找这个范畴:
# sysctl net.inet.ip.portrange.first net.inet.ip.portrange.last
在 FreeBSD 和更早的 Mac OS 版本上,应用如下的 ipfw 命令:
# sudo ipfw add 1 deny tcp from any to any 40000 in
# masscan 10.0.0.0/8 -p80 --banners --source-port 40000
在高于 MacOS X 版本还有 OpenBSAD 上,应用 pf 包过滤器。在 /etc/pf.conf 文件中退出上面一行:
block in proto tcp from any to any port 40000
而后启用防火墙,运行上面的命令:
# pfctrl -E
如果防火墙曾经启用,要么重启机器,要么应用上面的命令,从新导入这个规定:
# pfctl -f /etc/pf.conf
Window 不会回应 RST 包,以上的形式都是有效的。然而,masscan 依然能够应用它本人的 IP 地址很好的运行。因而,如果可能的话,你应该应用为 masscan 指定 IP 的办法。
对于比方像心脏滴血破绽(选项为 –heartbleed)的探测,也是 banner 信息探测的一种,是十分必要的。
如何扫描整个互联网
尽管 masscan 对于内网来说非常无效,然而当初设计也思考到了整个互联网。所以,它能够应用如下的命令,间接扫描整个互联网:
# masscan 0.0.0.0/0 -p0-65535
扫描整个互联网是不好的。一方面,有一部分被扫描的信息资产不会返回无效的信息。另一方面,一些站点会跟踪扫描,禁止你再拜访。因而,你要想扫描很多大量的地址,能够设置黑名单或者例外 IP 范畴。如下:
# masscan 0.0.0.0/0 -p0-65535 --excludefile exclude.txt
这只是把扫描后果输入到终端。如果你想把扫描后果保留到一个文件中,应用上面的命令:
# masscan 0.0.0.0/0 -p0-65535 -oX scan.xml
以上命令把扫描后果寄存到一个 XML 文件中。你也能够把扫描后果放进数据库。
然而,这仅仅是默认的扫描速率(100 个包 / 秒)。如果你想减速扫描,应用如下命令:
# masscan 0.0.0.0/0 -p0-65535 --max-rate 100000
下面的命令把扫描速率设置到了 10 万数据包 / 秒,这个设置扫描整个互联网的 IP,速率大略是每 10 个小时一个端口。如果想扫描整个端口,那就须要 655360 个小时。
以上所有的命令都跟 nmap 兼容。除此之外,还有一些隐形设置选项跟 nmap 也是一样的。例如:-sS,-Pn,-n,–randomize-hosts,–send-eth 等。同样的,扫描后果输入的 xml 文件也是跟 nmap 兼容的。
当然,masscan 跟 nmap 还有有很多不同的中央。实质上来说,masscan 是异步传输的实现形式,这导致它跟 nmap 有着根本性的区别。
以上命令行的形式比拟麻烦。上面有更简略的形式,就是把设置都保留在一个文件中。下面命令的中的设置写到文件中,如下:
# 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
启用以上配置:
# masscan -c myscan.conf
当你反复扫描时,以上的形式将会让扫描更加简略。
默认的,masscan 首次启动就会导入配置文件:/etc/masscan/masscan.conf。但之后的配置参数批改都会笼罩之前的默认文件。整个工作都是自动化实现的。
后果输入
默认的,masscan 会产生同样大小的文本文件。同时这个文件也能够很容易的转换成其余格局。上面有五种能够反对的格局:
- xml: 应用参数 -oX \<filename>. 或者应用参数 –output-format xml 和 –output-filename \<filename>.
- binary: 这是 masscan 内建指令. 它输入的文件更小, 扫描整个互联网能够用这个参数,不至于把硬盘塞满。它还须要解析. 命令选项 –readscan 将会读取这个二进制扫描文件。应用 –readscan 再搭配 -oX 选项就会输入一个 xml 的扫描后果文件。
- grepable: 这是 nmap 的 -oG 选项实现的,输入后果很容易被命令行工具解析。只须要应用参数 -oG \<filename> 或者应用 –output-format grepable 和 –output-filename \<filename>.
- json: 输入后果保留为 json,应用参数 -oJ \<filename> 或者 –output-format json 和 –output-filename \<filename>。
- list: 这是一个 list,每行一个 ip 和端口对儿。应用参数 -oL \<filename> 或者 –output-format list 和 –output-filename \<filename>. 格局是:
<port state> <protocol> <port number> <IP address> <POSIX timestamp>
open tcp 80 XXX.XXX.XXX.XXX 1390380064
与 Nmap 的比拟
只管 masscan 跟 nmap 从根本上来说是齐全不同的,然而开发者尽了最大的致力让 namp 的用户应用 masscan 时会感觉比拟相熟。上面是这两款工具之间最重要的两个不同点:
- 不指定默认扫描端口, 你必须明确扫描端口:-p \<ports>
- 指标主机是 IP 地址或者 IP 地址范畴, 而不是 DNS 名或者 nmap 应用的子网范畴(比方 10.0.0-255.0-255).
你能够认为 masscan 的以下选项是长期有效的:
-sS: 只进行 SYN 探测 (目前是这样, 未来会改良)
-Pn: 不首先 ping 主机,这是异步传输的根本要求
-n: 不进行 DNS 解析
–randomize-hosts: 齐全随机化扫描
–send-eth: 发送原生数据包如果你想理解其余和 nmap 兼容的设置,应用上面的命令:
# masscan --nmap
传输速率(重要!!!)
这个程序发送数据包十分快。在 windows 或者是虚拟机中,能够达到 30 万 / 秒的速率。在 linux(不是虚拟机)上,可达到 160 万 / 秒。速度快到能够捣毁大部分的网络。
留神,这个工具只能用来本人毁坏本人的网络。该工具在应用时随机抉择指标 IP,不应该用来毁坏任何一个近程网络。
默认的扫描速率是 100 数据包 / 秒。能够应用上面的选项来进步速率到一百万:–rate 1000000。
以下几局部将次要介绍 Masscan 的设计问题,帮忙你理解为什么本工具会有这么弱小的性能。感兴趣的同学,可持续往下浏览。
Code Layout
main.c 文件蕴含了 main()函数,也蕴含了 transmit\_thread()和 receive\_thread()函数。这些函数刻意写的比拟通俗易懂,且有大量的正文。你能够逐行浏览这些代码来理解这个程序的设计。
异步传输
masscan 是一个异步传输的设计。换句话说,它和 nmap 的关系就好比 nginx 和 apache 的关系。它的发送和接管线程是离开的,相互之间具备极大的独立性。在 scanrand, unicornscan 和 ZMap 中也有同样的设计。
因为它的异步性,包容许传输多块,该工具就能够运行多块。
随机抉择
Masscan 和其余扫描器之间一个最要害的区别在于它的指标地址是随机的。
最根本的准则是定义一个从 0 开始的索引变量,在每次探测时,每次减少 1。用 C 语言实现如下:
for (i = 0; i < range; i++) {scan(i);
}
还必须把索引翻译成 IP 地址。如果你想扫描所有的公有 IP,那么扫描范畴如下:
192.168.0.0/16
10.0.0.0/8
172.16.0.0/12
在这个例子中,前 64K 的索引对应的指标地址是 192.168.x.x。而后,起初的 160 万个索引对应的指标地址是 10.x.x.x。最初,其余的索引对应的指标地址范畴是 172.16.x.x。
下面的例子咱们只有 3 个范畴。当扫描整个互联网的时候,实际上会超过 100 个范畴。那是因为你必须设置黑名单还有很多排除在外的子网范畴。这个把想扫描的范畴宰割成了成百个更小的范畴。
这就导致程序运行变慢。咱们每秒传输 100 万个包,并且必须每次传输包和探测都须要将索引变量转换成 IP 地址。咱们通过应用二分法来解决这个问题,而且占用很少的内存。包传输在这种速率下,缓存效率开始影响算法效率。
实践上还存在大量更无效的技术手段,然而,在理论利用中,这些伎俩都因为占用过多内存而导致速度变的更慢。
咱们申明一个函数 pick(),用来实现把索引转换成 IP 地址。实现如下:
for (i = 0; i < range; i++) {ip = pick(addresses, i);
scan(ip);
}
Masscan 不仅反对 IP 范畴,也反对端口范畴。这意味着,咱们须要从 IP 地址和端口的索引变量中去拿 IP 和端口。上面是实现:
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 纳秒。当以 100 万包 / 秒的速率传输时,每个包仅仅只有 100 纳秒的工夫。我找不到更加优化的形式了。
侥幸的是,两个这样的操作能够同时进行。因而,做下面的两个运算不会比做一个减少累赘。
事实上,对于上述的运算问题,存在着更优的抉择。然而逐个减少索引变量要通过 C ++ 实现。实际上,咱们须要随机化这个变量。咱们要随机化指标 IP 地址的扫描程序,否则因为扫描速度过快,会毁坏指标网络。咱们要平均的将流量摊派到指标地址上。
咱们随机化的形式非常简单,就是加密索引变量。依据定义,加密是随机的,并且在原始的索引变量和输入之间减少一个一对一的 mapping。
这意味着,咱们线性的实现了这个范畴,然而输入的 IP 地址却是齐全随机的。代码实现如下:
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 的倍数,咱们就不能用比拟节约资源的二进制技术,比方 \& 和 ^。相同,咱们就必须应用 \% 操作符。在我以后的基准下,加密一个变量须要破费 40 纳秒的工夫。
这个架构容许很多比拟酷的个性。例如,反对分片。你能够抉择 5 个机器,每个机器设置五分之一的扫描,或者应用范畴数 / 分片数。
分片能够通过多台机器实现,或者单台机器多个网卡实现。如果你想,也能够在一个网卡上调配多个 IP 地址来实现分片。
或者,你也能够在加密函数上应用一个 seed 或一个 key,以此,每次扫描时,你能够失去一个不同的程序。比方 x = encrypt(seed, i)。
咱们也能够通过退出程序来暂停扫描,并且记住以后的 i 值,之后再重启扫描。在整个开发过程中,我做了很多。我留神到,在互联网扫描时,呈现了谬误,我就去终止扫描。而后在我修复 bug 后,再重启。
另一个特点就是重发。数据包在网络传输中有时会失落,因而你能够接连发两个包。然而,有时会呈现一个包失落,另一个紧跟着的包也失落的状况。
因而,你想要发送数据的二分之一的正本,这很简略。咱们有一个 rate 变量,这个变量是每秒钟传输数据包的数量,因而从新传输的函数就是在索引的根底上,简略用 i +rate 即可。
C10 扩大
异步传输技术因为解决了 C10K 问题而被熟知。Masscan 的设计是为了下一个量级扩大:C10M 问题。C10M 问题的解决形式就是绕过内核。在 Masscan 中,次要有三种内核绕过形式:
- 自定义网络驱动
- 用户模式 TCP 栈
- 用户模式异步传输
Masscan 能够应用 PF\_RING DNA 驱动器。这个驱动采纳间接内存拜访的形式传输数据包。数据包传输没有内核的干涉,间接从用户模式内存到网络驱动器。
这种形式容许软件以硬件可反对的最大速率传输数据包,即便是一个低速 CPU。如果一台电脑上有 8 个 10-gbps 个网卡,这意味着,你的传输速度能够达到一亿 / 秒。
Masscan 有它本人内建的 TCP 栈,这是为了能够从 TCP 连贯中获取 banner。这意味着如果电脑有足够的内存,它能够轻易的反对一百万并发的 TCP 连贯。
Masscan 没有互斥锁。古代的互斥锁 (aka. futexes) 次要是用户模式,然而他们都存在两个问题。
第一个问题是,他们造成了缓存链在 CPU 之间来回跳动;第二个问题是,当存在资源抢夺时,他们会做一个零碎申明,进入内核。这会杀掉性能。
互斥锁在程序的速度之路上,重大限度了程序的可扩展性。相同,Masscan 应用“环”来同步解决这个事件,比方,当用户模式下的 TCP 栈在接管一个线程时,这个线程传输的包不能被这个传输线程干预。
移植性
这个代码能够很好的在 linux,windows 还有 mac os X 上运行。所有重要位都基于 C90 规范。因而能够应用微软的 Visual Studio 编译。还能够应用 Clang/LLVM 在 Mac OS X 上编译,也能够用 GCC 在 linux 上实现编译。
windows 和 Mac 上不能设置传输包的数量,只能是默认值 30 万 / 秒,然而 linux 上能够做到 150 万 / 秒。不管怎样,都会比你设想中要快。
代码平安
该我的项目为脆弱性发现提供了奖金,具体信息查看文件 VULNINFO.md。
这个我的项目应用了平安函数 strcpy\_s(),strcpy()函数不平安。
这个我的项目有自动化单元回归测试。
兼容性
为了让每个应用端口扫描的人都有种相熟的感觉,该工具的开发中做了很多的致力,让它的输出 / 输入更像是 nmap。
作者
这个工具由 Robert Graham 开发。
邮箱: robert\_david\_graham\@yahoo.com
twitter: \@ErrataRob
我的项目地址:
https://github.com/robertdavi…
开源前哨
日常分享热门、乏味和实用的开源我的项目。参加保护 10 万 + Star 的开源技术资源库,包含:Python、Java、C/C++、Go、JS、CSS、Node.js、PHP、.NET 等。