吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 5366|回复: 22
收起左侧

[Web逆向] 某网站 clearkey SPC CKC解密分析

  [复制链接]
我是不会改名的 发表于 2025-9-13 23:24

某网站 clearkey 分析

网站有两种 DRM:WidevinebiliDRM(clearkey)


1. 获取 Key

单纯拿 key 都很简单,下个插件,随便找个 L3 就能拿到 key。

项目地址:
https://github.com/DevLARLEY/WidevineProxy2

img.png


2. 分析过程

2.1 关闭 Widevine DRM

edge://flags/ 中关闭 Widevine DRM:
img.png

JS 不过多分析了,扣代码也很容易,基本直接用就行。


2.2 定位加密位置

很容易定位到加密位置,请求和处理响应分别是:

  • biliDRMGenSPC
  • biliDRMParseCKC

img.png


2.3 biliDRMGenSPC 分析

根据提示,传入分别是:

说明:

  • MB = malloc(WASM 导出函数 C)
  • RB = free(对应函数 z)

传入函数 _biliDRMGenSPC

  • kid 指针
  • aeskey 指针
  • 公钥指针、长度
  • 返回值长度指针
  • 返回值指针的指针

img.png


2.3.1 wasm 层函数

WASM 层对应函数是 x,利用 jeb 分析 导出全部函数。

jeb 交叉引用不起作用,导出来用其他软件分析。

img.png

从后往前分析:

  • param0 对应返回值
  • v51 = 长度

函数 f44 多次调用:

  • 传入代码行号和返回值
  • 不为 0 → 报错并返回 0
  • 为 0 → 返回 1 继续执行

img.png
img.png


2.3.2 函数 f131

函数 f131 多次调用,并带有日志。
稍微分析变化 → 得出是内存拷贝

img.png
img.png
img.png

在 f131 下断点,打印每次传入参数大小,可以看出大致分为几段:

  • 0–8
  • 8–24
  • 24–40
  • 40–168
  • 168–188
  • 188–192
  • 192–240

img.png


2.3.3 各段数据分析
0–8

固定的 8 字节 "bilibili"

8–24
  • 8–20 固定
  • 20–24 写入时间戳

img.png
img.png

24–40

随机 16 字节

某处调用是循环,很明显是随机生成。
img.png

40–168

长度 128 + 公钥 → RSA 加密后的内容

加密前的内容可直接修改传入公钥,利用对应私钥解密。
调用 f619 → 对 JS 随机生成的 aeskey 进行 RSA 加密。

img.png
img.png

168–188

对公钥进行 SHA1

img.png
img.png

188–192

后续数据长度

img.png
img.png

192–240

倒推,最后调用 f226,明显是 AES 加密

  • key = 传入的 aeskey
  • iv = 前面随机生成的 24–40 字节

img.png
img.png

密文由几部分组成,同样调用 f131 组合:

  • 第一部分(16字节):目前固定值
    img.png

  • 第二部分(16字节):调用 f226(ECB 模式),加密 kid 前 16 字节

  • 第三部分(16字节):kid 后 16 字节
    img.png


总的组成如下结构

SPC = Struct(
    "bilibili" / Bytes(8),  # 固定 bilibili
    "header" / Bytes(12),   # 固定
    "time" / Int32ub,       # 时间戳
    "iv" / Bytes(16),       # 随机生成的 IV 
    "cipher_key" / Bytes(128),  # RSA 加密后的 AES 密钥 
    "sha" / Bytes(20),      # RSA 公钥的 SHA1 哈希值 
    "contentKeyCtxSize" / Int32ub,  # AES 加密后的 KID 上下文长度 
    "contentKeyCtx" / Bytes(this.contentKeyCtxSize),  # AES 加密后的 KID 上下文
)

KID = Struct(
    "salt" / Bytes(16),
    "enc_kid" / Bytes(16),  # 加密后的 kid 前 16 字节 
    "kid" / Bytes(16),      # kid 后 16 字节
)

2.3 biliDRMParseCKC 分析

biliDRMParseCKC搞定了上面就很简单了
主要就是aes解密

CKC = Struct(
    "header" / Bytes(12),
    "time" / Int32ub,
    "iv" / Bytes(16),
    "data_len" / Int32ub,
    "data" / Bytes(this.data_len),#第一次解密全部,第二次解密后16字节,转为hex就是key
)

img.png

3. 总结

总的来说并不难,很多符号和提示都给了,还用的openssl里面的库。



免费评分

参与人数 15吾爱币 +17 热心值 +14 收起 理由
521105 + 1 + 1 用心讨论,共获提升!
happyjack + 1 谢谢@Thanks!
fiscivaj + 1 谢谢@Thanks!
fengbin8606 + 1 + 1 我很赞同!
13955925361 + 1 + 1 用心讨论,共获提升!
fengbolee + 2 + 1 用心讨论,共获提升!
soyiC + 1 + 1 用心讨论,共获提升!
mjhwzwg6 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
制冷设备 + 2 + 1 我很赞同!
allspark + 1 + 1 用心讨论,共获提升!
pp67868450 + 1 + 1 用心讨论,共获提升!
mscsky + 1 + 1 我很赞同!
daxz + 1 + 1 谢谢@Thanks!
greendays + 1 + 1 谢谢@Thanks!
4everlove + 2 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

4everlove 发表于 2025-9-14 00:19
顺藤摸瓜翻到了一个19年的旧版源码,里面DRM逻辑好相似,大佬有没有兴趣分析一波
bilibiliplayer/bilibiliplayer/js/player/drm.ts at master · MotooriKashin/bilibiliplayer
https://github.com/MotooriKashin ... er/js/player/drm.ts
li5323923 发表于 2025-10-13 11:38
大神,你那个优酷hook的已经挂了,能不能更新一下啊,现在一用就是“TS下载重试次数超过限制,下载失败!”
头像被屏蔽
hudianman 发表于 2025-9-14 17:19
Niklaus 发表于 2025-9-15 11:30
支持,研究研究

免费评分

参与人数 1吾爱币 -15 收起 理由
RS水果 -15 本版块禁止『灌水』或回复与主题无关内容,违者重罚

查看全部评分

putitree 发表于 2025-9-15 22:08
楼主厉害了,我表示一点也看不懂

免费评分

参与人数 1吾爱币 -15 收起 理由
RS水果 -15 本版块禁止『灌水』或回复与主题无关内容,违者重罚

查看全部评分

kll545012 发表于 2025-9-16 16:35
liming123458 发表于 2025-9-15 08:20
很好,可惜不玩游戏

这个跟游戏没关系吧~~这是视频网站下载视频时候需要的一个key
l2399007164 发表于 2025-9-17 03:19
看起来有些吃力,看来还需要多学学这块的东西了
xwlsjs 发表于 2025-9-17 09:38
厉害,感谢大佬的教程
Yafd8 发表于 2025-9-18 09:29
厉害了,感谢分享
changdage 发表于 2025-9-19 11:02
学到了,谢谢分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-2-19 08:12

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表