Black Hat 2025 USA:基于 LLM 的微服务污点漏洞检测
搞过应用安全的朋友大概率都踩过这样一个痛点:面对分布式微服务架构,传统SAST工具早已经显得力不从心。一个用户请求从前端发起,经中间层路由至后端服务集群,需要穿透多个微服务节点;而污点数据会通过RES 2025-11-26 04:34:58 Author: www.freebuf.com(查看原文) 阅读量:24 收藏

搞过应用安全的朋友大概率都踩过这样一个痛点:面对分布式微服务架构,传统SAST工具早已经显得力不从心。一个用户请求从前端发起,经中间层路由至后端服务集群,需要穿透多个微服务节点;而污点数据会通过REST API、gRPC 调用、Kafka消息队列等多类通道跨服务流转。此时,传统SAST聚焦单服务内部的漏洞检测逻辑,已经无法适配这种跨服务、多链路的复杂数据流场景 ,这类跨服务调用链中的漏洞很难被精准识别。

今年Black Hat 2025 USA大会上Fengyu Liu团队发布的MScan工具,用 “LLM入口识别+插件化跨服务追踪+距离引导污点分析”的三层架构,直接在25个开源项目(1K+ GitHub Star)和5个金融级工业应用中检出59个0-day漏洞,召回率100%、准确率71.95%,全面超越CodeQL。本文将基于 Fengyu Liu 团队在大会上公开的演讲 PPT,简要分析MScan的技术架构、给大家提供一些方向参考。

一、微服务污点追踪的痛点

微服务的去中心化、通信多样化特性,让污点漏洞(SQL注入、命令执行、任意文件写入等)的检测难度增加,传统工具的SAST、DAST短板变得尤其明显。

1. 接口路径盲区

