wuzhicms 【代码审计】
字数 3892 2025-10-26 18:21:34

WuzhiCMS v4.1.0 代码审计教学文档

一、 环境与项目结构分析

在进行代码审计前,首先需要了解目标程序的基本结构和环境。

  1. 核心目录说明

    • coreframe/:框架核心目录,包含所有业务模块和核心库。
    • caches/:缓存目录,存放系统生成的各种缓存文件。
    • www/:网站Web根目录,存放对外开放的入口文件。
    • uploadfile/:用户上传文件的存储目录,是文件上传漏洞的常见挖掘点。
    • install/:安装目录。安全规范:在系统安装完成后,此目录必须删除,否则可能导致重装攻击。
  2. 关键入口文件

    • www/index.php:网站前台主入口。
    • www/admin.php:网站后台管理入口。
    • api/ 目录:提供API接口,是寻找未授权访问、逻辑漏洞和SQL注入的重点区域。

二、 漏洞审计与详解

以下将按照漏洞类型对文中发现的漏洞进行逐一剖析。

类型一:任意文件删除漏洞

  • 漏洞文件coreframe/app/attachment/admin/index.php

  • 漏洞函数del()

  • 漏洞分析
    该函数提供了两种删除附件的方式:通过附件ID ($id) 或通过附件URL ($url)。问题出在通过URL删除的逻辑上。

    1. $GLOBALS['url']获取用户输入的url参数,并经过remove_xss()函数过滤(此过滤主要用于防XSS,对路径遍历无效)。
    2. 使用 str_ireplace(ATTACHMENT_URL, '', $url) 将附件的基准URL替换为空,得到相对路径 $path
    3. 直接将 $path 拼接到 ATTACHMENT_ROOT(附件根目录)后,形成绝对路径 ATTACHMENT_ROOT . $path
    4. 调用 my_unlink($path) 函数,该函数内部直接执行 unlink($path)
  • 漏洞利用
    由于对 $path 未进行有效的路径遍历检查,攻击者可以构造特殊的 url 参数,使其指向系统任意文件。
    POC(攻击验证代码)

    http://target.com/index.php?m=attachment&f=index&v=del&_su=wuzhicms&url=../../../configs/web_config.php
    

    上述请求会将 url 参数解析为 ../../configs/web_config.php,最终拼接成类似 .../uploadfile/../../configs/web_config.php 的路径,从而跨越目录,删除重要的配置文件 web_config.php

  • 修复建议
    在删除文件前,应对 $path 进行规范化(如使用 realpath 函数),并严格校验其是否位于允许的目录(如 ATTACHMENT_ROOT)之下。

类型二:SQL注入漏洞

文中提到了多处SQL注入风险,主要原因是未对用户输入进行充分过滤就直接拼接SQL语句。

  • 漏洞点1:API接口注入

    • 漏洞文件api/sms_check.php

    • 漏洞分析
      该脚本直接使用 $GLOBALS['param'] 作为变量,并将其拼接到SQL查询语句中。

      $code = strip_tags($GLOBALS['param']); // strip_tags仅去除HTML标签,对SQL注入无效
      ...
      $r = $db->get_one('sms_checkcode',"`code`='$code' AND `posttime`>$posttime",'*',0,'id DESC');
      

      $code 变量未经任何转义或参数化处理就直接嵌入SQL字符串,导致注入。

    • 漏洞利用POC

      http://target.com/api/sms_check.php?param=1' OR extractvalue(1,concat(0x7e,(SELECT user()))) -- -
      

      此Payload会触发数据库报错,并将当前数据库用户信息显示在错误信息中。

  • 漏洞点2:后台搜索功能注入

    • 漏洞文件coreframe/app/promote/admin/index.php

    • 漏洞函数search()

    • 漏洞分析
      用户可控的 $keywords$fieldtype 变量被直接拼接进 $where 字符串。

      $where = "`siteid`='$siteid' AND `$fieldtype` LIKE '%$keywords%'";
      $result = $this->db->get_list('promote',$where, '*', 0, 20,$page,'id DESC');
      

      尽管此漏洞位于后台,需要管理员权限才能访问,但一旦攻击者通过其他手段(如钓鱼)获取了后台权限,这将是一个高危的内网渗透漏洞。

    • 漏洞利用POC

      http://target.com/admin.php?m=promote&f=index&v=search&fieldtype=place&keywords=1' OR extractvalue(1,concat(0x7e,user())) -- -
      
  • 根因探究
    框架的数据库封装方法(如 get_one, get_list)设计存在缺陷。它们接受原始的 $where 字符串进行拼接,而不是使用预编译占位符。审计时应重点关注所有调用这些方法且 $where 参数用户可控的地方。

