一次逻辑漏洞的代码审计(0day-通杀)
字数 1021 2025-08-29 08:29:58
逻辑漏洞代码审计与利用:绕过登录限制漏洞分析
漏洞概述
本文档详细分析了一个存在于某ERP系统中的逻辑漏洞,该漏洞允许攻击者绕过正常的登录限制,直接进入系统后台。漏洞的核心在于系统对登录状态验证逻辑存在缺陷,通过简单的响应包修改即可实现未授权访问。
漏洞详情
漏洞位置
- 文件路径:
lianjieerp_new/app/src/Endpoint/Web/Users/LoginController.php - 路由:
/users/checklogin(POST请求)
漏洞原理
- 系统接收
username和password参数进行登录验证 - 定义了一个
code参数,初始值为-1 - 系统首先检查
confirm_password是否为空- 如果为空,进入else分支
- 在else分支中,如果session有效或账号密码正确,则将
code设为1
- 关键漏洞点:系统仅检查
code是否为1或3来决定是否允许进入后台 - 攻击者可以通过拦截登录响应包并修改
code值为1或3来绕过验证
代码分析
关键代码结构
// 路由定义
Route::post('/users/checklogin', 'LoginController@checkLogin');
// LoginController.php中的关键逻辑
public function checkLogin(Request $request) {
$username = $request->input('username');
$password = $request->input('password');
$code = -1; // 初始code值为-1
// 检查confirm_password
if (!empty($confirm_password)) {
// 某些处理逻辑
} else {
// 如果session有效或账号密码正确
if ($validSession || $validCredentials) {
$code = 1;
}
}
// 关键验证点
if ($code == 1 || $code == 3) {
// 允许进入后台
return redirect('/admin');
} else {
// 登录失败
return back()->withErrors(['登录失败']);
}
}
漏洞关键点
- 状态码依赖:系统完全依赖
code值来决定是否允许访问,而没有其他验证机制 - 客户端可控:
code值可以通过拦截和修改响应包来操纵 - 缺乏完整性校验:响应数据没有签名或加密保护,容易被篡改
漏洞复现步骤
-
正常登录尝试
- 使用任意账号密码发送登录请求
- 示例请求:
POST /users/checklogin HTTP/1.1 Host: target.com Content-Type: application/x-www-form-urlencoded username=test&password=123456
-
拦截响应
- 使用代理工具(Burp Suite等)拦截服务器响应
- 典型响应可能包含
code字段:{ "code": -1, "message": "登录失败" }
-
修改响应
- 将
code值修改为1或3 - 修改后的响应示例:
{ "code": 1, "message": "登录成功" }
- 将
-
放行响应
- 客户端收到修改后的响应后,系统会认为登录成功
- 自动跳转到后台管理界面
漏洞利用条件
- 能够拦截客户端与服务器之间的通信
- 系统未对响应数据进行完整性保护
- 前端完全信任后端返回的
code值
修复建议
-
服务器端验证增强
- 在跳转后台前增加session验证
- 不要仅依赖单一状态码进行权限判断
-
响应数据保护
- 对关键响应数据进行签名
- 使用HTTPS防止中间人攻击
-
代码逻辑修正
// 修正后的验证逻辑 if (($code == 1 || $code == 3) && $validSession) { return redirect('/admin'); } -
增加二次验证
- 对于敏感操作增加CSRF Token验证
- 实现双因素认证
总结
该漏洞展示了逻辑缺陷在Web应用安全中的重要性。开发人员不应仅依赖客户端可修改的参数进行关键权限判断,而应该结合服务器端状态验证。审计时应特别关注:
- 权限判断逻辑是否完备
- 是否存在可绕过的主流程判断
- 关键参数是否可被客户端篡改