微服务的访问入口由网关路由规则统一管控,但非结构化的网关配置易形成检测盲区,导致那些间接可达的漏洞接口被传统 SAST 工具遗漏。这类隐藏入口点的核心风险在于:网关虽拦截了目标服务的直接访问路径,但是无法阻断其他服务通过内部调用转发请求,进而让被 “屏蔽” 的漏洞路径成为间接攻击通道 。典型场景如下:

  • 网关明确对 /user/**路径返回 403 拒绝访问,看似阻断了对 User Service 的直接调用,但 Portal Service 作为可正常访问的中间服务,能接收用户输入并通过内部接口转发至 User Service;
  • 代码实例(服务内漏洞) :Portal Service 对外开放的 /portal/query接口直接接收用户可控的 id参数,该参数未经任何过滤处理,便通过 ScriptEngineManager.eval方法执行动态脚本,最终形成高危的服务内代码注入漏洞。代码实现如下:
  • java// Portal Service (可访问) @Path(value = "/portal/query")publicUserquery(Stringid){Stringquery=(newScriptEngineManager()).eval(id);// 污点数据直接执行,无净化returnselect(query);}
  • 传统SAST默认不会解析网关规则,要么直接将 /user/**排除(漏报跨服务漏洞),要么将所有接口识别为漏洞(误报)。

2. 跨服务数据流盲区

微服务架构中,服务间通信同时存在REST、gRPC等同步调用方式,以及Kafka、RabbitMQ等异步消息队列机制,这种混合通信模式使得污点数据的跨服务传递路径在代码层面表现为断裂的状态。传统SAST工具只能分析单个服务内的代码逻辑,无法跨服务串联污点数据的完整流转链路,最终形成跨服务数据流的检测盲区,让这类跨服务传导的漏洞成为潜在的漏网之鱼。

  • 代码示例(跨服务漏洞):Portal Service 将接收的用户可控 id参数未经净化直接写入 Kafka 消息队列,User Service 从队列中消费该消息后,直接提取 id参数传入 eval方法执行动态脚本,最终形成跨服务的代码注入漏洞。完整的跨服务漏洞代码实现如下:

  1. // 1. Portal Service (可访问) @Path(value = "/portal/query") 
  2. publicUser query(String id){
  3. String op ="query";
  4. KafkaProducer kafkaProducer =newKafkaProducer();
  5. kafkaProducer.send(id);// 将用户输入id异步发送至Kafka
  6. }

  7. // 2. User Service (不可直接访问) @KafkaListener(topics="user/query") 
  8. publicUser queryTask(){
  9. String id = kafkaConsumer.poll();// 从Kafka接收id(污点数据)
  10. String query =(newScriptEngineManager()).eval(id);// 直接执行,无净化
  11. return select(query);
  12. }

传统工具只能分析单服务代码,无法识别 KafkaProducer.send与 KafkaConsumer.poll的通信关联,这类场景会导致跨服务传导。

3. 长调用链场景中性能和精度之间的困境

在电商或金融等这类中大型复杂业务场景的微服务架构中,调用链深度甚至达到10层以上,传统SAST工具在对这类长调用链做上下文分析时,会面临性能与精度不可兼得的困境,如果采用 “全上下文敏感分析”,会因上下文对象数量呈指数级膨胀引发内存溢出(OOM),导致工具直接崩溃;如果为了规避性能问题改用固定的深度分析(例如2层调用链),又会因调用链分析被强行截断,牺牲漏洞检测的精度,最终造成漏洞漏报。

以一个典型的电商场景为例:

  • 一个电商平台的下单请求,需依次经过网关→用户服务→订单服务→库存服务→支付服务5 层服务调用,仅这一基础链路,如果对每一层的交互都执行全上下文敏感分析,上下文对象的创建与存储会让内存占用呈指数级增长,短时间可能会引发JVM的OOM错误,导致分析流程中断;
  • 如果将分析深度简化为2层调用,工具只能追踪相邻两层服务的污点数据,当分析到库存服务时,向支付服务传递的污点数据链路会被直接截断。如果此时支付服务中存在因参数校验缺失导致的支付金额篡改、订单状态伪造等高危漏洞,会因工具无法追踪完整的污点流转路径而被漏报。

二、MScan的三层技术架构

MScan基于Tai-e静态分析引擎构建,仅通过7K行Java代码便实现了 8 类典型微服务漏洞的检测能力,核心通过 “LLM 辅助入口识别 → 跨服务依赖图 → 污点分析” 三步递进的技术路径解决微服务安全检测中隐藏入口遗漏、跨服务数据流盲区、长调用链性能失衡三大核心痛点。

1、LLM 辅助识别入口点

针对网关路由规则非结构化导致的隐藏入口遗漏问题,MScan 引入大语言模型(LLM)解析网关配置文件识别用户实际可达的接口代码路径 ,从源头上剔除无效分析链路,大幅降低后续污点追踪的计算开销。

  • LLM 解析逻辑 :向 LLM 输入原始网关路由规则,并预设Prompt: “保留合法转发正则、仅返回用户可达的转发路径” 等输出约束,模型会自动识别并过滤被网关拦截的路径。例如:

  1. 输入路由规则:portal-route: path:/portal/**; util-route: path:/util/**; filter: denyLLM 

  2. 输出结果:["/portal/**"](自动过滤被 deny规则拦截的/util/**路径)代码层面价值 :仅将 /portal/query等网关允许访问的接口代码纳入分析范围,直接排除 /user/**等被屏蔽的不可达接口,从根源上减少无意义的污点数据追踪与分析,提升检测效率。

Fengyu Liu团队通过对照组实验验证了这个思路的有效性,如果关闭入口过滤功能(MScan-NoEntry)后,检测结果的误报数量从 23 骤增至 89,整体检测准确率从 71.95% 大幅降至 39.86%。从对照组数据结果看,LLM 辅助的入口识别环节能有效削减代码层面的误报源,这里面得益于大模型强大的上下文分析能力。笔者之前所在团队在自研DAST中使用了LLM来识别接口上下文,特别是在未授权类访问类漏洞识别准确率上收益极为明显,准确率可达90%以上,另外在接口识别中可以有效的排除增删改类接口,能够极大降低脏数据对业务的影响。

2、跨服务数据流串联

MScan为每类通信框架开发专属插件,识别跨服务通信API,在代码层面构建 “communication edge”,串联不同服务的控制流。

框架类型关键 API
OpenFeign同步@FeignClient注解、 @Target接口
RestTemplate同步RestTemplate.exchangegetpost
Kafka异步KafkaProducer.sendKafkaConsumer.poll
gRPC同步*BlockingStub.**ImplBase.*

在代码层面构建依赖图

以Kafka通信为例,插件识别 KafkaProducer.send(id)(Portal Service)与 KafkaConsumer.poll()(User Service)的关联,在SDG中添加Portal到User 的communication edge,使污点数据 id的流转路径变得可追踪 。

实验验证

关闭跨服务communication edge(MScan-NoSDG)后,仅能检出27个服务内漏洞,32个跨服务漏洞被漏报,召回率降到了45.76%。

3、污点传播距离引导机制

MScan以污点传播距离为核心调度机制,针对代码调用链中的关键节点实施差异化分析,对近距核心节点进行深度上下文敏感分析,对远距非关键节点采用轻量化处理方案,从根源上规避 OOM 风险,同时最大化分析效率。

  • 距离定义:以污点源(用户输入参数)为起始基准,直接调用节点距离赋值为 1,间接调用节点按调用层级递推(距离 = 2,3...),形成量化的传播路径度量标准;
  • 代码分析逻辑: 典型调用链示例:/portal/query接口(污点源,距离0)→PortalService的KafkaProducer.send(直接调用,距离1,上下文敏感分析)→Kafka队列(中转节点,距离2,轻量化简化处理)→UserService的KafkaConsumer.poll(间接调用,距离3,上下文敏感分析)→eval(id)(漏洞高风险点,距离4,上下文敏感分析);

这里仅对距离≤4的节点做上下文分析,既保证 eval(id)的漏洞点精准识别,又避免长调用链的性能损耗,在检测精度与性能之间做了平衡取舍。

方案召回率准确率超时率
全上下文分析49.15%72.50%30%
双层调用策略100%19.03%0%
距离引导机制100%71.95%0%

三、实战验证

MScan的有效性在三类典型场景中得到验证,以下根据PPT中的代码片段推导的检测逻辑。

1. 案例1:Spring Cloud Dataflow 任意文件写入(CVE-2024-22263)

漏洞背景:Stream Service接收用户上传参数,漏洞根因是Stream Service 通过 RestTemplate 传递用户可控的文件参数,Package Service 未校验路径可以达成任意文件写入。

核心代码片段


  1. // 1. Stream Service入口:/streams/deployments 
  2. @RequestMapping("/streams/deployments")
  3. publicResponse deploy(Map<String,String> properties){
  4. this.deployStream.upload(properties);// 接收用户输入(污点源)
  5. }

  6. // 2. RestTemplate跨服务调用 
  7. String url =String.format("%s/%s", baseUrl,"upload");
  8. Object response = restTemplate.exchange(url, entity);// 调用Package Service

  9. // 3. Package Service写入文件(污点sink)
  10. @RequestMapping("/api/package/upload")
  11. publicMetadata uploadFile(UploadRequest req){
  12. Path file =Paths.get(uploadDir + req.getName());// 未校验路径
  13. Files.write(req.getFileAsBytes(), file);// 直接写入,触发任意文件写入
  14. returnMetadata;
  15. }

MScan检测逻辑


  1. 1、RestTemplate插件识别exchange调用,构建跨服务依赖;
  2. 2、污点分析追踪 properties→req.getFileAsBytes()的流转路径;
  3. 3、发现Files.write(sink)无路径净化,命中告警。

2、案例2:Site Where IoT平台 跨服务SQL注入

漏洞背景

Device Rest接口接收 alternateId,通过gRPC传给Event Service,直接拼接SQL导致SQL注入漏洞;

核心代码片段


  1. // 1. Device Rest入口:/alternate/{alternateId} 
  2. @Path("/alternate/{alternateId}")
  3. publicEvent getDeviceEventById(Request request){
  4. return getEvent(request.getAltId());// 接收alternateId(污点源)
  5. }

  6. // 2. gRPC跨服务调用 
  7. publicEvent getEventByAltId(String alternateId){
  8. EventGrpc.EventStub stub =EventGrpc.newStub();
  9. return stub.getDeviceEventById(alternateId);// 调用Event Service
  10. }

  11. // 3. Event Service SQL拼接(污点sink)
  12. publicstaticIDeviceEvent getEvent(String altId){
  13. String query ="select * from events where altid="+ altId +";";// 直接拼接
  14. return getInflux().query(query);// 执行SQL,触发注入
  15. }

MScan检测逻辑


  1. 1、gRPC插件识别EventGrpc.newStub()调用,串联跨服务数据流;
  2. 2、污点分析发现 altId直接进入SQL拼接(无预编译/过滤)判定为SQL注入漏洞。

3. 案例3:Mogu Blog SSRF漏洞

漏洞背景

Web Service接收用户URL,通过OpenFeign传给Picture Service,可以直接构造URL对象;

核心代码片段


  1. // 1. Web Service入口:/wechatCheck 
  2. @PostMapping("/wechatCheck")
  3. publicString index(HttpServletRequest request){
  4. FileVO fileVO =newFileVO();
  5. fileVO.setUrl(request.getParameter("url"));// 接收用户URL(污点源)
  6. return pictureClient.uploadPicsByUrl(fileVO);
  7. }

  8. // 2. OpenFeign跨服务调用 
  9. @FeignClient("mogu-picture")
  10. publicinterfacePictureFeignClient{
  11. @Target(value ="/uploadPicsByUrl")
  12. String uploadPicsByUrl(FileVO fileVO);// 调用Picture Service
  13. }

  14. // 3. Picture Service构造URL(污点sink)
  15. publicString uploadPictureByUrl(FileVO fileVO){
  16. URL url =new URL(fileVO.getUrl());// 直接用用户URL构造对象,无校验
  17. // 后续请求逻辑,触发SSRF
  18. }

MScan检测逻辑


  1. 1、OpenFeign插件识别@FeignClient注解,构建Web到Picture的 communication edge(这个不晓得咋翻译合适);
  2. 2、污点分析发现 fileVO.getUrl()直接进入 URL,判定为SSRF漏洞。

四、应用安全团队可以借鉴的思路

Fengyu Liu团队在MScan项目中的技术创新,给甲方应用安全团队落地微服务漏洞的代码级检测提供了可直接参考的实践路径,这是LLM在SAST落地的一个优秀的细分的落地案例,比较平衡的解决了跨服务漏洞识别的难题。一方面解决在没有IAST的情况下,以及在一切皆可code的DevSecOps场景下实现最大化的ROI,另外这个思路还可以延伸到与DAST的联动,实现静态扫描 + 动态验证。

1. 优先聚焦框架层关键API

微服务跨服务污点传递的核心载体是各类通信框架的API,实战中需将这类API的代码路径作为检测重点:

  • 优先覆盖主流通信框架的关键API,如Kafka的 sendpoll方法、gRPC的 Stub类调用、OpenFeign的 @FeignClient注解等,这些是跨服务漏洞的核心触发节点;
  • 基于Tai-e静态分析引擎开发自定义插件,去适配企业内部定制化通信组件(如自研消息队列、私有RPC框架)

2. 通过LLM预处理

网关路由规则的非结构化特性,加上数量变大的话导致人工解析效率低、不仅成本高也容易遗漏,利用LLM实现网关配置的自动化预处理,充分发挥LLM优势:

  • 针对Spring Cloud Gateway的 application.yml等网关配置文件,利用LLM批量解析并提取用户可达的接口列表,仅对这些接口对应的代码开展检测,大幅减少无效分析工作量;
  • 参考标准化提示词实现精准解析。

3. 充分利用LLM的上下文理解能力,动态平衡分析深度

微服务长调用链下,全上下文敏感分析容易引发性能瓶颈,可以根据代码调用深度动态调整分析策略,平衡检测精度与效率:

  • 对核心节点做高精度分析:以用户输入的入口接口为距离0,其直接调用的服务(距离1-2)采用上下文敏感分析,确保漏洞点的精准识别;
  • 对深层调用做简化分析:对距离≥3的间接调用服务,切换为上下文不敏感分析,避免因调用链过长导致的分析超时、内存溢出问题。

结语:

MScan的创新在于将原本只能由IAST完成的跨服务污点追踪能力,左移到了SAST阶段,初步实现代码级别的串联检测,为微服务架构的漏洞检测提供了创新思路。在这里给项目团队点个赞,同时也期待甲方同学点企业级落地实践案例。

附:

项目开源地址:https://github.com/LFYSec/MScan

PPT截图:


文章来源: https://www.freebuf.com/articles/459100.html
如有侵权请联系:admin#unsafe.sh