CVE-2018-12613 的一些思考
复现 CVE-2018-12613 的一些思考,关于文件包含路径的问题
漏洞
/index.php 第 55 行
$target_blacklist = array (
'import.php', 'export.php'
);
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;
}
传入参数 target 需要满足
- 不以 index.php 开头
- 不在 target_blacklist 中
- 通过 checkPageValidity() 函数检验
checkPageValidity() 函数
public static function checkPageValidity(&$page, array $whitelist = [])
{
if (empty($whitelist)) {
$whitelist = self::$goto_whitelist;
}
if (! isset($page) || !is_string($page)) {
return false;
}
if (in_array($page, $whitelist)) {
return true;
}
$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
$_page = urldecode($page);
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
return false;
}
第一个返回 True 的地方,直接将 page 与 whitelist 比较,传入的必须是白名单里的文件名,无法绕过
if (in_array($page, $whitelist)) {
return true;
}
第二个返回 True 的地方,mb_strpos($x, $y) 函数查找 $y 在 $x 中首次出现的位置。mb_substr($str, $start, $length) 函数从 $str 中,截取从 $start 位置开始,长度为 $length 的字符串。
但是在这里如果直接构造 payload : ?target=db_sql.php?/../../../cookie.txt 并不能跨路径包含,? 后面的字符串会被当做传入 db_sql.php 的参数,这就要利用后面的 urldecode 了
$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
第三个返回 True 的地方,可以利用双重编码绕过,将 ? 经过两次编码 %253f 就可以绕过白名单验证。%253f 传入时,首先会被自动解码一次,变成 %3f,然后urldecode() 再解码一次,就变成了 ?
此时的 payload : ?target=db_sql.php%253f/../../../cookie.txt
$_page = urldecode($page);
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
问题
include 'db_sql.php%253f/../../../cookie.txt'为什么只会包含 cookie.txt 而不会包含 db_sql.php传入
db_sql.php%253f/../../../cookie.txt为什么会在in_array($_page, $whitelist)处返回 True如图,z.php 中 include 两个 ../ 可以包含,y.php 中一个 include 也可以包含


