从SSO认证缺陷到任意用户登录漏洞
字数 1230 2025-08-23 18:31:18

SSO认证缺陷到任意用户登录漏洞分析

1. SSO单点登录概述

单点登录(SSO, Single Sign-On)是一种身份验证机制,允许用户在多个系统中使用单一凭证登录。核心特点:

  • 用户只需一次登录即可访问多个系统
  • 各系统可以感知用户登录状态
  • 通常通过Token或Ticket机制实现跨系统认证

2. 漏洞发现背景

在测试中发现一个应用(A)通过SSO跳转到第三方应用(B)时存在认证缺陷:

  1. A应用根据Token颁发ticketId
  2. B应用通过ticketId获取data数据(本应作为授权凭据)
  3. 但实际流程中B应用并未使用该data数据,而是使用了自己的认证系统

3. 漏洞分析过程

3.1 初步观察

  • B应用使用独立的/auth/register接口进行认证
  • 请求和响应数据均加密处理
  • 初步怀疑存在越权漏洞

3.2 接口测试

  1. 使用不同账号(本人和李四)访问同一功能接口(query)
  2. 发现请求数据不同,推测加密后内容包含用户ID
  3. 尝试替换请求数据,但接口仍通过Token鉴权

3.3 JS加密定位

B应用加载两套JS:

  1. 通过A的统一网关根据appid发送的JS
  2. 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接口:

  1. 请求参数:身份证号+姓名+手机号(测试发现仅需正确手机号)
  2. 返回用户Token
  3. 构造其他用户的请求数据即可获取其Token

漏洞本质:B应用未正确实现SSO认证,且自身认证系统仅依赖手机号等易伪造信息。

4. 对抗升级分析

4.1 开发修复尝试

第二天开发"修复"后变化:

  1. 接口和加密格式未变
  2. 数据格式变为:
{
  "userInfo": "加密数据",
  "openId": null
}
  1. 增加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生成流程

  1. 生成8位随机字符串b
  2. 获取当前时间戳w
  3. 第一次MD5:md5(w + 加密后的data)
  4. 第二次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 根本原因

  1. B应用未正确实现SSO认证流程
  2. 自行实现的认证系统存在设计缺陷
  3. 过度依赖前端加密而非后端认证

5.2 修复建议

  1. 正确实现SSO认证流程,使用统一的Token机制
  2. 后端应严格校验用户身份,不依赖前端传递的参数
  3. 敏感操作应增加二次验证
  4. 加密算法应作为辅助手段而非主要安全措施

5.3 经验教训

  1. 前端加密无法替代后端安全控制
  2. 复杂的加密可能掩盖而非修复漏洞
  3. 认证系统设计应遵循最小权限原则
  4. 安全应建立在架构层面而非"隐藏"漏洞
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接口请求数据: 确认接口通过Token而非请求体进行身份验证。 3.5 任意用户登录漏洞 分析register接口: 请求参数:身份证号+姓名+手机号(测试发现仅需正确手机号) 返回用户Token 构造其他用户的请求数据即可获取其Token 漏洞本质 :B应用未正确实现SSO认证,且自身认证系统仅依赖手机号等易伪造信息。 4. 对抗升级分析 4.1 开发修复尝试 第二天开发"修复"后变化: 接口和加密格式未变 数据格式变为: 增加sign值校验 4.2 二层加密破解 发现userInfo使用AES/ECB加密,解密后: 4.3 Sign值破解 sign生成算法位于第一套JS中,分析得出: sign生成流程 : 生成8位随机字符串b 获取当前时间戳w 第一次MD5: md5(w + 加密后的data) 第二次MD5: md5(第一次结果 + b) Python实现示例: 5. 漏洞总结 5.1 根本原因 B应用未正确实现SSO认证流程 自行实现的认证系统存在设计缺陷 过度依赖前端加密而非后端认证 5.2 修复建议 正确实现SSO认证流程,使用统一的Token机制 后端应严格校验用户身份,不依赖前端传递的参数 敏感操作应增加二次验证 加密算法应作为辅助手段而非主要安全措施 5.3 经验教训 前端加密无法替代后端安全控制 复杂的加密可能掩盖而非修复漏洞 认证系统设计应遵循最小权限原则 安全应建立在架构层面而非"隐藏"漏洞