从SSO认证缺陷到任意用户登录漏洞
字数 1230 2025-08-23 18:31:18
SSO认证缺陷到任意用户登录漏洞分析
1. SSO单点登录概述
单点登录(SSO, Single Sign-On)是一种身份验证机制,允许用户在多个系统中使用单一凭证登录。核心特点:
- 用户只需一次登录即可访问多个系统
- 各系统可以感知用户登录状态
- 通常通过Token或Ticket机制实现跨系统认证
2. 漏洞发现背景
在测试中发现一个应用(A)通过SSO跳转到第三方应用(B)时存在认证缺陷:
- A应用根据Token颁发ticketId
- B应用通过ticketId获取data数据(本应作为授权凭据)
- 但实际流程中B应用并未使用该data数据,而是使用了自己的认证系统
3. 漏洞分析过程
3.1 初步观察
- B应用使用独立的
/auth/register接口进行认证 - 请求和响应数据均加密处理
- 初步怀疑存在越权漏洞
3.2 接口测试
- 使用不同账号(本人和李四)访问同一功能接口(query)
- 发现请求数据不同,推测加密后内容包含用户ID
- 尝试替换请求数据,但接口仍通过Token鉴权
3.3 JS加密定位
B应用加载两套JS:
- 通过A的统一网关根据appid发送的JS
- B应用自身的JS
定位技巧:
- 优先关注index.js、app.js等常见文件
- 使用HAE插件匹配加密算法名称或密钥
- 关注sensitive information部分
最终在第二套JS中发现SM4加密算法及密钥。
3.4 数据解密分析
解密query接口请求数据:
{
"orderDateType": "0",
"userId": "10000", // 用户标识
"pageNum": 1,
"pageSize": 15,
"orderId": null
}
确认接口通过Token而非请求体进行身份验证。
3.5 任意用户登录漏洞
分析register接口:
- 请求参数:身份证号+姓名+手机号(测试发现仅需正确手机号)
- 返回用户Token
- 构造其他用户的请求数据即可获取其Token
漏洞本质:B应用未正确实现SSO认证,且自身认证系统仅依赖手机号等易伪造信息。
4. 对抗升级分析
4.1 开发修复尝试
第二天开发"修复"后变化:
- 接口和加密格式未变
- 数据格式变为:
{
"userInfo": "加密数据",
"openId": null
}
- 增加sign值校验
4.2 二层加密破解
发现userInfo使用AES/ECB加密,解密后:
{
"paperType": "1",
"name": "",
"paperNum": "",
"phone": ""
}
4.3 Sign值破解
sign生成算法位于第一套JS中,分析得出:
i = sm4Encrypt(JSON.stringify(i), atob(n.APP_SER));
var b = randomString(8),
w = (new Date).getTime(),
_ = md5(md5(w + i) + b);
x = {
"x-access-token": f,
"channel-code": m,
randomchar: b,
time: w,
sign: _
};
sign生成流程:
- 生成8位随机字符串b
- 获取当前时间戳w
- 第一次MD5:
md5(w + 加密后的data) - 第二次MD5:
md5(第一次结果 + b)
Python实现示例:
import hashlib
def md5_encrypt(input_string):
hash_object = hashlib.md5()
hash_object.update(input_string.encode('utf-8'))
return hash_object.hexdigest()
# 示例参数
w = "1708659397259" # 时间戳
i = "6...f90d2" # 加密数据
b = 'Z38ZzxzS' # 8位随机字符
# 计算sign
first_md5 = md5_encrypt(w + i)
second_md5 = md5_encrypt(first_md5 + b)
print(second_md5) # 最终sign值
5. 漏洞总结
5.1 根本原因
- B应用未正确实现SSO认证流程
- 自行实现的认证系统存在设计缺陷
- 过度依赖前端加密而非后端认证
5.2 修复建议
- 正确实现SSO认证流程,使用统一的Token机制
- 后端应严格校验用户身份,不依赖前端传递的参数
- 敏感操作应增加二次验证
- 加密算法应作为辅助手段而非主要安全措施
5.3 经验教训
- 前端加密无法替代后端安全控制
- 复杂的加密可能掩盖而非修复漏洞
- 认证系统设计应遵循最小权限原则
- 安全应建立在架构层面而非"隐藏"漏洞