在进行端口扫描时,引入随机化技术可以增加隐蔽性,降低被目标系统检测到的风险,从而提高扫描的成功率。本文将讨论常用端扫工具在目的端口和IP的随机化算法。
基础
在进行端口扫描随机化时,我们可以将IP地址和端口号组合视为一个数组。为了实现随机化,我们可以对这个数组进行打散处理。以 python 为例,默认的 random.shuffle 的实现通常基于 Fisher-Yates(或称为 Knuth)洗牌算法。基本步骤如下:
- 从序列的最后一个元素开始,向前遍历到第一个元素。
- 对于当前位置 i,从 0 到 i(包括 i)之间选择一个随机索引 j。
- 交换位置 i 和位置 j 上的元素。
- 重复步骤 2 和 3,直到到达序列的开始。
- 以下是 Fisher-Yates 洗牌算法的一个简单实现示例:
1 | import random |
尽管该算法的空间复杂度和时间复杂度均为O(n),相对较低,但在面对IPv4地址空间的十亿级规模时,这一方案就显得不太可行了。
即使不扫描整个IPv4地址空间,一个内网B段包含256*256=65536个IP地址,每个IP地址有65536个端口,总共有2^32个元素。在最小的情况下,一个IP地址加端口需要6字节,那么所需的存储空间将达到6(2^32) / 2^10 / 2^10 / 2^10 = 24GB。
具体的运行时间可以用以下代码估计
1 | import os |
输出
1 | Size: 1024, Time: 0.00024179997853934765 seconds |
2的8次方乘以6等于1536秒,即25分钟。一个B段的随机化过程需要大量时间。那么,已有的算法是如何解决这个问题的呢?
nmap
nmap 中,随机化通过 -r
选项开启,在代码中处理逻辑如下:
1 | if (o.randomize_ports) { |
而随机化算法如下,是简单的洗牌算法
1 | void shortfry(unsigned short *arr, int num_elem) { |
最后会对常用端口做一个优化
1 | // Move some popular TCP ports to the beginning of the portlist, because |
通过分析代码,我们可以清楚地看到nmap并未对IP地址进行随机化处理。此外,我们还可以利用strace工具,在不需要检查代码的情况下,验证这一结论。
1 | strace -e sendmsg nmap 10.5.0.0/24 -p 2233,4455 |
显而易见,nmap的随机方法采用了较为简化的策略,通过牺牲随机性来对端口进行随机化处理。
masscan
转而关注 masscan,从其源代码中我们发现,masscan 的随机化算法源自论文 Ciphers with Arbitrary Finite Domains。该算法通过类似块密码的方法实现了一种变换。即类似
1 | 0 -> 6 |
显然,我们可以按照此算法对0到n进行依次变换,并获取相应的IP端口对。此方法还可用于恢复进度。此外,masscan也提供了该算法的基准测试方案,可以通过以下命令执行:
1 | masscan --benchmark --blackrock-rounds 10 |
输出如下:
1 | === benchmarking (64-bits) === |
从 benchmarking 的源代码 可以看出,预先配置的数组范围和迭代次数都较高,这表明该算法的整体时间成本相对较低。此外,该算法也不需要额外的空间资源。
1 | blackrock_benchmark(unsigned rounds) |
zmap
与nmap和masscan不同,zmap在设计时旨在覆盖整个互联网空间。基于这一目标,zmap在设计过程中采用了循环群技术对IPv4地址空间进行随机化处理。
循环群是一种独特的群结构,其特性在于可通过单一元素生成,即群内所有元素均可表示为此元素的幂。此元素被称为循环群的生成元或原根。具体来说,假设G是一个群,a是G中的某个元素,若存在正整数n,使得a的n次幂能够遍历G中的所有元素,且a的幂次模n不会重复,则称G是由a生成的循环群,且a是G的一个生成元或原根。例如,整数集合Z构成一个循环群,由1生成,因为任何整数都可以表示为1的幂次。另一个例子是模p的剩余系构成的乘法群,由原根生成,因为原根的幂可以取遍所有非零剩余类。循环群在数学和密码学领域都有着广泛的应用。在密码学中,循环群可用来构建公钥密码系统,例如Diffie-Hellman密钥交换算法和ElGamal加密算法。
具体来说,Zmap使用循环群算法找到一个大于2的32次方的原根,通过每次遍历这个循环群来实现其遍历IPv4地址空间的能力。
1 |
|
参考链接
https://github.com/robertdavidgraham/masscan/blob/master/src/crypto-blackrock.c
https://github.com/zmap/zmap/blob/main/src/cyclic.c#L196
http://www.cs.ucdavis.edu/~rogaway/papers/subset.pdf