欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

端口扫描软件有哪些(手机扫描软件排行榜)

程序员文章站 2024-03-29 11:11:40
这是一个端口扫描器。理论上它可以在 5 分钟内扫描整个 internet,从一台机器每秒传输 1000 万个数据包。它的用法(参数、输出)类似于nmap端口扫描器。支持对多台机器进行广泛扫描,但不支持...

这是一个端口扫描器。理论上它可以在 5 分钟内扫描整个 internet,从一台机器每秒传输 1000 万个数据包。

它的用法(参数、输出)类似于nmap端口扫描器。支持对多台机器进行广泛扫描,但不支持对单台机器进行深入扫描。

在内部,它采用异步传输,像类似于端口扫描器 scanrand,unicornscan和zmap。它更灵活,允许任意端口和地址范围。

注意: masscan 使用它自己的ad hoc tcp/ip 堆栈。除了简单的端口扫描之外的任何其他操作都可能导致与本地 tcp/ip 堆栈发生冲突。也就是说需要使用–src-ip从不同 ip 地址运行的选项,或用于–src-port配置 masscan 使用的源端口,然后还配置内部防火墙(如pf或iptables)以将这些端口与操作系统的其余部分隔开。


安装

除了 c 编译器(例如gcc 或clang)之外,它实际上没有任何依赖项。

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

二进制在masscan/bin子目录中。

make install

源代码由许多小文件组成,因此使用多线程构建可以加快构建速度。

make -j

用法

用法类似于nmap. 要扫描某些端口的网段:

# 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功能。这将转储当前配置并退出。此输出可用作返回到程序的输入:

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

横幅信息

masscan 可以做的不仅仅是检测端口是否打开。它还可以在该端口完成与应用程序的 tcp 连接和交互,以获取简单的“横幅”信息。

masscan 支持以下协议的横幅检查:

  • ftp
  • http
  • imap4
  • memcached
  • pop3
  • smtp
  • ssh
  • ssl
  • smbv1
  • smbv2
  • telnet
  • rdp
  • vnc

问题是masscan 包含自己的 tcp/ip 堆栈,与系统分开。当本地系统收到来自探测目标的 syn-ack 时,它会响应一个 rst 数据包,在 masscan 获取横幅之前终止连接。

防止这种情况的最简单方法是为 masscan 分配一个单独的 ip 地址。这将类似于以下示例之一:

# 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,这看起来像:

# iptables -a input -p tcp --dport 61000 -j drop
# masscan 10.0.0.0/8 -p80 --banners --source-port 61000

您可能希望选择与 linux 可能为源端口选择的端口不冲突的端口。您可以查看 linux 使用的范围,并通过查看文件重新配置该范围:

/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 上,有类似的步骤。要找出要避免的范围,请使用如下命令:

# sysctl net.inet.ip.portrange.first net.inet.ip.portrange.last

在 freebsd 和较旧的 macos 上,使用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 和 openbsd 上,使用pf包过滤实用程序。编辑文件/etc/pf.conf以添加如下一行:

block in proto tcp from any to any port 40000

然后要启用防火墙,请运行以下命令:

# pfctrl -e    

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

# pfctl -f /etc/pf.conf

windows 不响应 rst 数据包,因此这两种技术都不是必需的。然而,masscan 仍然被设计为使用它自己的 ip 地址最好地工作,所以你应该尽可能地以这种方式运行,即使它不是绝对必要的。

其他检查也需要同样的事情,例如–heartbleed检查,这只是横幅检查的一种形式。


如何扫描整个互联网

虽然对于较小的内部网络很有用,但该程序的设计确实考虑到了整个 internet。它可能看起来像这样:

# masscan 0.0.0.0/0 -p0-65535

扫描整个互联网是体验糟糕的。一方面,互联网的某些部分对被扫描的反应很差。另一方面,某些站点会跟踪扫描并将您添加到禁止列表中,这将使您免受 internet 有用部分的影响。因此,您要排除很多范围。要将范围列入黑名单或排除范围,您需要使用以下语法:

# masscan 0.0.0.0/0 -p0-65535 --excludefile exclude.txt

这只是将结果打印到命令行。您可能希望将它们保存到文件中。因此,您需要类似的东西:

# masscan 0.0.0.0/0 -p0-65535 -ox scan.xml

这会将结果保存在 xml 文件中,让您可以轻松地将结果转储到数据库或其他内容中。

但是,这仅以 100 个数据包/秒的默认速率进行,这将花费很长时间来扫描 internet。你需要加快速度:

# masscan 0.0.0.0/0 -p0-65535 --max-rate 100000

这将速率提高到 100,000 个数据包/秒,这将在每个端口大约 10 小时(如果扫描所有端口则为 655,360 小时)内扫描整个 internet(不包括)。


与 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: 使用 raw 发送 libpcap

如果您需要其他nmap兼容设置的列表,请使用以下命令:

# masscan --nmap

传输速率(重要!!)

这个程序非常快地发出数据包。在 windows 或 vm 上,它可以每秒处理 300,000 个数据包。在 linux(无虚拟化)上,它将每秒处理 160 万个数据包。这速度足以融化大多数网络。

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

扫描 ipv4 internet 时,您将扫描大量子网,因此即使有很高的数据包出去率,每个目标子网也会收到少量传入数据包。

但是,通过 ipv6 扫描,您将倾向于关注具有数十亿个地址的单个目标子网。因此,您的默认行为将淹没目标网络。网络经常在 masscan 产生的负载下崩溃。


怎么设计的

代码布局

文件main.c包含该main()函数。它还包含transmit_thread()和receive_thread()功能。这些函数已被故意扁平化并进行了大量注释,以便您可以通过逐行逐行浏览每个函数来阅读程序的设计。

异步

这是一个异步设计。它具有独立的发送和接收线程,这些线程在很大程度上彼此独立。

因为它是异步的,所以它的运行速度与底层数据包传输允许的一样快。

随机化

masscan 与其他扫描仪的主要区别在于它随机化目标的方式。

基本原则是有一个从零开始的单个索引变量,每次探测都增加 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.xx 以形成目标地址。然后,将接下来的 1600 万附加到 10.xxx 范围内的其余索引应用到 172.16.xx

在这个例子中,我们只有三个范围。在扫描整个 internet 时,我们实际上有 100 多个范围。那是因为您必须将许多子范围列入黑名单或排除在外。这将所需的范围切成数百个较小的范围。

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

我们将把索引转换成 ip 地址的pick()函数。在使用中,它看起来像:

for (i = 0; i < range; i++) {
    ip = pick(addresses, i);
    scan(ip);
}

masscan 不仅支持 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 纳秒。当以 1000 万个数据包/秒的速率传输时,我们每个数据包只有 100 纳秒。我认为没有办法更好地优化它。幸运的是,两个这样的操作可以同时执行,因此执行其中两个操作(如上所示)并不比执行一个更昂贵。

对于上面的性能问题其实有一些简单的优化,但是都依赖于i++索引变量增加。实际上,我们需要随机化这个变量。我们需要随机化我们扫描的 ip 地址的顺序。我们需要将流量均匀地分布在目标上。

随机化的方式是简单地加密索引变量。根据定义,加密是随机的,并在原始索引变量和输出之间创建一对一的映射。这意味着当我们线性地遍历范围时,输出的 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 的偶次幂,因此我们不能使用廉价的二进制技术,如 and (&) 和 xor (^)。相反,我们必须使用昂贵的操作,例如 modulus (%)。在我当前的基准测试中,加密变量需要 40 纳秒。

这种架构允许许多很酷的功能。例如,它支持“分片”。您可以设置 5 台机器,每台机器执行五分之一的扫描或 range / shard_count. 分片可以是多台机器,也可以是同一台机器上的多个网络适配器,甚至(如果需要)同一网络适配器上的多个 ip 源地址。

或者,您可以对加密函数使用“种子”或“密钥”,以便每次扫描时获得不同的顺序,例如x = encrypt(seed, i).

