JAVA之URLDNS链再分析

URLDNS链再分析

readObject()方法

Java反序列化会调用对应的readobject方法
比如我创建一个类test。序列化test类就会调用writeobject方法,
反序列化就会调用test类的readobject方法。默认是存在的。可以重写readobject方法
在HashMap类中,恰恰存在readobject方法

以ysoserial的payload为例,作者有明确指出

 *   Gadget Chain:
 *     HashMap.readObject()
 *       HashMap.putVal()
 *         HashMap.hash()
 *           URL.hashCode()

我先是把这条链子跟完了,现在分析一下他的payload

public Object getObject(final String url) throws Exception {
	URLStreamHandler handler = new SilentURLStreamHandler();
	HashMap ht = new HashMap(); 
	URL u = new URL(null, url, handler); 
	ht.put(u, url); 
	Reflections.setFieldValue(u, "hashCode", -1); 
	return ht;
}

整条链子加起来不到5行,他第一步先是实例化了一个URLStreamHandler的对象,但是这里用的是它的子类,因为后面你调试的时候会发现,他本是是一个抽象类,想要实例化只能选择继承他的子类,而这里作者是在下面自己继承了一个子类

        static class SilentURLStreamHandler extends URLStreamHandler {

                protected URLConnection openConnection(URL u) throws IOException {
                        return null;
                }

                protected synchronized InetAddress getHostAddress(URL u) {
                    return null;
                }
        }

第一行的openConnection方法是必须被子类重写的,我们可以回到URLStreamHandler他有对这个抽象方法的介绍:Opens a connection to the object referenced by the URL argument. This method should be overridden by a subclass.意思就是子类应该覆盖该方法,而且这个方法也是抽象方法,子类必须要对它实现

而第二行,经过我反复测试,当把这一行代码删除的时候,dns的请求次数会+1,也就是说之所以要有一个return null是为了防止在poc创建的时候触发dns请求,而无法判断是否是链条本身触发的dns请求,他本身也有解释:**此UrlStreamHandler的实例用于在创建URL实例时避免任何DNS解析。**DNS分辨率用于漏洞检测。重要的是使用序列化对象先前探测给定的URL。潜在假阴性:如果首先从测试器计算机解析DNS名称,则目标服务器可能会在第二分辨率上获取缓存。

链子分析:

首先就是利用HashMap.readObject()方法在反序列化的时候作为触发点,其中putVal(hash(key), key, value, false, false);的hash方法会对key进行处理,而这里的key就是我们创建的url对象,那么他是如何赋值的:利用ht.put(u, url);作为下一个跳板,来调用URL u的hashcode并用Reflections.setFieldValue(u, “hashCode”, -1); 对URL的对象u的参数进行调整,再利用其hashcode调用URLStreamHandler的hashcode来进行dns请求,达到我们的要求

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
首先,你需要引入 JavaURL 和 IO 相关的库,代码如下: ```java import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URL; ``` 接下来,你需要定义一个方法来获取网页的内容,代码如下: ```java public static String getHtml(String urlString) throws Exception { // 创建 URL 对象 URL url = new URL(urlString); // 打开连接 BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream())); // 读取数据 String line; StringBuilder stringBuilder = new StringBuilder(); while ((line = reader.readLine()) != null) { stringBuilder.append(line); } reader.close(); // 返回网页内容 return stringBuilder.toString(); } ``` 在这个方法中,你需要传入一个字符串类型的参数 `urlString`,表示需要爬取的网页地址。然后,通过 `URL` 类创建一个连接对象,用 `BufferedReader` 类读取网页内容,最后返回一个字符串类型的内容。 接下来,你需要定义一个方法来分析网页敏感词,代码如下: ```java public static boolean analyzeHtml(String htmlContent, String[] sensitiveWords) { // 遍历所有敏感词 for (String word : sensitiveWords) { // 判断当前敏感词是否存在于网页中 if (htmlContent.contains(word)) { return true; } } return false; } ``` 在这个方法中,你需要传入两个参数:一个是字符串类型的 `htmlContent`,表示需要分析的网页内容;另一个是字符串类型的 `sensitiveWords`,表示需要检测的敏感词数组。方法中会遍历所有敏感词,判断当前敏感词是否存在于网页中,如果存在则返回 true,表示网页包含敏感词;否则返回 false,表示网页不包含敏感词。 最后,你可以在主函数中调用以上两个方法,代码如下: ```java public static void main(String[] args) { try { // 爬取网页内容 String htmlContent = getHtml("https://www.example.com/"); // 敏感词数组 String[] sensitiveWords = {"敏感词1", "敏感词2", "敏感词3"}; // 分析网页敏感词 boolean hasSensitiveWords = analyzeHtml(htmlContent, sensitiveWords); if (hasSensitiveWords) { System.out.println("网页包含敏感词"); } else { System.out.println("网页不包含敏感词"); } } catch (Exception e) { e.printStackTrace(); } } ``` 在这个示例中,我们爬取了一个网页的内容,并定义了一个敏感词数组,然后调用了分析网页敏感词的方法。如果网页包含敏感词,则输出 `网页包含敏感词`;否则输出 `网页不包含敏感词`。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yn8rt

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值