每周刷题总结(1)
对最近两周的CTF刷题记录进行一次复盘和总结,整理学到的各种漏洞利用技巧和知识点。总的来说,做的题目覆盖面比较广,从经典的 SQL 注入、SSTI 到各种语言特性和框架的漏洞,收获很大。
0x01 SQL注入
这周在SQL注入方面接触到了几种很有意思的技巧,除了常规的盲注,还有一些绕过姿势和特殊利用方式。
1.1 Quine注入
面试时被问到这个,当时一脸懵。后来才知道,Quine 是一种能产生自身源码副本的程序。在 SQL 注入中,目标就是让查询的输出和我们的输入完全一致,从而绕过一些需要密码完全匹配的登录逻辑。
- 核心原理:利用
REPLACE()和CHAR()函数进行套娃,构造一个执行后结果就是其自身的 SQL 语句。 - 例题:[[第五空间 2021]yet_another_mysql_injection]]
- 题目要求
SELECT出的密码必须与输入的密码===。 - 通过 Quine 注入,构造一个
' union select replace(...)#这样的 payload,让查询结果就是 payload 本身,从而password === $password恒成立。
- 题目要求
1.2 盲注的绕过姿势
在 [[CISCN2019 华北赛区 Day2 Web1]Hack World]] 中,and 和 or 被过滤了,但盲注常用函数 ascii、substr 还在。
- 姿势:使用异或
^代替and或or。0^(布尔表达式),当表达式为真时,结果为1,为假时结果为0,可以通过页面回显的不同来判断。 - Payload 示例:
id = 0^((substr((select(flag)from(flag)),1,1))='f')
1.3 Handler 代替 Select
在 [[GYCTF2020]Blacklist]] 中,select 关键字被过滤了。
- 姿势:使用
HANDLER语句进行查询。这是一种不常用但有效的替代方法。 - Payload 示例:
?inject=1'show+tables;--+(堆叠注入发现表名)?inject=1';handler+FlagHere+open+as+a;handler+a+read+first--+(读取表内容)
1.4 二次注入 (Second-Order Injection)
[[网鼎杯 2018]Comment]] 是一个典型的二次注入。
- 流程:
- 写入:在一个功能点(如“写留言”)插入恶意的 SQL 语句。此时,
addslashes()等函数会转义特殊字符,但数据被原样存入了数据库。
- 写入:在一个功能点(如“写留言”)插入恶意的 SQL 语句。此时,
# 在 category 字段插入恶意语句,利用 content 字段执行查询
title=12&category=12',content=(select(load_file("/etc/passwd"))),/*&content=123- 读取:在另一个功能点(如“查看留言”)读取之前插入的数据。此时,应用从数据库中取出未转义的恶意语句并再次拼接到新的 SQL 查询中,导致注入。
0x02 服务端模板注入 (SSTI)
这周遇到了好几道 SSTI 的题目,涉及 Python 的 Tornado、Bottle 框架和 PHP 的 Smarty 引擎。
2.1 Tornado SSTI
[[护网杯 2018]easy_tornado]] 中,通过报错页面发现存在 SSTI。
- 关键Payload:
{{handler.settings}} - 利用点:Tornado 的
handler.settings对象中存储了应用的环境配置信息,其中可能包含敏感信息,如此题中的cookie_secret。拿到cookie_secret后,就可以伪造 filehash 来读取任意文件。
2.2 Smarty SSTI
在 [[BJDCTF2020]The mystery of ip]] 和 [[CISCN2019 华东南赛区]Web11]] 中,通过 X-Forwarded-For 头注入。
- 利用点:老版本的 Smarty 模板引擎允许在
{if}标签中直接执行 PHP 代码。 - Payload:
X-Forwarded-For: {if system('cat /flag')}{/if}
2.3 Bottle SSTI
Bottle 框架的 SSTI 相对复杂一些,特别是存在 WAF 的情况下。
- [[XYCTF 2025]出题人已疯]]:有长度限制和关键字过滤。
- 姿势:利用
os模块可以像字典一样被操作的特性,将长 payload 分段写入os的某个属性(如os.a),最后再eval(os.a)执行。
- 姿势:利用
- [[XYCTF 2025]出题人又疯]]:黑名单更严格。
- 姿势:可能需要利用一些生僻字符(如斜体字
ª%aa)来绕过bottle.template的解析和过滤。
- 姿势:可能需要利用一些生僻字符(如斜体字
0x03 反序列化漏洞
从 PHP、Python 到 Go,反序列化漏洞的形式多种多样。
3.1 PHP 反序列化
- [[网鼎杯 2020] phpweb]]:利用
__destruct魔术方法,在call_user_func中调用被禁用的函数(如assert),实现 RCE。 - [[网鼎杯 2020] AreUSerialz]]:
- 属性类型混淆:利用高版本 PHP 对
protected和public同名属性不敏感的特性,用public声明来绕过对protected属性不可见字符的检查。 - 强类型比较绕过:在
__destruct中,$this->op === "2"的判断可以通过传入数字2而不是字符串"2"来绕过,从而触发读文件逻辑。
- 属性类型混淆:利用高版本 PHP 对
3.2 Python Flask/Bottle Session 伪造
Flask 和 Bottle 的 session cookie 如果密钥泄露或为弱密钥,就可能被伪造。
- [[CISCN2019 华东南赛区]Web4]] & [[HCTF 2018]admin]]:
- 通过 LFI 或源码泄露找到
SECRET_KEY。SECRET_KEY的生成可能与 MAC 地址等固定值有关,导致其可被预测。 - 使用
flask-session-cookie-manager等工具,传入SECRET_KEY和想要伪造的 session 内容,生成新的 cookie。
- 通过 LFI 或源码泄露找到
- [[XYCTF 2025] Signin]]:Bottle 框架的
get_cookie函数使用了pickle.loads,存在反序列化 RCE。通过泄露的secret伪造一个恶意的 pickle 对象 cookie,触发__reduce__执行任意命令。
3.3 Go 反序列化
- [[VNCTF2023] BabyGo]]:
- 漏洞点在于
gob解码。应用会创建一个user.gob文件,其中Power字段为low。 - 通过 LFI (
/unzip?path=../) 将我们自己制作的、Power为admin的user.gob文件解压覆盖掉原来的文件。 - 再次访问
/backdoor时,反序列化新的gob文件,获得 admin 权限,触发goeval.EvalRCE。
- 漏洞点在于
0x04 命令与代码执行
4.1 preg_replace /e 模式 RCE
[[BJDCTF2020]ZJCTF,不过如此]] 中遇到了经典的 /e 修饰符代码执行漏洞。
- 原理:
/e模式会将preg_replace的第二个参数当作 PHP 代码来执行。 - Payload:
?\S*={${getFlag()}}&cmd=system('cat+/flag');\S*匹配getFlag(),通过\\1传入strtolower,但因为我们的 payload 是{${...}}结构,最终花括号内的代码被执行。
4.2 escapeshellarg 和 escapeshellcmd 连用绕过
[[BUUCTF 2018]Online Tool]] 中的一个经典组合拳。
- 原理:
escapeshellarg会给字符串加上单引号,escapeshellcmd会转义特殊字符。当两者连用时,攻击者可以通过一个精心构造的输入(如' -oG shell.php '),使得escapeshellarg添加的引号被escapeshellcmd转义,从而注入额外的 shell 参数。 - 利用:使用
nmap的-oG参数将命令执行结果写入文件,实现写马。
4.3 Python 沙箱逃逸
- [[阿里云CTF2025] ezoj]]:
sys.addaudithook限制了函数调用。- 姿势:使用未被 hook 的底层模块
_posixsubprocess.fork_exec来执行命令,绕过审计。
- 姿势:使用未被 hook 的底层模块
- [[XYCTF 2025] Now you see me 1]]:一个集大成的题目,
del删除了大量 RCE 相关函数。- 姿势:使用
importlib.reload重载被删除的模块(如os,subprocess),恢复被删除的函数,从而实现 RCE。
- 姿势:使用
0x05 其他技巧
- 整数溢出:在 [[VNCTF2023]电子木鱼]] (Rust) 中,通过传入一个巨大的
quantity,使得cost * quantity的结果超过i32的最大值,溢出成一个负数,从而反向增加功德。 - SSRF:在 [[网鼎杯 2020 玄武组]SSRFMe]] 中,使用
0.0.0.0绕过内网 IP 检测,再用gopher://协议与内网 Redis 通信,写入 webshell。 - 文件上传:
.htaccess:配合<script language='php'>,即使文件后缀不是.php也能被当作 PHP 解析。.user.ini:利用auto_prepend_file包含自身,并通过注释写入一句话木马。
这次总结收获颇丰,很多知识点串联了起来。接下来要继续深入研究,拓宽知识面。