我们还可以通过退出程序来暂停扫描,只需记住 的当前值i,稍后再重新启动。我在开发过程中经常这样做。我发现 internet 扫描出现问题,所以我点击停止扫描,然后在修复错误后重新启动它。

另一个功能是重传/重试。数据包有时会在 internet 上丢失,因此您可以背靠背发送两个数据包。然而,丢弃一个数据包的东西可能会丢弃紧随其后的数据包。因此,您希望将副本发送间隔约 1 秒。我们已经有一个“速率”变量,它是我们正在传输的每秒数据包数,因此重新传输函数只是i + rate 用作索引。


c10 可扩展性

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

c10m 解决方案是绕过内核。在 masscan 中有三个主要的内核旁路:

  • 自定义网络驱动程序
  • 用户模式 ​tcp 堆栈
  • 用户模式同步

masscan 可以使用 pf_ring dna 驱动程序。此驱动程序 dma 将数据包直接从用户模式内存发送到网络驱动程序,而零内核参与。这允许软件,即使 cpu 速度较慢,也能以硬件允许的最大速率传输数据包。如果将 8 个 10-gbps 网卡放入计算机,这意味着它可以以 1 亿个数据包/秒的速度传输。

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

masscan 没有“互斥锁”。现代互斥体(又名 futexes)大多是用户模式的,但它们有两个问题。第一个问题是它们导致缓存行在 cpu 之间快速来回反弹。第二个是当存在争用时,他们会对内核进行系统调用,这会降低性能。程序快速路径上的互斥锁严重限制了可扩展性。相反,masscan 使用“环”来同步事物,例如当接收线程中的用户模式 ​​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 个数据包。无论如何,这可能比您想要的要快。


安全

该项目使用安全函数,strcpy_s()而不是像strcpy().

该项目具有自动单元回归测试 ( make regress)。


ipv6 和 ipv4 共存

masscan 支持 ipv6,但没有特殊模式,两者同时支持。

在任何使用 masscan 的示例中,只需将 ipv6 地址放在您看到 ipv4 地址的位置。您可以在同一扫描中同时包含 ipv4 和 ipv6 地址。输出包括相同位置的适当地址,没有特殊标记。

ipv6 地址空间非常大。您可能不想扫描大范围,除了dhcpv6 分配的子网的前 64k 个地址。

您可能希望扫描存储在–include-file filename.txt从其他来源获得的文件 ( )中的大量地址列表。该文件可以包含 ipv4 和 ipv6 地址的列表。使用的测试文件包含 800 万个地址。这种大小的文件在启动时需要额外的几秒钟才能读取(masscan 在扫描前对地址进行排序并删除重复项)。

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


pf_ring

要超过 200 万个数据包/秒,您需要一个英特尔 10-gbps 以太网适配器和一个来自 ntop 的称为“pf_ring zc”的特殊驱动程序。为了使用 pf_ring,不需要重建 masscan。要使用 pf_ring,需要构建以下组件:

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

当 masscan 检测到一个适配器被命名为类似zc:enp1s0而不是类似的名称时enp1s0,它会自动切换到 pf_ring zc 模式。


回归测试

该项目包含一个内置的单元测试:

$ make test
bin/masscan --selftest
selftest: success!

这测试了代码的许多棘手部分。您应该在构建后执行此操作。


性能测试

要测试性能,请对不用的地址运行以下类似操作,以避免本地路由器过载:

$ bin/masscan 0.0.0.0/4 -p80 --rate 100000000 --router-mac 66-55-44-33-22-11

伪造者–router-mac将数据包保留在本地网段上,这样它们就不会传到 internet 上。

您还可以在“离线”模式下进行测试,这是程序在没有传输开销的情况下运行的速度:

$ bin/masscan 0.0.0.0/4 -p80 --rate 100000000 --offline

第二个基准测试大致显示了如果使用 pf_ring 时程序的运行速度,它的开销接近于零。

顺便说一下,随机化算法大量使用“整数算法”,这是 cpu 上长期慢操作。现代 cpu 已将执行此计算的速度提高了一倍,从而使masscan速度更快。