reverse-skills-max: initial public release (restored, redacted, hardened)
This commit is contained in:
113
vendor-new/rev-skills/.claude/skills/re-drm/SKILL.md
Normal file
113
vendor-new/rev-skills/.claude/skills/re-drm/SKILL.md
Normal file
@@ -0,0 +1,113 @@
|
||||
---
|
||||
name: re-drm
|
||||
description: >
|
||||
DRM 分析:PlayReady/Widevine 实现、许可证流程、解密器还原。
|
||||
触发词:DRM、PlayReady、Widevine、许可证、内容保护
|
||||
capabilities: [drm-analysis]
|
||||
---
|
||||
|
||||
# DRM 分析(PlayReady / Widevine / 许可证流程)
|
||||
|
||||
## 何时使用 / 何时不用
|
||||
|
||||
- **边界(继承 [[re-cracking]])**:仅限自有内容保护方案 / 授权测试 / CTF·研究环境;禁止未授权内容解密与商业 DRM 绕过
|
||||
- 用:分析 DRM 系统(Widevine / PlayReady / FairPlay)的组件结构、许可证挑战/响应流程
|
||||
- 用:理解播放器/CDM(内容解密模块)如何管理密钥与解密内容(授权研究)
|
||||
- 用:DRM 漏洞/弱点研究(密钥提取、解密流程绕过等,**限授权环境**)并负责任披露
|
||||
- 用:CENC 加密媒体(MP4/CMAF)的 PSSH 与加密方案识别
|
||||
- 不用:普通内容保护理解/协议逆向(那是 [[re-protocol]] 域)
|
||||
- 不用:样本没有 DRM 只是普通加密([[re-crypto-*]] 系列)
|
||||
- 不用:制作盗版工具 / 提取密钥用于盗版分发(**明确禁止,见授权边界**)
|
||||
- **授权边界(必读)**:本技能仅限授权研究——自有设备、自有内容、实验室环境、已获书面许可的安全研究。禁止:提取/分发用于盗版的内容密钥、发布可用密钥提取工具、绕过 DRM 获取未授权内容。DRM 分析涉及反规避法律(如 DMCA 1201 类)与平台 ToS,分析以漏洞研究 + 防御视角产出,发现走负责任披露(厂商安全团队/漏洞奖励计划),敏感细节(密钥材料)不写入公开报告。
|
||||
|
||||
## 工具准备
|
||||
|
||||
静态分析(CDM 反编译 / 抓包分析)免沙箱;运行 CDM 与抓许可证流量属动态执行,在受控环境([[re-analyze/platform-tips]] 最高原则)内进行。所有工具先验证再使用。
|
||||
|
||||
### 反编译工作台([[re-ghidra]])—— CDM/解密器分析
|
||||
|
||||
- [[re-ghidra]](默认):导入 CDM 二进制(Widevine CDM 是带导出表的 ELF so)与播放器二进制
|
||||
- [[re-ida]]:备选;验证: 导入 libwidevinecdm.so 后能反编译 `Initialize`/`CreateSession` 类导出
|
||||
- CDM 获取(自有环境):Chrome 的 Widevine CDM 在 `~/.config/google-chrome/WidevineCdm/`(Linux)/ `%LOCALAPPDATA%\Google\Chrome\User Data\WidevineCdm`(Windows)/ `~/Library/...`(macOS);Edge 的 PlayReady 同理
|
||||
|
||||
### 网络捕获([[re-netcap]])—— 许可证挑战/响应
|
||||
|
||||
- tshark/wireshark/mitmproxy 安装见 [[re-netcap]]「工具准备」
|
||||
- 验证: `tshark --version`;`mitmdump --version`
|
||||
- HTTPS 解密按 [[re-netcap]] 步骤 4(mitmproxy CA 装入受控环境)
|
||||
|
||||
### protobuf 解析(Widevine 侧)
|
||||
|
||||
- `pip install protobuf`(或 grpcio-tools);验证: `python3 -c "import google.protobuf; print(google.protobuf.__version__)"`
|
||||
- 用途: 许可证挑战/响应是 protobuf,按字段号解析(字段表见 [[layout]])
|
||||
|
||||
### CDM 分析辅助工具(Widevine L3 设备,研究用途)
|
||||
|
||||
- 无独立发行版包:Widevine L3 CDM(软件实现)的分析工具来自社区研究(GitHub 检索 Widevine L3 相关研究仓库,如 pywidevine),安装 `pip install pywidevine`(只用于自有设备授权研究)
|
||||
- 验证: `python3 -c "import pywidevine; print(pywidevine.__version__)"`
|
||||
- 用途与边界:只分析自有设备/自有内容;密钥材料不出现在报告中(见坑 3)
|
||||
|
||||
## 操作步骤
|
||||
|
||||
按顺序执行,每步产物(组件清单、许可证流程笔记、CDM 结构笔记)记录证据路径 + sha256(见 [[re-triage]]),供报告引用。**所有步骤在授权范围与受控环境内进行**(授权边界见「何时使用」)。
|
||||
|
||||
1. **DRM 组件识别(CDM / 解密器)**:
|
||||
- 播放器/浏览器侧:EME API(`requestMediaKeySystemAccess("com.widevine.alpha")` / `"com.microsoft.playready"`)→ 定位 DRM 类型与 CDM 路径
|
||||
- CDM 组件:`libwidevinecdm.so`(Chrome 内置;**后缀标注的是架构**——`-arm`/`-arm64`/`-x86`/`-x64` 为 CPU 架构而非安全等级,L1/L3 取决于设备 TEE 信任根,无 TEE 的 ARM 设备同样跑 L3 软件实现,见坑 1);PlayReady 组件在 Edge/Windows 系统组件;FairPlay 在 Apple 侧([[re-ios]] 域)
|
||||
- CDM 导出函数(C ABI):`Initialize`、`CreateSession`(CreateSessionAndGenerateRequest)、`UpdateSession`(处理许可证响应)、`CloseSession`、`RemoveSession`、`Decrypt`、`SetServerCertificate`——导出表见 [[layout]]
|
||||
- 记录:DRM 类型、CDM 路径与版本、文件 sha256(版本锚点,坑 4)
|
||||
|
||||
2. **CENC/PSSH 识别(媒体侧)**:
|
||||
```sh
|
||||
# 在 MP4/CMAF 里找 pssh box(可脚本遍历 ISO BMFF box 链)
|
||||
grep -oba 'pssh' sample.mp4 | head
|
||||
```
|
||||
- PSSH box:`size(4) + 'pssh'(4) + version/flags(4) + SystemID(16) + [v1 才有 KID 数+KIDs] + DataSize(4) + Data`(字段表见 [[layout]])
|
||||
- SystemID 判 DRM:Widevine `edef8ba9-79d6-4ace-a3c8-27dcd51d21ed`;PlayReady `9a04f079-9840-4286-ab92-e65be0885f95`;FairPlay `94ce86fb-07ff-4f43-adb8-93d2fa968ca2`
|
||||
- DASH 侧等价物:`ContentProtection schemeIdUri="urn:uuid:EDEF8BA9-..."` + base64 `<cenc:pssh>`;加密方案字段(cenc/cbc1/cbcs)决定后续解密分析走向
|
||||
- 产物:PSSH 列表(SystemID → DRM 类型 → 初始数据),Python 解析示例见 [[examples]]
|
||||
|
||||
3. **许可证流程还原(挑战 / 响应)**:
|
||||
```sh
|
||||
# 受控环境内播放一段自有内容,mitmproxy/tshark 捕获许可证请求
|
||||
tshark -r license.pcap -Y 'http.request' -T fields -e http.host -e http.request.uri | head
|
||||
# 典型流程:初始化 → license challenge(POST,含设备指纹/证书)→ license response(含密钥材料)
|
||||
```
|
||||
- Widevine:license 请求/响应是 protobuf(SignedMessage 包裹,字段表见 [[layout]]);PlayReady:SOAP/XML(`AcquireLicense`,命名空间 `http://schemas.microsoft.com/DRM/2007/03/protocols`);内容元数据里通常带 license URL(PSSH box / manifest 字段)
|
||||
- 还原:challenge 里有什么(设备证书/非对称密钥公钥/会话 ID)→ 服务端如何验设备 → 响应里封装了什么(内容密钥 CEK 的密文 + 权限策略)
|
||||
- 产物:许可证流程图(发起方 → 挑战 → 响应 → 密钥解出)+ 各步格式与字段笔记
|
||||
|
||||
4. **解密器实现分析(密钥管理)**:
|
||||
- CDM 静态([[re-ghidra]]):导出函数还原(`Initialize`、`CreateSession`、`UpdateSession`(处理许可证响应)、`Decrypt`)→ 找密钥存储与解密路径
|
||||
- 密钥分层(见坑 2):设备密钥(device key,L3 软件密钥存于 CDM 内/持久化存储)→ 解密许可证响应拿到内容密钥(CEK)→ CEK 解密媒体;分析"哪一步解出什么密钥"
|
||||
- 解密算法识别:AES-CBC / AES-CTR 等([[re-crypto-id]] 常量表指纹思路),CENC(Common Encryption)样本格式(cenc/cbc1/cbcs 方案)
|
||||
- 产物:密钥链图(每层密钥来源与保护方式)+ 解密调用路径
|
||||
|
||||
5. **漏洞 / 弱点定位(授权研究)**:
|
||||
- 常见研究面:L3 设备密钥提取(软件密钥从 CDM 内存/持久化存储提取)、许可证响应验证缺失、防回滚(CDM 版本检查)绕过、解密前完整性校验缺失
|
||||
- 方法:静态定位(密钥解密/加载函数)→ 动态观察(受控环境内断点/插桩看密钥材料流向)→ 验证边界(什么条件下能解出什么)
|
||||
- **发现后负责任披露**:记录复现条件与影响评估,提交厂商安全团队/漏洞奖励计划;不公开 PoC 细节
|
||||
- 产物:发现清单(条件/影响/披露状态)
|
||||
|
||||
6. **报告(合规)**:
|
||||
- 报告结构:授权范围声明 → 组件清单(CDM 版本/哈希)→ 许可证流程图 → 解密器/密钥管理结构 → 发现与披露计划 → 防御建议
|
||||
- 合规要点:不包含密钥材料与可用提取工具;ToS/法律边界声明(DMCA 1201 类反规避条款);结论以漏洞研究/防御视角表述
|
||||
- 产物:报告存档(sha256)
|
||||
|
||||
## 跨域联合
|
||||
|
||||
- [[re-ghidra]]:CDM 与播放器反编译工作台(结构标注 / 脚本化分析)
|
||||
- [[re-netcap]]:许可证挑战/响应捕获(mitmproxy 解密 HTTPS,[[re-protocol]] 第 1 步联动)
|
||||
- [[re-protocol]]:许可证协议还原(challenge/response 结构、protobuf/SOAP 解析)
|
||||
- [[re-crypto-id]] / [[re-crypto-keys]] / [[re-crypto-decrypt]]:加密算法识别、密钥材料定位、密文还原
|
||||
- [[re-android-native]] / [[re-ios]]:移动端 CDM(Android 侧 Widevine 集成、FairPlay/Apple 侧)——设备侧 DRM 的延伸
|
||||
- [[re-sandbox]] / [[re-analyze/platform-tips]]:动态执行(播放自有内容/抓包)受控环境最高原则
|
||||
|
||||
## 常见坑与陷阱
|
||||
|
||||
- **L1/L3 等级差异(硬件 vs 软件)**:现象——同一个 Widevine CDM 相关样本,在 A 设备能分析的密钥结构/流程在 B 设备完全对不上,或按 L3 思路分析 L1 目标处处碰壁;原因——安全级别不同:L1 密钥在 TEE(可信执行环境)硬件中保护,L3 是纯软件 CDM 可提取可分析;架构标识:`libwidevinecdm.so` 的后缀标注的是**架构**(`-arm`/`-arm64`/`-x86`/`-x64`)而非安全等级——L1/L3 取决于设备 TEE 信任根(带 TEE 的 ARM 设备才是 L1,无 TEE 的 ARM 设备同样跑 L3,x86 平台一般只有 L3);PlayReady 同样分硬件信任根与软件实现;对策——先确认目标安全级别(设备能力/厂商文档),L3 才能做软件层密钥提取分析,L1 分析走 TEE/信任根方向(硬件安全);结论严格标注级别,不跨级别套用
|
||||
- **密钥分层(设备 / 内容)**:现象——费劲拿到一个"密钥",拿去解媒体内容却解不开;原因——DRM 是分层密钥体系:设备密钥(device key)解密许可证响应 → 得到内容密钥(CEK),CEK 才用于解密媒体;拿到的是中间某一层,或 CEK 还被权限策略(输出保护等)约束;对策——先完整还原许可证流程(步骤 3:challenge 里的设备公钥/证书、response 里的 CEK 密文),再进解密器分析(步骤 4)确认每一层"哪来的、解什么";按密钥链图核对拿到的密钥属于哪一层,缺哪层补哪层
|
||||
- **法律与 ToS 边界(仅研究)**:现象——研究产物(提取脚本、密钥材料)被用于盗版分发,研究者承担法律后果(DMCA 1201 类反规避责任、平台 ToS 违约);原因——DRM 分析产物天然可用作盗版工具,密钥提取与绕过行为可能直接违反反规避法律;对策——严格限定自有设备/自有内容/书面授权实验室;报告只写"机制如何工作"与"如何防御",不写可复现的密钥提取步骤、不附密钥材料;发现走负责任披露(厂商漏洞奖励);拿不准的边界先查授权文件再动
|
||||
- **DRM 更新频繁(结论过期)**:现象——CDM 更新后提取/分析手段全部失效,密钥轮换后旧结论作废;原因——CDM 定期更新并轮换密钥、加固反提取(加壳/混淆/密钥在内存生命周期短);对策——记录 CDM 精确版本 + 文件 sha256 + 分析时间(步骤 1);分析方法(流程还原、结构分析、分层建模)跨版本复用,具体密钥/偏移/签名不跨版本复用;分析结论按"结构/流程"组织而非"某个密钥值"
|
||||
- **PSSH 版本混用**:现象——按 v0 布局解析 v1 PSSH 后字段全错位;原因——version 字段为 1 时 KID 列表插在 SystemID 与 DataSize 之间;对策——解析先读 version(第 8 字节),v1 跳过 4+N×16 字节 KID 区再读 DataSize([[layout]] 字段表)
|
||||
- **challenge 与 response 都经 SignedMessage 包裹**:现象——直接按 LicenseRequest 解析响应失败;原因——Widevine 所有消息外层都是 SignedMessage(type 字段区分:0=license request 1=license 2=error),内层消息按 type 选 protobuf;对策——先解外层 SignedMessage 看 type,再按 type 选内层 schema([[layout]] 字段表)
|
||||
@@ -0,0 +1,139 @@
|
||||
# DRM 最小解析示例
|
||||
|
||||
示例以本机可复现的最小样本为主:PSSH 用 Python 构造并解析(ISO/IEC 23001-7 字段),Widevine protobuf 用官方测试向量与 pywidevine 同源字段号(见 [[layout]])。所有示例不涉及真实密钥材料。
|
||||
|
||||
## 1. PSSH box 解析(Python,本机可直接跑)
|
||||
|
||||
```python
|
||||
import struct
|
||||
|
||||
# 构造一个 Widevine PSSH v0(Widevine SystemID + 初始数据)
|
||||
WIDEVINE_SYSTEM_ID = bytes.fromhex('edef8ba979d64acea3c827dcd51d21ed')
|
||||
|
||||
def build_pssh(system_id, data, version=0, key_ids=()):
|
||||
body = bytes([version, 0, 0, 0]) + system_id
|
||||
if version == 1:
|
||||
body += struct.pack('>I', len(key_ids))
|
||||
for kid in key_ids:
|
||||
body += kid
|
||||
body += struct.pack('>I', len(data)) + data
|
||||
return struct.pack('>I', 8 + len(body)) + b'pssh' + body
|
||||
|
||||
def parse_pssh(buf):
|
||||
assert buf[4:8] == b'pssh', 'not a pssh box'
|
||||
size, = struct.unpack_from('>I', buf, 0)
|
||||
version = buf[8]
|
||||
sysid = buf[12:28].hex()
|
||||
off = 28
|
||||
kids = []
|
||||
if version == 1:
|
||||
n, = struct.unpack_from('>I', buf, off); off += 4
|
||||
kids = [buf[off + 16*i : off + 16*(i+1)].hex() for i in range(n)]
|
||||
off += 16 * n
|
||||
dsize, = struct.unpack_from('>I', buf, off); off += 4
|
||||
data = buf[off : off + dsize]
|
||||
return dict(size=size, version=version, system_id=sysid,
|
||||
key_ids=kids, data_len=dsize, data=data)
|
||||
|
||||
pssh = build_pssh(WIDEVINE_SYSTEM_ID, b'\x08\x10\x12\x04test')
|
||||
print(parse_pssh(pssh))
|
||||
# {'size': 40, 'version': 0, 'system_id': 'edef8ba979d64acea3c827dcd51d21ed',
|
||||
# 'key_ids': [], 'data_len': 8, 'data': b'\x08\x10\x12\x04test'}
|
||||
# size = 8(头) + 4(version/flags) + 16(SystemID) + 4(DataSize) + 8(Data) = 40 ✓
|
||||
```
|
||||
|
||||
对照要点:v0 布局 size + pssh + version/flags + SystemID + DataSize + Data;SystemID 判 DRM 类型(对照表见 [[layout]]);v1 的 KID 列表插在 SystemID 与 DataSize 之间——解析必须先读 version(坑 5)。
|
||||
|
||||
## 2. 真实媒体里找 PSSH(命令)
|
||||
|
||||
```sh
|
||||
# 简易定位(box 链遍历更可靠,见上)
|
||||
grep -oba 'pssh' sample.mp4 | head -5
|
||||
# 结构化解析用 ffprobe(ffmpeg 自带)
|
||||
ffprobe -v error -show_entries stream_tags=variant_bitrate -of json sample.mp4
|
||||
# 或 mp4dump(bento4):输出所有 box 树
|
||||
mp4dump sample.mp4 | grep -A4 pssh
|
||||
```
|
||||
|
||||
## 3. Widevine 挑战/响应结构速查(字段号对照)
|
||||
|
||||
以 pywidevine 同源 protobuf 字段号(完整表见 [[layout]])验证解析:
|
||||
|
||||
```python
|
||||
# 依赖: pip install protobuf
|
||||
# 用 grpcio-tools 从 Widevine 协议 .proto 生成后:
|
||||
# 外层 SignedMessage: msg.type 判定层(0=license request 1=license 2=error)
|
||||
# 内层 LicenseRequest: client_id(1) content_id(2) type(3) request_time(4)
|
||||
# protocol_version(6) key_control_nonce(7)
|
||||
def peek_proto(data, fields):
|
||||
"""极简 protobuf 字段窥探(varint 场景):打每字段的 字段号/类型/值头"""
|
||||
out = []
|
||||
i = 0
|
||||
while i < len(data):
|
||||
tag = data[i]; i += 1
|
||||
fno, wtype = tag >> 3, tag & 7
|
||||
if wtype == 0: # varint
|
||||
val = 0; sh = 0
|
||||
while True:
|
||||
b = data[i]; i += 1
|
||||
val |= (b & 0x7f) << sh
|
||||
if not b & 0x80: break
|
||||
sh += 7
|
||||
out.append((fno, 'varint', val))
|
||||
elif wtype == 2: # length-delimited
|
||||
ln = data[i]; i += 1
|
||||
out.append((fno, 'bytes', ln, data[i:i+ln]))
|
||||
i += ln
|
||||
else:
|
||||
break
|
||||
return out
|
||||
|
||||
# 用例:构造的 WidevineCencHeader 初始数据(见 [[layout]] WidevinePsshData 字段)
|
||||
```
|
||||
|
||||
对照要点:外层 SignedMessage 的 `type` 决定内层 schema——直接按 LicenseRequest 解析响应必错(坑 6)。
|
||||
|
||||
## 4. PlayReady 头/挑战 XML 对照
|
||||
|
||||
```xml
|
||||
<!-- 内容元数据里的 WRMHEADER(PlayReadyHeader 命名空间) -->
|
||||
<WRMHEADER xmlns="http://schemas.microsoft.com/DRM/2007/03/PlayReadyHeader" version="4.0.0.0">
|
||||
<DATA>
|
||||
<PROTECTINFO><KEYLEN>16</KEYLEN><ALGID>AESCTR</ALGID></PROTECTINFO>
|
||||
<KID>Cofu3FaCfjuAJNqKod80iw==</KID> <!-- KID GUID(小端 base64) -->
|
||||
<CHECKSUM>2u+jpp0wDIk=</CHECKSUM>
|
||||
<LA_URL>https://lic.example/rightsmanager.asmx</LA_URL>
|
||||
</DATA>
|
||||
</WRMHEADER>
|
||||
|
||||
<!-- 许可证挑战(SOAP,protocols 命名空间) -->
|
||||
<AcquireLicense xmlns="http://schemas.microsoft.com/DRM/2007/03/protocols">
|
||||
<challenge><Challenge xmlns="http://schemas.microsoft.com/DRM/2007/03/protocols/messages">
|
||||
<LA xmlns="http://schemas.microsoft.com/DRM/2007/03/protocols" Id="SignedData">
|
||||
<Version>1</Version><ContentHeader><!-- 内嵌 WRMHEADER --></ContentHeader>
|
||||
</LA>
|
||||
</Challenge></challenge>
|
||||
</AcquireLicense>
|
||||
```
|
||||
|
||||
对照要点:KID 是公开标识(对得上许可证 URL 才有后续);CHECKSUM 防 KID/密钥错配——拿到"密钥"后先按此核对再下结论(坑 2)。
|
||||
|
||||
## 5. CDM 导出表核验(Ghidra/readelf)
|
||||
|
||||
```sh
|
||||
# 自有环境 Widevine CDM(路径见 SKILL.md 步骤 1)
|
||||
readelf -d libwidevinecdm.so | grep NEEDED # 依赖链(沙箱环境核对)
|
||||
readelf -s libwidevinecdm.so | grep -E 'Initialize|CreateSession|UpdateSession|Decrypt'
|
||||
# 导出函数是静态分析入口:交叉引用到密钥加载/解密路径
|
||||
```
|
||||
|
||||
## 实现教训(内化)
|
||||
|
||||
- 分层建模先行(设备密钥 → CEK → 媒体),任何"密钥"先问属于哪一层、解什么
|
||||
- PSSH 解析先读 version;Widevine 消息先解 SignedMessage 再按 type 选 schema
|
||||
- 版本锚点(CDM 版本 + sha256 + 分析时间)是所有结论的前提
|
||||
|
||||
## 使用注意
|
||||
|
||||
- 所有步骤限授权范围与受控环境([[re-analyze/platform-tips]] 最高原则);密钥材料不进报告
|
||||
- 与 [[re-protocol]]、[[re-crypto-id]]、[[re-netcap]] 配合;本文件示例不含真实密钥材料
|
||||
137
vendor-new/rev-skills/.claude/skills/re-drm/references/layout.md
Normal file
137
vendor-new/rev-skills/.claude/skills/re-drm/references/layout.md
Normal file
@@ -0,0 +1,137 @@
|
||||
# DRM 布局:密钥分层 / CENC-PSSH / Widevine protobuf / PlayReady SOAP
|
||||
|
||||
DRM 分析的三个结构层:媒体侧(PSSH 与加密方案)、协议侧(许可证挑战/响应格式)、设备侧(CDM 导出与密钥链)。本文件给出三层的关键字段表,字段以 ISO/IEC 23001-7、Widevine protobuf(pywidevine 同源)与 PlayReady 官方规范为准。
|
||||
|
||||
## 密钥分层模型(先建层再动手)
|
||||
|
||||
```
|
||||
设备密钥 (device key, L3 软件密钥在 CDM 内/持久化存储;L1 在 TEE)
|
||||
│ 解密许可证响应(含 CEK 密文 + 权限策略)
|
||||
▼
|
||||
内容密钥 (CEK, content key)
|
||||
│ AES-CBC/CTR 解密媒体样本(cenc/cbc1/cbcs)
|
||||
▼
|
||||
明文媒体
|
||||
```
|
||||
|
||||
- 分析每层时回答"哪来的、解什么":设备密钥解许可证、CEK 解媒体——拿到中间层去解媒体必失败(坑 2)
|
||||
- CEK 通常还有权限策略约束(输出保护 HDCP 等)与短生命周期(密钥轮换)
|
||||
|
||||
## CENC PSSH box(ISO/IEC 23001-7,大端)
|
||||
|
||||
```
|
||||
offset 字段 说明
|
||||
0x00 size (u32) 整 box 字节数(含自身)
|
||||
0x04 'pssh' (u32) 类型(0x70 73 73 68)
|
||||
0x08 version (1B) + flags (3B) version 0 / 1
|
||||
0x0C SystemID (16B) DRM 系统 UUID
|
||||
[version=1 时] KID count (u32) + KIDs (16B×N)
|
||||
0x? DataSize (u32) 初始数据长度
|
||||
0x? Data DRM 特定初始数据(Widevine 为 WidevineCencHeader protobuf)
|
||||
```
|
||||
|
||||
### SystemID 对照表
|
||||
|
||||
| DRM | SystemID |
|
||||
|---|---|
|
||||
| Widevine | `edef8ba9-79d6-4ace-a3c8-27dcd51d21ed` |
|
||||
| PlayReady | `9a04f079-9840-4286-ab92-e65be0885f95` |
|
||||
| FairPlay | `94ce86fb-07ff-4f43-adb8-93d2fa968ca2` |
|
||||
| Common (v1) | `1077efec-c0b2-4d02-ace3-3c1e52e2fb4b` |
|
||||
|
||||
- EME keySystem 字符串:`com.widevine.alpha` / `com.microsoft.playready` / `com.apple.fairplay`
|
||||
- DASH 等价:`ContentProtection schemeIdUri="urn:uuid:EDEF8BA9-..."` + base64 `<cenc:pssh>`
|
||||
- 媒体加密方案:cenc(AES-CTR)/ cbc1(AES-CBC)/ cbcs(模式保留,样本级加密)——决定解密分析走向
|
||||
|
||||
## Widevine 消息(protobuf)
|
||||
|
||||
所有客户端-服务端消息外层为 SignedMessage,按 type 选内层 schema。
|
||||
|
||||
### SignedMessage(外层)
|
||||
|
||||
| 字段号 | 名称 | 说明 |
|
||||
|---|---|---|
|
||||
| 1 | type | 0=license request 1=license 2=error |
|
||||
| 2 | msg | 内层序列化消息(按 type 解析) |
|
||||
| 3 | signature | 签名(会话密钥/设备密钥派生) |
|
||||
| 4 | session_key | 会话密钥(RSA-OAEP 封装) |
|
||||
| 5 | remote_attestation | 远程证明 |
|
||||
|
||||
### LicenseRequest(type=0 时的内层)
|
||||
|
||||
| 字段号 | 名称 | 说明 |
|
||||
|---|---|---|
|
||||
| 1 | client_id | ClientIdentification(设备证书/指纹) |
|
||||
| 2 | content_id | ContentIdentification(oneof) |
|
||||
| 3 | type | 1=NEW 2=RENEWAL 3=RELEASE(首次获取恒 NEW) |
|
||||
| 4 | request_time | Unix 秒(客户端时钟) |
|
||||
| 6 | protocol_version | 恒 CURRENT(协议版本 21) |
|
||||
| 7 | key_control_nonce | u32 随机数(31 位),参与 CMAC 密钥派生 |
|
||||
| 8 | encrypted_client_id | 隐私模式(AES-CBC 加密的 ClientIdentification) |
|
||||
|
||||
### ClientIdentification
|
||||
|
||||
- 1=token(TOKEN_TYPE_KEYBOX 或 DEVICE_CERTIFICATE)、2=client_info(name/value 对)、3=provider_info、4=supported_protocols(含 3=SRM 等)、5=key_control_nonces(老式)
|
||||
|
||||
### ContentIdentification(oneof content_id_variant)
|
||||
|
||||
| 变体号 | 名称 | 说明 |
|
||||
|---|---|---|
|
||||
| 1 | widevine_pssh_data | WidevinePsshData:pssh_data、key_ids、content_id、protection_scheme、crypto_period_* |
|
||||
| 2 | webm_key_id | WebM(header + license_type) |
|
||||
| 3 | existing_license | 续期/释放(引用已有 license) |
|
||||
| 4 | init_data | 原始 init data(隐私/非标准 PSSH) |
|
||||
|
||||
### License(type=1 时的内层)
|
||||
|
||||
- 1=license_identification(request_id + session_id)、2=content_key_info[](每条:1=key_id、2=key_type(SW_SECURE_CRYPTO/SW_SECURE_DECODE/HW_SECURE_CRYPTO/HW_SECURE_DECODE/HW_SECURE_ALL)、3=key(CEK 密文)、4=permissions)、3=certificate、4=protection_scheme
|
||||
- key_type 等级与安全级别(L1/L3)对应——设备侧能力决定能拿到哪种 key
|
||||
|
||||
## PlayReady 许可证(SOAP/XML)
|
||||
|
||||
- 命名空间三件套:头 `http://schemas.microsoft.com/DRM/2007/03/PlayReadyHeader`;协议操作 `http://schemas.microsoft.com/DRM/2007/03/protocols`(`AcquireLicense`/`LicenseResponse`);消息包裹 `.../protocols/messages`
|
||||
- 挑战:`AcquireLicense` → `challenge` → `LA`(SignedData,Version=1 + ContentHeader 内嵌 WRMHEADER)
|
||||
- 响应:`Response` → `LicenseResponse` → 加密 `License` blob(base64)
|
||||
|
||||
### WRMHEADER(PlayReady 头,version 属性 4.0.0.0+)
|
||||
|
||||
```xml
|
||||
<WRMHEADER xmlns="http://schemas.microsoft.com/DRM/2007/03/PlayReadyHeader" version="4.0.0.0">
|
||||
<DATA>
|
||||
<PROTECTINFO><KEYLEN>16</KEYLEN><ALGID>AESCTR</ALGID></PROTECTINFO>
|
||||
<KID>base64-KID</KID> <!-- 4.1+ 为 VALUE/ALGID/CHECKSUM 属性形式 -->
|
||||
<CHECKSUM>base64-checksum</CHECKSUM>
|
||||
<LA_URL>https://.../rightsmanager.asmx</LA_URL>
|
||||
</DATA>
|
||||
</WRMHEADER>
|
||||
```
|
||||
|
||||
- KID 是公开的密钥标识 GUID(小端字节序 base64);CHECKSUM 防 KID/密钥错配
|
||||
- 服务端按 KID 查/派生内容密钥(key seed + KID 派生算法)
|
||||
- FairPlay(Apple 侧):SPC(Server Playback Context,设备证书+会话)→ CKC(Content Key Context,含 CEK 密文)——由 [[re-ios]] 域延伸
|
||||
|
||||
## CDM 导出函数(libwidevinecdm.so,C ABI)
|
||||
|
||||
| 导出 | 作用 |
|
||||
|---|---|
|
||||
| Initialize | 初始化 CDM 实例(allow_distinctive_identifier / allow_persistent_state 等标志) |
|
||||
| CreateSession | 建会话(session_type + init_data_type + init_data),产出挑战 |
|
||||
| UpdateSession | 喂许可证响应(服务端返回的 license 消息) |
|
||||
| CloseSession / RemoveSession | 关会话 / 删持久会话 |
|
||||
| Decrypt | 解密样本(InputBuffer → 明文;无密钥返回 kNoKey) |
|
||||
| SetServerCertificate | 设置服务端证书(隐私模式/会话密钥封装) |
|
||||
|
||||
- 静态分析入口:导出函数 → 交叉引用到密钥加载/解密路径
|
||||
- 接口带版本号(ContentDecryptionModule_7/8/11),同一导出名不同版本行为有差异
|
||||
|
||||
## 版本差异要点
|
||||
|
||||
- PSSH version 0(老)vs 1(新,带 KID 列表)——解析先读 version
|
||||
- Widevine 协议版本 CURRENT=21(字段号稳定,但服务端可能拒绝旧协议)
|
||||
- PlayReady WRMHEADER:4.0 的 KID 元素 → 4.1+ 的 VALUE/ALGID/CHECKSUM 属性形式
|
||||
- CDM 每季度更新:分析方法跨版本复用,密钥/偏移/签名不跨版本复用
|
||||
|
||||
## 使用注意
|
||||
|
||||
- 所有动态步骤在受控环境内([[re-analyze/platform-tips]] 最高原则);密钥材料不进报告
|
||||
- 与 [[re-protocol]](协议结构)、[[re-crypto-id]](算法识别)、[[re-netcap]](抓包)配合使用
|
||||
Reference in New Issue
Block a user