1. 漏洞背景与核心原理
这道N1CTF 2026的PWN题目名为"ez_canary",考察的是利用__stack_chk_fail函数进行劫持的技术。Canary机制作为现代栈保护的重要手段,通常被用来检测栈溢出攻击。当检测到canary值被修改时,程序会调用__stack_chk_fail函数终止执行。
在glibc的实现中,__stack_chk_fail函数会打印出错误信息并调用abort终止程序。这个函数的地址通常存储在GOT表中,而GOT表在开启RELRO保护的情况下是只读的。但题目故意设计为部分RELRO,使得我们可以通过某些方式修改这个函数的指针。
关键点:部分RELRO保护下,GOT表项在程序运行期间是可写的,这为劫持__stack_chk_fail提供了可能性
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 漏洞利用链分析
完整的利用链需要以下几个步骤:
- 首先触发栈溢出修改canary值
- 程序检测到canary被修改,调用__stack_chk_fail
- 通过信息泄露获取关键地址
- 修改__stack_chk_fail的GOT表项指向我们控制的地址
- 构造ROP链实现任意代码执行
2.1 栈布局与溢出构造
通过逆向分析可以发现,程序存在一个明显的栈溢出漏洞。在某个函数中,读取用户输入时没有正确检查长度,导致可以覆盖返回地址和canary值。
典型的栈布局如下:
code复制+-----------------+
| 局部变量 |
+-----------------+
| 保存的寄存器 |
+-----------------+
| canary值 |
+-----------------+
| 返回地址 |
+-----------------+
我们可以构造这样的payload:
code复制payload = b'A'*offset_to_canary + p64(canary) + b'B'*8 + p64(target_address)
2.2 信息泄露技术
为了成功劫持__stack_chk_fail,我们需要获取以下关键信息:
- 程序基地址
- libc基地址
- 栈地址
常见的泄露方法包括:
- 利用格式化字符串漏洞
- 通过程序
