基础的网络空间测绘是存在成熟实践的工程问题,从域名枚举到端口爆破到应用扫描都有着大量可选用的优质工具。但是当测绘目标的数量提高几个数量级时,问题开始变得有些许不同。过量的域名解析请求被域名服务器禁止,大量的端口扫描之后是大量的超时、漏报、误报。如果不解决随着测绘规模扩大而来的问题,当扫描目标量级的不断提升,测绘得到的数据质量将会不断下降。
为了能更清晰的拆解需求、分析问题、研究解决方案,笔者在尝试进行规模化测绘的工程实践时,对遇到的挑战进行了一些思考和总结,形成了这篇文章,希望能对测绘感兴趣的同学有所帮助。
0. 问题分析
在笔者看来,要实现一个有意义的、支持规模化扫描的网络空间测绘工具要关注的是三个核心点:即数据质量、工程实现和数据使用。数据质量要保证扫描结果漏报率、误报率低,面临的是与防火墙和情报的对抗;工程实现要解决的是实际的工程问题,即大量扫描节点的任务分发、调度、监控;数据使用是考虑如何发挥测绘数据的价值。
1. 数据质量
最基本的衡量数据质量的指标是漏报率和误报率。即原本不开放的端口被识别为开放,原本开放的端口被识别为不开放。理论上讲,用白IP以相对长的等待时间对目标IP单个端口进行完整的协议交互,获得的数据是干净准确的。然而数据质量是受测绘规模影响最直观的指标。当测绘量级扩大到数亿级时,获得有质量的数据开始变得困难。在现网环境下,造成漏报、误报的原因大部分是与防火墙的对抗和与情报的对抗。
在实际的网络空间中有多种多样的防御产品,这些产品的检测与防御机制都各有不同。有针对扫描工具特征的检测,例如nmap扫描中的报文特征;有针对扫描技术的检测,例如SYN扫描。很多防护设备在检测到一定量级的SYN报文之后,会对所有的SYN报文响应ACK,直到完成TCP三次握手为止。当使用已有的扫描工具时,其扫描策略也是防护设备已知的,即是说,使用公开方案对有防护设备的网络进行扫描,获得的数据质量都是相对有限的。
除了与防护设备对抗之外,在威胁情报逐渐发展的今天,测绘也面临着与情报的对抗。要在有效时间内完成扫描,一个IP通常会发出大量的请求。而测绘量级扩大之后,用于扫描的IP资源和需要扫描的IP空间是不成正比的。对一些能力较强的组织,常见的IP池,如云供应商、代理池、秒拨的IP池通常在情报中。常见的获得大量IP的方式,如云函数、Cloudflare Worker等手段也被拥有较强能力的防守方所禁止。另外在特定时间段,一些激进策略可能会直接禁止掉上述情报中的IP。此外,如果扫描到了蜜罐,用于扫描的IP可能会进入威胁情报中,从而被数个组织联动禁止。
如果使用降低扫描速率来减小被发现概率的方式,时间成本就会成为新的问题。不难想象,如果扫描完IPv4的地址空间需要数个月以上的时间,许多IP地址可能已经重新分配了,一些应用也可能已经经历了上线下线的生命周期从而不再出现。
IPv4测绘面临的挑战是更多是如何用有限的IP获得高质量的结果,而IPv6测绘面临的第一个问题是几乎难以对全IPv6地址空间进行探测。128位的地址空间带来了大量的IP,扫描所有可能的IPv6地址并不是一个现实的问题,因此需要考虑如何找到有效的IPv6地址段。
除了漏报和误报以外,还有一个重要的因素是数据是否完善。不妨假设有以下几份数据:
- IP为
1.2.3.4
的机器开放了22端口 - IP为
1.2.3.4
的机器开放了22端口,端口对应的服务为OpenSSH 7.4
- IP为
1.2.3.4
的机器开放了22端口,端口对应的服务为OpenSSH 7.4
,配置了允许通过密码登录,支持的加密协议有chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com
很显然,虽然以上几例数据同样都是22端口开放的信息,但是这几例数据的价值是完全不同的。在这个样例中,SSH协议是相对常见的协议,有较为方便的库可以用于提取信息,协议开放端口也是IANA标准定义的标准端口。而在网络空间中,有许多协议并不常见,同时开在非IANA标准所定义的端口中,如果不进行识别与交互,测绘数据的价值将会相对低。
2. 工程实现
要解决的第二个核心挑战是如何进行工程实现。
工程实现的挑战也主要是由量级扩大带来的。在单个目标的场景下,DNS子域名爆破到IP端口扫描到应用扫描的路径非常清晰。但是当量级开始扩大时,问题出现了。考虑到单机不能实现大规模的扫描,实际需要分布式场景的解决方案。这引入了新的问题,即任务分发、任务调度、限流与过载保护、隔离、异常检测与恢复、数据存储、监控、日志收集与查询等。当然,这些问题有一些成熟的解决方案,甚至可以从云服务商处直接买到对应的SaaS服务,需要考虑的是如何让这些方案满足测绘场景的需求。
其二,在测绘系统变为复杂的分布式系统后,各种基础环境的可用性不再一定有保证,网络环境、数据库服务、外部服务、内部服务都可能变得不可靠。笔者在之前的文章中有提到DNS服务的不可用性,这实际只是很小一个方面。同时当系统性能开始接近极限时,操作系统也不一定可靠,原本低概率触发的网络抖动、数据错误、资源泄露等场景都可能出现。此外在很多场景下测绘使用云服务商提供的基础服务,由于合规等因素,大规模的扫描也可能触发服务商的封禁策略,导致账号被封禁。
还有一个不能忽略的问题是成本和性能。假设单个IP单次扫描的流量在1M左右,按当前的云服务流量价格计算,1个G的流量费用约为0.8元,而如果不加区分的扫描整个IPv4地址段,流量费用会近百万。这还没有计算存储、设备的费用。因此在工程实现时也需要考虑如何以可接受的成本进行测绘。
小规模的测绘其实是不太需要考虑性能问题的,但是当量级扩大时,性能的损耗会被扩大很多倍,很多参数、算法的选择会带来较大的影响。考虑一种场景,分别设置扫描请求超时等待的时间为5s和6s,在超时任务占总任务20%的情况下,第一种超时设置扫描总耗时10天,那么第二种设置单次扫描会多耗时近5个小时。另一种场景是分布式算法、技术栈选择的不同也对应着不同的性能损耗,考虑算法、实现带来的性能损失在10%左右,那么10天左右的扫描在未优化的情况会多耗时近1天。
3. 数据使用
不使用的数据是没有价值的。对企业来说,最基础的测绘数据应用当然是攻击面管理(Attack Surface Management,ASM),根据测绘识别脆弱点进行加固;而在0day漏洞爆发时,全网测绘则能发挥预警、推动修复等作用。
除此之外,不如让我们考虑测绘数据还能做些什么。例如是否能通过对测绘数据的聚类找到新的协议、能否通过对特定协议的扫描预先找到恶意的攻击基础设施并进行预警。
数据使用的需求背后是数据库的支持。最原始的测绘数据仅期望能索引目标,小型的需求开源数据库就可以满足。而当数据量超过百万,普通数据库就需要一定的优化才能在可容忍的时间内查询到结果。继续扩充数据量到超过亿级,可能从数据库选型到库结构到字段定义都需要针对性的优化。
再进一步的考虑,如果存储异构数据,即大量不同的网络协议的数据,就又对数据库提出了新的要求。如HTTP协议需要记录的数据特征是响应,SSH协议需要记录的数据是交互算法。不加优化的存储所有数据到一种数据库、按协议分库都不一定是合适的做法。
再考虑多一步,在大规模测绘时,会希望对数据的产生、转化、消费有比较明确的记录以防止部分错误数据污染整个数据库,这就需要对数据血缘进行管理。
数据库的使用还需要考虑历史数据自动轮换等问题。存储全量数据当然是很有吸引力的方案,但是大量数据的存储成本同样非常高昂。如果想以可接受的成本存储数据,就需要考虑数据分级等问题,即部分数据长久存储,部分数据可以一定时间后删除,部分数据可以一定时间后切换到廉价存储。
参考资料
参考文章
参考工具
https://github.com/stanford-esrg/lzr
https://github.com/zmap/zgrab2