You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

存在Canary但无法获取其值时,如何利用BOF漏洞?

带Canary保护的BOF漏洞利用方案探讨

题目代码

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void func(int key){
    char overflowme[32];
    printf("overflow me : ");
    gets(overflowme);   // smash me!
    if(key == 0xcafebabe){
        system("/bin/sh");
    }
    else{
        printf("Nah..\n");
    }
}
int main(int argc, char* argv[]){
    func(0xdeadbeef);
    return 0;
}

问题描述

这段代码中的gets()函数存在明显的缓冲区溢出漏洞,但目标二进制编译时开启了Canary保护,无法直接溢出缓冲区。在没有格式化字符串泄露的情况下,除了暴力破解外,还有哪些可行的方法可以获取Canary值以完成漏洞利用?


可行的替代方案

1. 逐字节爆破Canary(高效版暴力破解)

这是CTF中最常用的方案,比全量暴力破解效率高得多:

  • Canary的最后一个字节固定为0x00(用于终止字符串,避免被strcpy等函数泄露),所以实际需要爆破的字节数为3个(32位程序)或7个(64位程序)。
  • 构造溢出 payload,每次覆盖Canary的一个字节,尝试所有可能的256个值,如果程序没有崩溃(说明猜中了该字节),就固定这个字节,继续爆破下一个字节。
  • 如果程序采用fork子进程处理请求的架构,爆破过程不会导致主进程崩溃,完全可以通过脚本自动化完成,耗时极短。

2. 栈帧重叠利用

如果程序存在重复调用目标函数(func)的机会(比如循环结构、可重复触发的交互逻辑),可以利用栈帧的重叠特性:

  • 第一次调用时,构造溢出覆盖Canary的部分字节,记录不崩溃的情况;第二次调用时,栈帧的位置可能和第一次重叠,基于之前的结果继续爆破剩余字节,逐步拼接完整的Canary值。

3. 堆内存关联泄露

如果程序存在堆操作(malloc/free)且有堆泄露漏洞,可尝试寻找栈Canary到堆内存的拷贝路径:

  • 某些场景下,栈上的Canary会被意外复制到堆内存中(比如结构体拷贝、字符串操作时的内存复制)。如果能泄露堆中的对应内存区域,就可以提取出Canary值。不过这种方法依赖程序的具体实现,通用性较弱。

4. 异常上下文泄露

如果程序未正确处理内存错误信号(如SIGSEGV),可以构造溢出触发崩溃,从异常上下文(寄存器值、崩溃快照)中提取Canary:

  • 部分环境下,程序崩溃时会输出寄存器或栈内存的部分信息,若Canary恰好出现在这些信息中,就能直接获取。但这种方法受限于目标环境的配置,在严格的CTF场景中可用性较低。

内容的提问来源于stack exchange,提问作者Roman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 12:15:39