[BUUOJ记录] [HCTF 2018]WarmUp
BUUOJ Web的第一题,其实是很有质量的一道题,但是不知道为什么成了Solved最多的题目,也被师傅们笑称是“劝退题”,这道题的原型应该是来自于phpMyadmin的一个文件包含漏洞(CVE-2018-12613)
解题过程
解题思路
进入题目查看源代码发现提示:
跟进source.php得到源代码:
<?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\" />";
}
?>
代码分为两部分来看,第一部分是定义了emmm类的一个checkFile函数,用来检查传入的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']) //用$_REQUEST来接收file参数,如果file参数的值不为空、为字符串、可以通过emmm类checkFile函数检测,则包含该文件
) {
include $_REQUEST['file'];
exit;
} else {
echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
}
在emmm类的checkFile函数中我们可以看到白名单中有两个文件:
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
包含一下hint.php文件来试试 /source.php?file=hint.php :
提示我们Flag在ffffllllaaaagggg中,那么我们解题的关键就是如何包含这个在whitelist外的文件
从第二部分代码我们可以看出,重点是如何让ffffllllaaaagggg通过checkFile的检查,因此我们就需要从emmm类的checkFile函数入手
前置知识点
我们在读这个函数的代码前需要提前了解几个checkFile函数中出现的函数:
1. in_array() 函数搜索数组中是否存在指定的值
更多信息参考:https://www.w3school.com.cn/php/func_array_in_array.asp
2. mb_substr() 函数返回字符串的一部分,之前我们学过 substr() 函数,它只针对英文字符,如果要分割的中文文字则需要使用 mb_substr()
更多信息参考:https://www.runoob.com/php/func-string-mb_substr.html
3. mb_strpos() 查找字符串在另一个字符串中首次出现的位置
更多信息参考:https://www.php.net/manual/zh/function.mb-strpos.php
核心代码分析
在了解了上面的几个小点之后我们返回来看核心代码:
class emmm
{
public static function checkFile(&$page)
{
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
if (! isset($page) || !is_string($page)) { //page必须不为空或为字符串
echo "you can't see it";
return false;
} if (in_array($page, $whitelist)) { //in_array()检测page是否在whitelist中
return true;
} $_page = mb_substr( //如果page含有?,则获取page第一个?前的值并赋给_page变量
$page,
0,
mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) { //检测_page是否在whitelist中
return true;
} $_page = urldecode($page); //给_page二次赋值,使其等于URL解码之后的page
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?') //如果_page有?,则截取_page(URL解码后的page)两个?中间的值
);
if (in_array($_page, $whitelist)) { //检测_page是否在whitelist中
return true;
}
echo "you can't see it";
return false;
}
}
逻辑可能看着有点乱,所以我们梳理一下逻辑,这里引用王叹之师傅的分析:
可以看到函数代码中有四个if语句:
第一个if语句 对变量进行检验,要求$page为字符串,否则返回false //因为返回False所以这里无用
第二个if语句 判断$page是否存在于$whitelist数组中,存在则返回true
第三个if语句 判断截取后的$page是否存在于$whitelist数组中,截取$page中'?'前部分,存在则返回true
第四个if语句 判断url解码并截取后的$page是否存在于$whitelist中,存在则返回true
若以上四个if语句均未返回值,则返回false有三个if语句可以返回true,第二个语句直接判断$page,不可用
第三个语句截取'?'前部分,由于?被后部分被解析为get方式提交的参数,也不可利用
第四个if语句中,先进行url解码再截取,因此我们可以将?经过两次url编码,在服务器端提取参数时解码一次,checkFile函数中解码一次,仍会解码为'?',仍可通过第四个if语句校验。
只要这四个if语句有一个为true即可包含file,关键点在_page 经过截断后返回true.
所以我们的突破点就在于第四个if语句中,只要满足他的条件,我们就可以包含文件:
$_page = urldecode($page);
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
这里URL解码了一次$page值,这里需要注意的是,PHP中$_GET、$_POST、$_REQUEST这类函数在提取参数值时会URL解码一次
而这里在代码中又一次URL解码了一次,共计解码了两次,所以我们也需要对传入的值进行两次URL编码
其次我们的突破点就在于这段代码只会截取?之前的字符串拿去和whitelist比对,因此只要确保?前的值是source.php或hint.php即可返回true
等同于 /source.php?file=source.php%253F123456 便可以使用include()函数包含 source.php?123456 这个文件(%253f是?URL编码两次后的值)
所以可以构造Payload:
/index.php?file=source.php%253F/../../../../ffffllllaaaagggg
需要注意的是,这里之所以可以包含到ffffllllaaaagggg是因为PHP将 source.php%253F/ 视作了一个文件夹,然后 ../ 的用途是返回上级目录
ffffllllaaaagggg位于根目录下,一般Web服务的文件夹在/var/www/html目录中,再加上source.php?/这个“文件夹”,所以我们总共需要../四次来返回到根目录
(如果比赛中不知道flag具体位置的话可以一层一层来试)
[BUUOJ记录] [HCTF 2018]WarmUp的更多相关文章
- [原题复现]HCTF 2018 Warmup(文件包含)
HCTF 2018 Warmup 原题复现:https://gitee.com/xiaohua1998/hctf_2018_warmup 考察知识点:文件包含漏洞(phpmyadmin 4.8.1任意 ...
- 攻防世界 WEB 高手进阶区 HCTF 2018 warmup Writeup
攻防世界 WEB 高手进阶区 HCTF 2018 warmup Writeup 题目介绍 题目考点 PHP代码审计 Writeup 打开 http://220.249.52.134:37877 常规操 ...
- [HCTF 2018]WarmUp
靶场首页 打开靶场后,查看源码即可看到<!--source.php--> 打开source.php页面 代码如下 <?php highlight_file(__FILE__) ...
- 刷题[HCTF 2018]WarmUp
解题思路 进入页面之后,一个大大的滑稽. 查看源码 查看源码发现有source.php .打开 发现还有一个hint.php.打开发现 由此可知是代码审计了 解题 代码审计 先看此段代码,大致意思是. ...
- CTF-WEB-HCTF 2018 Warmup
题目链接 攻防世界-Warmup 解题思路 [原题复现]HCTF 2018 Warmup(文件包含)
- [BUUOJ记录] [GYCTF]EasyThinking
主要考察ThinkPHP6.0的一个任意文件写入的CVE以及突破disable_function的方法. ThinkPHP6.0.0任意文件操作漏洞 理论分析 进入题目是一个简单的操作页面,dirma ...
- warmup(HCTF 2018)
为啥想写这道题的wp呢,因为这道题就是照着phpmyadmin 4.8.1 远程文件包含漏洞(CVE-2018-12613)复现出来的 题目 查看源码很容易找到source.php,直接访问 分析 题 ...
- BUUCTF | [HCTF 2018]admin
首先爬一遍整个网站,发现有没注册的时候有“login”,"register",这两个页面,注册一个123用户登录后发现有 "index“,”post“,”logout“, ...
- [HCTF 2018]admin
前言: 最近在BUUCTF刷题,参照师傅们wp后复现一下 0x01 拿到题目后进去如下界面 发现有登录和注册界面,相比是要登录后才能查看想要的信息. 查看页面源代码,看看有没有上面提示,界面如下 提示 ...
随机推荐
- python分析BOSS直聘的某个招聘岗位数据
前言 毕业找工作,在职人员换工作,离职人员找工作……不管什么人群,应聘求职,都需要先分析对应的招聘岗位,岗位需求是否和自己匹配,常见的招聘平台有:BOSS直聘.拉钩招聘.智联招聘等,我们通常的方法都是 ...
- 使用HttpClient 发送 GET、POST(FormData、Raw)、PUT、Delete请求及文件上传
httpclient4.3.6 package org.caeit.cloud.dev.util; import java.io.File; import java.io.IOException; i ...
- [机器学习 ]PCA降维--两种实现 : SVD或EVD. 强力总结. 在鸢尾花数据集(iris)实做
PCA降维--两种实现 : SVD或EVD. 强力总结. 在鸢尾花数据集(iris)实做 今天自己实现PCA,从网上看文章的时候,发现有的文章没有搞清楚把SVD(奇异值分解)实现和EVD(特征值分解) ...
- 定宽整形(C++11起)
定义于头文件 cstdint中int8_t.int16_t.int32_t.int64_t 分别为宽度恰为 8 . 16 . 32 和 64 位的有符号整数类型无填充位并对负值使用补码(仅若实现支持该 ...
- 2020-06-14:Redis怎么实现分布式锁?
福哥答案2020-06-14: 1.SETNX+EXPIRE.非原子性.2.SET key value [EX seconds] [PX milliseconds] [NX|XX]EX second ...
- C#LeetCode刷题之#717-1比特与2比特字符( 1-bit and 2-bit Characters)
问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3740 访问. 有两种特殊字符.第一种字符可以用一比特0来表示.第 ...
- [开源] .Net ORM FreeSql 1.8.0-preview 最新动态播报(番号:我还活着)
写在开头 FreeSql 是 .NET 开源生态下的 ORM 轮子,在一些人眼里属于重复造轮子:不看也罢.就像昨天有位朋友截图某培训直播发给我看,内容为:"FreeSQL(个人产品),自己玩 ...
- SpringSecurity权限管理系统实战—三、主要页面及接口实现
系列目录 前言 后端五分钟,前端半小时.. 每次写js都头疼. 自己写前端是不可能的,这辈子不可能自己写前端的,只能找找别人的模板才能维持的了生存这样子.github,gitee上的模板又多,帮助文档 ...
- Wireshark中遇到的epoch time
使用Wireshark分析DNS时遇到的Epoch time 首先看一下Wireshark分析DNS的情况(如下图): 这是协议树的第一项,第一项中的第五行出现了Epoch Time,查阅资料之后才知 ...
- node.js 模拟自动发送邮件验证码
node.js 模拟自动发送邮件验证码 引言 正文 1. QQ邮箱设置 2. 安装nodemailer 3.配置信息 4.综合 5.讲解 结束语 引言 先点赞,再看博客,顺手可以点个关注. 微信公众号 ...