在 php 的 include 中,
include 'hint.php?/../cookie.txt';会报错,include 'hint.php%3f/../cookie.txt';不会报错,且可以成功包含
一些解释
在 include 中,举个例子,假设 x.php 代码包含 include '1source.phps/../cookie.txt'; ,假设 1source.phps 不存在,那么这个文件包含等同于 : 在 1source.phps 文件夹目录下的上一级中的 cookie.txt ,也就是和 x.php 在同一目录下的 cookie.txt ,如果 1source.phps 存在,并且它是一个文件,那么肯定会报错,如果它是一个文件夹,也会成功包含 cookie.txt 。如果变为 include '1source.phps/./cookie.txt'; ,道理和上面相同
重新思考
代码如下 :
<?php
highlight_file(__FILE__);
class emmm
{
public static function checkFile(&$page)
{
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
if (! isset($page) || !is_string($page)) {
echo "you can't see it";
return false;
}
if (in_array($page, $whitelist)) {
return true;
}
$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
$_page = urldecode($page);
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
); if (in_array($_page, $whitelist)) {
return true;
}
echo "you can't see it";
return false;
}
} if (! empty($_REQUEST['file'])
&& is_string($_REQUEST['file'])
&& emmm::checkFile($_REQUEST['file'])
) {
include $_REQUEST['file'];
exit;
} else {
echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
}
?>
- 传入
file=hint.php,在第一个in_array处会返回 true,然后直接包含hint.php - 传入
file=hint.php?/../cookie.txt,在第二个in_array处会返回 true,第二个in_array中的_page为hint.php,然后包含hint.php?/../cookie.txt,但是这里的?起到传递参数的作用而不是破坏路径 - 传入
file=hint.php%253f/../cookie.txt,在第三个in_array处会返回 true ,第三个in_array中的_page为hint.php,然后包含hint.php%3f/../cookie.txt,这里的%3f即?,破坏了路径,前面部分的路径不存在,可以包含后面的文件
- 传入
CVE-2018-12613 的一些思考的更多相关文章
- 深入剖析最新IE0day漏洞
在2018年4月下旬,我们使用沙箱发现了IE0day漏洞;自从在野外发现上一个样本(CVE-2016-0189)已经有两年多了.从许多方面来看,这个特别的漏洞及其后续的开发比较有趣.下一篇文章将分析最 ...
- 《Link Prediction with Personalized Social Influence》论文解读
论文:Huo, Zepeng, Xiao Huang, and Xia Hu. "Link Prediction with Personalized Social Influence.&qu ...
- 2018-2019-2 网络对抗技术 20165236 Exp5 MSF基础应用
2018-2019-2 网络对抗技术 20165236 Exp5 MSF基础应用 一. 实践内容(3.5分) 本实践目标是掌握metasploit的基本应用方式,重点常用的三种攻击方式的思路.具体需要 ...
- Debian Security Advisory(Debian安全报告) DSA-4405-1 openjpeg2
package :openjpeg2 相关CVE ID: CVE-2017-17480 CVE-2018-5785 CVE-2018-6616 CVE-2018-14423 CVE-2018-1808 ...
- 2018-2019-2 20165330《网络对抗技术》Exp5 MSF基础应用
目录 基础问题 相关知识 实验目的 实验内容 实验步骤 离实战还缺些什么技术或步骤? 实验总结与体会 实验目的 本实践目标是掌握metasploit的基本应用方式,重点常用的三种攻击方式的思路 返回目 ...
- 2018-2019-2 网络对抗技术 20165230 Exp5 MSF基础应用
目录 1.实验内容 2.基础问题回答 3.实验内容 任务一:一个主动攻击实践 漏洞MS08_067(成功) 任务二:一个针对浏览器的攻击 ms11_050(成功) ms14_064(成功) 任务三:一 ...
- c语言实践 打印字母三角形
效果如下: 我是怎么想的: 总共需要打印6行字母,那么就需要一个循环来控制打印第几行,大概代码如下: for(int i=0;i<6;i++) { } 每行都会打印字母,而且循环越往后,需要打印 ...
- Linux提权常用漏洞速查表
漏洞列表 #CVE #Description #Kernels CVE–2018–18955 [map_write() in kernel/user_namespace.c allows privil ...
- 对EasyDarwin开源项目2018的思考与2019发展的规划:继续站在巨人的肩膀引入更多巨人
EasyDarwin@2018思考 从2012年开始接触Darwin Streaming Server,到2018年从底层开始完全重新架构.研发.完成,EasyDarwin这个项目已经发展了6年了,时 ...
- 2018.8.3 Java中容易犯错误的问题思考与总结
Java容易犯错误的问题思考 float型 float f = 3.4 是否正确 不正确,应该用强制类型转换.如下所示:float f = (float)3.4 或float f = 3.4f 在ja ...
随机推荐
- MySQL逻辑分层介绍
上一篇文章主要介绍了MySQL在Ubuntu18.04系统上的安装,以及安装过程中可能会遇到的一些问题的解决方案. 在这篇文章里,开始介绍MySQL数据库的逻辑分层.通过本文的介绍,可以大致了解到My ...
- STM32CubeMx——串口收发
生成代码 1.配置串口1 2.选择模式 3.开中断 4.其他的RCC.调试都一样,弄完直接生成代码. 串口发送 1.定义一个用来测试的数组并初始化 /* USER CODE BEGIN 0 */ ui ...
- coding++:拦截器拦截requestbody数据如何防止流被读取后数据丢失
1):现在开发的项目是基于SpringBoot的maven项目,拦截器的使用很多时候是必不可少的,当有需要需要你对body中的值进行校验,例如加密验签.防重复提交.内容校验等等. 2):当你开开心心的 ...
- 基于.NetCore3.1搭建项目系列 —— 使用Swagger导出文档 (番外篇)
前言 回顾之前的两篇Swagger做Api接口文档,我们大体上学会了如何在net core3.1的项目基础上,搭建一套自动生产API接口说明文档的框架. 本来在Swagger的基础上,前后端开发人员在 ...
- Web 环境设置
修改最大打开文件数量 ulimit -n 100000 修改创建文件的最大值 #/etc/security/limits.conf * soft nofile 262140 * hard nofile ...
- js实现 多级联动
<head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8&quo ...
- js 实现浏览器全屏效果
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 个人hexo博客(静态,无后台)搭建
博客搭建 1.工具安装 安装Node.js,其中包含Node.js和npm(包管理器) 利用npm安装cnpm(淘宝的npm,速度在国内更快) npm install -g cnpm --regist ...
- Windows恢复分区管控命令reagentc
reagentc命令可以实现Windows恢复分区的开关,创建.删除,状态查看. 可以只管确定当前系统恢复分区所在位置,便于删除多余的恢复分区.
- python socket简介
一.socket是什么 socket是应用层与TCP/IP协议通信的中间软件抽象层,它是一组接口.在设计模式中,socket其实就是一个门面模式,它把复杂的TCP/IP协议隐藏在socket接口后面, ...