类型三:任意文件写入/远程代码执行漏洞

  • 漏洞文件coreframe/app/core/libs/function/common.func.php

  • 漏洞函数set_cache()

  • 漏洞分析
    此函数用于生成缓存文件。关键代码如下:

    function set_cache($filename, $data, $dir = '_cache_'){
        ...
        $filename = $cache_path . $filename . '.' . CACHE_EXT . '.php';
        if (is_array($data)) {
            $data = '<?php' . "\n return " . array2string($data) . '?>';
        }
        file_put_contents($filename, $data); // 将数据写入文件
    }
    

    如果能够控制 $data 参数的内容,并且能预测或影响缓存文件的路径($filename),就可能写入一个恶意的PHP文件。

  • 关联漏洞点
    文中提到一个可能的触发点:index.php?m=attachment&f=index&v=ueditor&submit=1&setting=<php phpinfo();>。这暗示可能存在某个接口,将用户输入的数据传递给了 set_cache 函数。审计时需要寻找这类调用链。

  • 漏洞利用
    如果攻击者成功将PHP代码写入一个可通过Web访问的缓存文件中,就可以直接访问该文件来执行任意系统命令,造成RCE。

  • 修复建议
    严格校验传入 set_cache 函数的数据内容,确保 $data 是预期的序列化数据,而非原始PHP代码。对 $filename 也应做严格限制,防止目录穿越。

类型四:跨站请求伪造漏洞

  • 漏洞描述
    在WuzhiCMS 4.1.0中,后台缺乏对关键操作(如添加管理员)的CSRF Token校验。攻击者可以构造一个恶意页面或链接,诱骗已登录的管理员点击。管理员浏览器会在不知情的情况下携带其认证Cookie向CMS后台发起请求,执行添加攻击者账户等操作。
  • 漏洞利用
    攻击者创建一个HTML页面,内嵌一个自动提交的表单:
    <form action="http://target-cms.com/admin.php?m=core&f=member&v=add&_su=wuzhicms" method="POST">
      <input type="hidden" name="username" value="hacker" />
      <input type="hidden" name="password" value="hacker123" />
      <input type="hidden" name="roleid" value="1" /> <!-- 1可能是管理员角色ID -->
      <input type="submit" value="Click for a surprise!" />
    </form>
    <script>document.forms[0].submit();</script>
    
    管理员访问此页面后,一个名为 hacker 的管理员账户就被创建了。
  • 修复建议
    对所有状态变更的请求(POST、GET等)实施CSRF Token防护。为每个会话生成一个随机的Token,并在表单或请求参数中包含它,服务端验证此Token的有效性。

类型五:会话管理漏洞

  • 漏洞描述
    在登录逻辑中(coreframe/app/core/admin/index.phplogin 函数),系统在用户登录时没有重新生成Session ID,而是重用了客户端提供的Session ID。
  • 攻击场景(Session Fixation)
    1. 攻击者先访问网站,获取一个合法的Session ID(如 PHPSESSID=attacker_sess)。
    2. 攻击者构造一个指向后台登录页的钓鱼链接,并附上自己的Session ID:http://target.com/admin.php?m=core&f=index&v=login&...&PHPSESSID=attacker_sess
    3. 管理员点击此链接,使用攻击者的Session ID进行登录。
    4. 登录成功后,服务器将管理员的权限与 attacker_sess 这个Session绑定。
    5. 攻击者此时使用 PHPSESSID=attacker_sess 访问网站,便直接拥有了管理员权限。
  • 修复建议
    在用户认证成功(如登录、权限提升)后,必须调用 session_regenerate_id(true) 函数来销毁旧会话并生成一个新的、随机的会话ID。

三、 代码审计方法论总结

通过本次对WuzhiCMS的审计,我们可以总结出一些通用的PHP代码审计技巧:

  1. 入口点追踪:从 index.phpadmin.phpapi/ 目录下的文件开始,追踪用户输入($_GET, $_POST, $_REQUEST, $GLOBALS)的传递过程。
  2. 敏感函数回溯:在IDE或编辑器中全局搜索关键函数,这是最高效的方法之一。
    • SQL注入:搜索 selectget_oneget_listqueryexecute 等。
    • 文件操作:搜索 unlink(删除)、file_put_contents/fwrite(写入)、include/require(包含)。
    • 代码执行:搜索 evalassertsystemexecpassthru 等。
  3. 权限校验检查:对于后台功能(admin/ 目录下的文件),检查每个操作函数开头是否有完善的登录状态和权限校验代码。
  4. 参数过滤审视:查看程序如何过滤输入。常见的错误是只使用 strip_tagshtmlspecialchars(防XSS)来处理用于SQL查询的参数,而应该使用数据库扩展提供的参数化查询或至少使用 mysqli_real_escape_string 进行转义。

