【导语】: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 regressbin/masscan --regressselftest: 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 Scanrate =  100000.00output-format = xmloutput-status = alloutput-filename = scan.xmlports = 0-65535range = 0.0.0.0-255.255.255.255excludefile = 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/1610.0.0.0/8172.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 等。