如何利用printf漏洞突破canary保护
@TOC
使用的实例代码如下
为了配合本次实例的教学,大家在编译时,不加pie保护,加cannary保护,整个的流程就是,分析程序之后,编写exp,利用printf漏洞(填充func函数,使其返回地址为exploit函数)来突破canary并且覆盖ret。
之后使用gdb开文件,查看func函数
来自英语白痴的小tip:
我们可以大概搞清楚func的流程,就是先read,然后printf,然后read,就是这样子。
我们下断就下到printf这里,我输入的测试用例是HHH
我们回去看一下代码,输出的格式format我们没有给,所以默认的输出就是esp+4,现在我们来看一下栈吧,也就是0x28
这里查看的canary的值,也就是0x619da200,我们在stack中找到他,然后计算一下canary和栈顶之间的偏移量是多少
我们重新运行,并且用一下format格式,也就是我输入的%15$08x,上图还是断到了printf函数,我们n,看看输出了什么
然后我们查看一下stack 0x28,看看canary的值
也就是我们输出的那个值。
我们成功的将cannary的值输出了,那我们就可以写exp了
上面就是exp了,现在我给大家讲一下exp为甚这样子写
首先导入pwn包,然后process()捕捉进程,然后计算canary的偏移,就是canary和输入的字符串的距离,第二个红框和第三个红框之间的距离,也就是8,所以canary_offset = 8*4(个字节)
canary_offset * ‘a’ 就是把那8行填充为垃圾数据’a’
然后加上canary了,然后定义个变量,canary
首先要发送泄露的地址,也就是p.sendline(%15&08x) 这里就是我们一开始查看的那个,这个格式是一个string.format(),然后我们要接收这个泄露的地址,所以就是canary = recv(),然后打印出canary,是为了测试一下canary对不对,这个写不写无所谓的,后面的[:8],是因为记录了回车,也就是那个\n,但是我们不需要它,所以只要8位就可以了。
payload目前是:canary_offset * ‘a’ + canary
然后我们应该把ret的那段也填充了,所以创建一个变量ret_offset为什么是3*4,如下图
现在的payload是:canary_offset * ‘a’ + canary + ret_offset * ‘a’
然后我们要加上然后地址,我们要getshell,然后的地址应该是函数exploit(),我们在gdb中用dissass exploit来查看,如下图
设置新变量exploit_add = p32(0x08049192) p32 告诉电脑这是个32位地址
最后就是sendline,给第二个read(大家回头看看程序的代码)发送payload
最后一步获取运行时环境p.interactive()
还有比较重要的一点就是在我们接收到的canary是人眼看到的正序,但是呢程序是小端存储,所以我们要把canary变成倒叙传给程序,也就是canary = cannary.decode(“hex”)[::-1]
大功告成
我们运行一下exp,看下图:
getshell成功!!!!!!!!
希望大家可以有所收获!!!!!!!
exp写起来太恶心了,但是写完的时候是真的爽,pwn基础篇完结撒花,呱唧呱唧!!!!
- 点赞
- 收藏
- 关注作者
评论(0)