四、 结论

WuzhiCMS v4.1.0 版本在多个关键安全环节存在缺陷,包括但不限于任意文件删除、SQL注入、CSRF、会话固定等中高危漏洞。这份教学文档详细分析了这些漏洞的成因、利用方式及修复方案,为安全研究人员和开发者提供了宝贵的代码审计实战案例。在进行任何CMS的二次开发或部署前,进行彻底的代码安全审计是至关重要的一步。


免责声明:本文档仅用于安全教学和研究目的。请勿将文中所述技术用于任何非法或未经授权的测试。在使用任何开源软件时,请确保使用最新版本,并参考官方安全公告。

WuzhiCMS v4.1.0 代码审计教学文档 一、 环境与项目结构分析 在进行代码审计前,首先需要了解目标程序的基本结构和环境。 核心目录说明 coreframe/ :框架核心目录,包含所有业务模块和核心库。 caches/ :缓存目录,存放系统生成的各种缓存文件。 www/ :网站Web根目录,存放对外开放的入口文件。 uploadfile/ :用户上传文件的存储目录,是文件上传漏洞的常见挖掘点。 install/ :安装目录。 安全规范 :在系统安装完成后,此目录必须删除,否则可能导致重装攻击。 关键入口文件 www/index.php :网站前台主入口。 www/admin.php :网站后台管理入口。 api/ 目录:提供API接口,是寻找未授权访问、逻辑漏洞和SQL注入的重点区域。 二、 漏洞审计与详解 以下将按照漏洞类型对文中发现的漏洞进行逐一剖析。 类型一:任意文件删除漏洞 漏洞文件 : coreframe/app/attachment/admin/index.php 漏洞函数 : del() 漏洞分析 : 该函数提供了两种删除附件的方式:通过附件ID ( $id ) 或通过附件URL ( $url )。问题出在通过URL删除的逻辑上。 从 $GLOBALS['url'] 获取用户输入的 url 参数,并经过 remove_xss() 函数过滤(此过滤主要用于防XSS,对路径遍历无效)。 使用 str_ireplace(ATTACHMENT_URL, '', $url) 将附件的基准URL替换为空,得到相对路径 $path 。 直接将 $path 拼接到 ATTACHMENT_ROOT (附件根目录)后,形成绝对路径 ATTACHMENT_ROOT . $path 。 调用 my_unlink($path) 函数,该函数内部直接执行 unlink($path) 。 漏洞利用 : 由于对 $path 未进行有效的路径遍历检查,攻击者可以构造特殊的 url 参数,使其指向系统任意文件。 POC(攻击验证代码) : 上述请求会将 url 参数解析为 ../../configs/web_config.php ,最终拼接成类似 .../uploadfile/../../configs/web_config.php 的路径,从而跨越目录,删除重要的配置文件 web_config.php 。 修复建议 : 在删除文件前,应对 $path 进行规范化(如使用 realpath 函数),并严格校验其是否位于允许的目录(如 ATTACHMENT_ROOT )之下。 类型二:SQL注入漏洞 文中提到了多处SQL注入风险,主要原因是未对用户输入进行充分过滤就直接拼接SQL语句。 漏洞点1:API接口注入 漏洞文件 : api/sms_check.php 漏洞分析 : 该脚本直接使用 $GLOBALS['param'] 作为变量,并将其拼接到SQL查询语句中。 $code 变量未经任何转义或参数化处理就直接嵌入SQL字符串,导致注入。 漏洞利用POC : 此Payload会触发数据库报错,并将当前数据库用户信息显示在错误信息中。 漏洞点2:后台搜索功能注入 漏洞文件 : coreframe/app/promote/admin/index.php 漏洞函数 : search() 漏洞分析 : 用户可控的 $keywords 和 $fieldtype 变量被直接拼接进 $where 字符串。 尽管此漏洞位于后台,需要管理员权限才能访问,但一旦攻击者通过其他手段(如钓鱼)获取了后台权限,这将是一个高危的内网渗透漏洞。 漏洞利用POC : 根因探究 : 框架的数据库封装方法(如 get_one , get_list )设计存在缺陷。它们接受原始的 $where 字符串进行拼接,而不是使用预编译占位符。审计时应重点关注所有调用这些方法且 $where 参数用户可控的地方。 类型三:任意文件写入/远程代码执行漏洞 漏洞文件 : coreframe/app/core/libs/function/common.func.php 漏洞函数 : set_cache() 漏洞分析 : 此函数用于生成缓存文件。关键代码如下: 如果能够控制 $data 参数的内容,并且能预测或影响缓存文件的路径( $filename ),就可能写入一个恶意的PHP文件。 关联漏洞点 : 文中提到一个可能的触发点: index.php?m=attachment&f=index&v=ueditor&submit=1&setting=<php phpinfo();> 。这暗示可能存在某个接口,将用户输入的数据传递给了 set_cache 函数。审计时需要寻找这类调用链。 漏洞利用 : 如果攻击者成功将PHP代码写入一个可通过Web访问的缓存文件中,就可以直接访问该文件来执行任意系统命令,造成RCE。 修复建议 : 严格校验传入 set_cache 函数的数据内容,确保 $data 是预期的序列化数据,而非原始PHP代码。对 $filename 也应做严格限制,防止目录穿越。 类型四:跨站请求伪造漏洞 漏洞描述 : 在WuzhiCMS 4.1.0中,后台缺乏对关键操作(如添加管理员)的CSRF Token校验。攻击者可以构造一个恶意页面或链接,诱骗已登录的管理员点击。管理员浏览器会在不知情的情况下携带其认证Cookie向CMS后台发起请求,执行添加攻击者账户等操作。 漏洞利用 : 攻击者创建一个HTML页面,内嵌一个自动提交的表单: 管理员访问此页面后,一个名为 hacker 的管理员账户就被创建了。 修复建议 : 对所有状态变更的请求(POST、GET等)实施CSRF Token防护。为每个会话生成一个随机的Token,并在表单或请求参数中包含它,服务端验证此Token的有效性。 类型五:会话管理漏洞 漏洞描述 : 在登录逻辑中( coreframe/app/core/admin/index.php 的 login 函数),系统在用户登录时没有重新生成Session ID,而是重用了客户端提供的Session ID。 攻击场景(Session Fixation) : 攻击者先访问网站,获取一个合法的Session ID(如 PHPSESSID=attacker_sess )。 攻击者构造一个指向后台登录页的钓鱼链接,并附上自己的Session ID: http://target.com/admin.php?m=core&f=index&v=login&...&PHPSESSID=attacker_sess 。 管理员点击此链接,使用攻击者的Session ID进行登录。 登录成功后,服务器将管理员的权限与 attacker_sess 这个Session绑定。 攻击者此时使用 PHPSESSID=attacker_sess 访问网站,便直接拥有了管理员权限。 修复建议 : 在用户认证成功(如登录、权限提升)后,必须调用 session_regenerate_id(true) 函数来销毁旧会话并生成一个新的、随机的会话ID。 三、 代码审计方法论总结 通过本次对WuzhiCMS的审计,我们可以总结出一些通用的PHP代码审计技巧: 入口点追踪 :从 index.php 、 admin.php 和 api/ 目录下的文件开始,追踪用户输入( $_GET , $_POST , $_REQUEST , $GLOBALS )的传递过程。 敏感函数回溯 :在IDE或编辑器中全局搜索关键函数,这是最高效的方法之一。 SQL注入 :搜索 select 、 get_one 、 get_list 、 query 、 execute 等。 文件操作 :搜索 unlink (删除)、 file_put_contents / fwrite (写入)、 include / require (包含)。 代码执行 :搜索 eval 、 assert 、 system 、 exec 、 passthru 等。 权限校验检查 :对于后台功能( admin/ 目录下的文件),检查每个操作函数开头是否有完善的登录状态和权限校验代码。 参数过滤审视 :查看程序如何过滤输入。常见的错误是只使用 strip_tags 、 htmlspecialchars (防XSS)来处理用于SQL查询的参数,而应该使用数据库扩展提供的参数化查询或至少使用 mysqli_real_escape_string 进行转义。 四、 结论 WuzhiCMS v4.1.0 版本在多个关键安全环节存在缺陷,包括但不限于任意文件删除、SQL注入、CSRF、会话固定等中高危漏洞。这份教学文档详细分析了这些漏洞的成因、利用方式及修复方案,为安全研究人员和开发者提供了宝贵的代码审计实战案例。在进行任何CMS的二次开发或部署前,进行彻底的代码安全审计是至关重要的一步。 免责声明 :本文档仅用于安全教学和研究目的。请勿将文中所述技术用于任何非法或未经授权的测试。在使用任何开源软件时,请确保使用最新版本,并参考官方安全公告。