记对某CMS的一次代码审计
字数 894 2025-08-25 22:58:20

某CMS认证逻辑缺陷漏洞分析与复现

漏洞概述

该CMS在处理登录认证时存在设计缺陷,导致admin用户可以在不校验密码的情况下直接登录系统。漏洞源于SQL查询语句逻辑设计不当,使得密码验证条件被绕过。

漏洞分析

1. 认证流程分析

  1. 初始登录页面oa.php?c=Public&a=login

    • 加载login.tpl模板文件
    • 表单提交到oa.php?c=Public&a=check_login
  2. 认证处理流程

    • 验证码检查(如果启用)
    • 账号密码非空检查
    • 特殊处理:当用户名为admin时直接设置ADMIN_AUTH_KEY会话变量
    • 构造查询条件并调用check_login方法

2. 关键漏洞代码

问题SQL语句(位于source/model/oa/model.login.php):

$sql = "SELECT * FROM ".DB_PREFIXOA."user WHERE emp_no='".$emp_no."' OR name='".$emp_no."' AND is_del='".$is_del."' AND password='".$password."'";

SQL逻辑问题

  • 由于AND优先级高于OR,实际执行逻辑为:
    SELECT * FROM PREFIXOA_user 
    WHERE (emp_no='admin') 
    OR (name='admin' AND is_del='0' AND password='[md5值]')
    
  • 当用户名为admin时,emp_no='admin'条件始终为真,导致整个WHERE条件为真
  • 正确设计应为:
    $sql = "SELECT * FROM ".DB_PREFIXOA."user WHERE ((emp_no='".$emp_no."') OR (name='".$emp_no."')) AND (is_del='".$is_del."') AND (password='".$password."')";
    

3. 认证绕过流程

  1. 提交admin账号和任意密码
  2. 系统构造SQL查询
  3. 由于SQL逻辑问题,返回admin用户记录
  4. 系统认为认证成功,设置会话变量:
    $_SESSION['USER_AUTH_KEY'] = $auth_info['id'];
    $_SESSION['emp_no'] = $auth_info['emp_no'];
    $_SESSION['user_name'] = $auth_info['name'];
    // 其他会话变量...
    
  5. 重定向到oa.php,完成登录

漏洞复现步骤

  1. 访问登录页面:

    http://[target]/oa.php?c=Public&a=login
    
  2. 在登录表单中输入:

    • 用户名:admin
    • 密码:任意值(如123456
  3. 提交表单,观察是否成功登录系统后台

修复建议

  1. 修改SQL查询逻辑

    $sql = "SELECT * FROM ".DB_PREFIXOA."user 
            WHERE (emp_no=? OR name=?) 
            AND is_del=? 
            AND password=?";
    
  2. 使用预处理语句

    • 采用参数化查询防止SQL注入
    • 使用PDO或mysqli预处理
  3. 加强认证逻辑

    • 移除对admin账号的特殊处理
    • 严格验证所有认证条件
  4. 日志记录

    • 记录失败的登录尝试
    • 监控异常登录行为

总结

该漏洞展示了SQL查询逻辑设计不当可能导致的安全问题。开发人员应当:

  1. 仔细设计SQL查询逻辑,必要时使用括号明确优先级
  2. 避免在认证流程中加入特殊例外
  3. 采用安全的数据库查询方式
  4. 对关键业务流程进行充分的测试和安全审计

通过此案例,我们认识到即使是看似简单的SQL语句,如果逻辑设计不当,也可能导致严重的安全漏洞。

某CMS认证逻辑缺陷漏洞分析与复现 漏洞概述 该CMS在处理登录认证时存在设计缺陷,导致admin用户可以在不校验密码的情况下直接登录系统。漏洞源于SQL查询语句逻辑设计不当,使得密码验证条件被绕过。 漏洞分析 1. 认证流程分析 初始登录页面 : oa.php?c=Public&a=login 加载 login.tpl 模板文件 表单提交到 oa.php?c=Public&a=check_login 认证处理流程 : 验证码检查(如果启用) 账号密码非空检查 特殊处理:当用户名为 admin 时直接设置 ADMIN_AUTH_KEY 会话变量 构造查询条件并调用 check_login 方法 2. 关键漏洞代码 问题SQL语句 (位于 source/model/oa/model.login.php ): SQL逻辑问题 : 由于AND优先级高于OR,实际执行逻辑为: 当用户名为 admin 时, emp_no='admin' 条件始终为真,导致整个WHERE条件为真 正确设计应为: 3. 认证绕过流程 提交 admin 账号和任意密码 系统构造SQL查询 由于SQL逻辑问题,返回admin用户记录 系统认为认证成功,设置会话变量: 重定向到 oa.php ,完成登录 漏洞复现步骤 访问登录页面: 在登录表单中输入: 用户名: admin 密码:任意值(如 123456 ) 提交表单,观察是否成功登录系统后台 修复建议 修改SQL查询逻辑 : 使用预处理语句 : 采用参数化查询防止SQL注入 使用PDO或mysqli预处理 加强认证逻辑 : 移除对admin账号的特殊处理 严格验证所有认证条件 日志记录 : 记录失败的登录尝试 监控异常登录行为 总结 该漏洞展示了SQL查询逻辑设计不当可能导致的安全问题。开发人员应当: 仔细设计SQL查询逻辑,必要时使用括号明确优先级 避免在认证流程中加入特殊例外 采用安全的数据库查询方式 对关键业务流程进行充分的测试和安全审计 通过此案例,我们认识到即使是看似简单的SQL语句,如果逻辑设计不当,也可能导致严重的安全漏洞。