关联:CTF刷题记录安全学习CTF wp

每周刷题总结(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]] 中,andor 被过滤了,但盲注常用函数 asciisubstr 还在。

  • 姿势:使用异或 ^ 代替 andor0^(布尔表达式),当表达式为真时,结果为1,为假时结果为0,可以通过页面回显的不同来判断。
  • Payload 示例id = 0^((substr((select(flag)from(flag)),1,1))='f')

1.3 Handler 代替 Select

在 [[GYCTF2020]Blacklist]] 中,select 关键字被过滤了。

  • 姿势:使用 HANDLER 语句进行查询。这是一种不常用但有效的替代方法。
  • Payload 示例
    1. ?inject=1'show+tables;--+ (堆叠注入发现表名)
    2. ?inject=1';handler+FlagHere+open+as+a;handler+a+read+first--+ (读取表内容)

1.4 二次注入 (Second-Order Injection)

[[网鼎杯 2018]Comment]] 是一个典型的二次注入。

  • 流程
    1. 写入:在一个功能点(如“写留言”)插入恶意的 SQL 语句。此时,addslashes() 等函数会转义特殊字符,但数据被原样存入了数据库。
 # 在 category 字段插入恶意语句,利用 content 字段执行查询
     title=12&category=12',content=(select(load_file("/etc/passwd"))),/*&content=123
  1. 读取:在另一个功能点(如“查看留言”)读取之前插入的数据。此时,应用从数据库中取出未转义的恶意语句并再次拼接到新的 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 代码。
  • PayloadX-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 对 protectedpublic 同名属性不敏感的特性,用 public 声明来绕过对 protected 属性不可见字符的检查。
    • 强类型比较绕过:在 __destruct 中,$this->op === "2" 的判断可以通过传入数字 2 而不是字符串 "2" 来绕过,从而触发读文件逻辑。

3.2 Python Flask/Bottle Session 伪造

Flask 和 Bottle 的 session cookie 如果密钥泄露或为弱密钥,就可能被伪造。

  • [[CISCN2019 华东南赛区]Web4]] & [[HCTF 2018]admin]]
    • 通过 LFI 或源码泄露找到 SECRET_KEYSECRET_KEY 的生成可能与 MAC 地址等固定值有关,导致其可被预测。
    • 使用 flask-session-cookie-manager 等工具,传入 SECRET_KEY 和想要伪造的 session 内容,生成新的 cookie。
  • [[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=../) 将我们自己制作的、Poweradminuser.gob 文件解压覆盖掉原来的文件。
    • 再次访问 /backdoor 时,反序列化新的 gob 文件,获得 admin 权限,触发 goeval.Eval RCE。

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 escapeshellargescapeshellcmd 连用绕过

[[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 来执行命令,绕过审计。
  • [[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 包含自身,并通过注释写入一句话木马。

这次总结收获颇丰,很多知识点串联了起来。接下来要继续深入研究,拓宽知识面。