文章目录
从0开始的pwn学习之随意pwnpwn(1)----两种绕过canary(金丝雀)的实例
做两道简单的pwn(因为刚刚学,可能难免会有错误,望师傅们轻点骂)
众所周知,绕过canary的方法除了一个一个猜字节(不是),还有两种常见方法
(1)通过覆盖00字符读出canary
(2)通过格式化字符串漏洞泄露canary
金丝雀基础知识
Canary 的意思是金丝雀,来源于英国矿井工人用来探查井下气体是否有毒的金丝雀笼子。工人们每次下井都会带上一只金丝雀。如果井下的气体有毒,金丝雀由于对毒性敏感就会停止鸣叫甚至死亡,从而使工人们得到预警。
canary是如何工作的
在函数初始化的时候回初始化一个随机的canary值置于缓冲区的末端,在函数返回之前会对canary的值进行验证,无误则正常返回。
如下图
原理
因为通过格式化字符串漏洞可以实现任意内存的读写,而且,在一个程序里,不同函数在运行中使用的canary值是相同的,所以可以通过对格式化字符串漏洞的利用,或用覆盖00字符的方法,将canary的值读出来,实现缓冲区溢出攻击后(控制RET地址),在函数退出验证前再将canary 的值填回栈中,通过验证实现函数的正常返回
覆盖00字符读出canary
原理
- canary的值设计为以0x00结尾,防止read,printf等函数直接读出
- 通过栈溢出覆盖最低位的字节,从而获得canary
利用条件
- 存在read/printf等读出字符串的函数
- 可以两次栈溢出
- 第一次是覆盖00字节,得到canary
- 第二次是利用canary进行攻击
实例–bugku现在的pwn4
首先,我们来checksec一下
发现,对got表进行半保护,即got表可读,有金丝雀,有NX(无法写入shellcode),地址不随机。
那么,反编译看看吧。
首先看看有没有奇怪字符串,发现惊喜
发现奇怪hint函数,跟进查看,再次发现惊喜
于是发现是简单绕过canary的题,没有格式化字符串漏洞,于是选择通过覆盖00字符读出canary
用gdb看一眼
可以看出金丝雀放在rbp-0x8的位置,设断点运行,看一眼金丝雀的地址
看一眼
重新开始,发现改变,确定此处就是金丝雀
那么思路到这里就结束了。
进行准备工作用ROPgadget找一下rdi和/bin/sh
于是扔脚本
from pwn import *
import struct
context.log_level = 'debug'