【CTF日记】
WarmUp
题目介绍
- 这道题来自BUUCTF,
Web组的第一题。 - 设计的知识点包括:
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\" />";
}
?>
函数解析
- isset ( mixed
$var, mixed$...= ? ) : bool- 判断变量
var是否被设置并且非NULL。
- 判断变量
- is_string ( mixed
$var) : bool- 检测变量
var是否是字符串。
- 检测变量
- in_array ( mixed
$needle, array$haystack, bool$strict=false) : bool- 检查数组
haystack中是否存在某个值needle。 - 若数组为键值数组,则匹配值。
- 检查数组
- mb_substr ( string
$str, int$start, int$length= NULL , string$encoding= mb_internal_encoding() ) : string- 根据字符数执行一个多字节安全的 substr() 操作。
- 取字符串
str从start开始length长度的子串。
- mb_strpos ( string
$haystack, string$needle, int$offset= 0 , string$encoding= mb_internal_encoding() ) : int- 查找字符串
needle在字符串haystack中首次出现的位置。
- 查找字符串
- urldecode ( string
$str) : string- 解码已编码的
URL字符串str。
- 解码已编码的
- include
- 后跟要被包含的文件名,表示引入该文件。
代码逻辑
主函数
- 第
40行的if语句判断了- 提交的参数
file是否为空; - 参数
file是否为字符串; - 函数
checkFile是否返回true。
- 提交的参数
- 上述条件满足就将
file对应的文件打开,不满足则显示滑稽。

checkFile函数
- 在第
5行中将参数file赋值给变量page。 - 第
7行给出白名单,分别是source.php、hint.php。 - 第
8行判断变量page是否已设置为字符串,若没有,则滑稽伺候。 - 第
13行第一次判断page是否属于白名单,若是则包含文件。 - 第
17行裁剪原始变量page,_page留下第一个?之前的字符串。 - 第
22行第二次判断page是否属于白名单。 - 第
26行对变量page进行URL编码的解码,赋值给_page。
注意:
page取自URL,作为参数传入会先进行一次解码。
- 第
27行裁剪解码后的变量_page。 - 第
32行第三次判断_page是否属于白名单。
hint.php
- 提示给出了
flag所在文件夹。
flag not here, and flag in ffffllllaaaagggg
EazySQL
解题过程
- 在上述我标红的三次判断中,可以设置不同状态的
page得到文件包含。 - 第一次判断时,对变量
page没有做任何改变,满足条件只有参数file(原始传入的page)为source.php或hint.php,很明显无法包含文件ffffllllaaaagggg。 - 第二次判断时,考虑到裁剪之后需要满足
?前包含source.php或hint.php,之后的部分可以任意修改。
包含
?后就已经绕过了第一个判断。
- 尝试包含到文件
ffffllllaaaagggg,在?之后不断添加访问上级目录符号../,例如。
source.php?../../ffffllllaaaagggg
- 当
../达到8个时,出现flag。

-
这里出现了多解,使用第三次判断仍然可以实现。
-
由于
URL会对特殊字符进行编码,故利用代码中的二次解码,将?设计为经过两次编码的码值。
? => %3f => %253f
- 使用
%253f替换?位置之后,传入服务器时变成%3f,此时即可绕过前两次判断。 - 在第三次判断前,
urldecode()将%3f转化为?,完成判断。 - 给出第三次判断的
Payload。
source.php%253f../../../../../../../../ffffllllaaaagggg
题目介绍
- 这道题来自BUUCTF,
Web组的第二题。 - 涉及的知识点包括:
SQL注入
题目解析
- 很单纯的登录界面,需要输入用户名和密码。

- 此时你输入的字符串将被用于数据库查询对应的用户,通过这样的机制,即可构造
SQL注入攻击。
SQL注入具体知识参考我的一篇博客。
解题过程
- 观察攻击场景,通常来说用户名和密码都为字符串输入,故此处猜测为字符型注入。
- 假设查询语句模型。
SELECT * FROM user WHERE user_id='${User-Name}' and passwd='${User-Passwd}';
- 尝试使用注释
#屏蔽后面代码,下面给出用户名和密码的Payload。
' or 1=1#
- 得到
flag。

- 若注释符被屏蔽,使用
'构造查询字符串闭合,给出Payload。
' or '1'='1

浙公网安备 33010602011771号