闲得蛋疼,对iTunes 登陆过程进行了初步的分析。 解密得到了spd字段内容。 将分析过程写出来,混个熟脸。
在分析这个东西之前, 需要做一些准备工作。 比如收集论坛前辈们的工作经验, github上某些开源代码。
通过对iTunes windows 和iOS10.x 系统进行抓包。 发现数据包基本是大同小异,iOS 调试非常不方便,特别构造win7 x86环境对 iTunes 12.6.20 进行了逆向分析。
加上 标准版OD + 海风StrongOD, 开始了这次逆向分析。
在分析之前,大概介绍下apple的这套东西,和平日玩windows逆向的区别。 iTunes 或者mac iTunes 或者 iOS 的绝大部分代码是完全一样的。
对登陆过程进行抓包
服务器地址 https://gsa.apple.com/grandslam/GSService2 数据是通过post传输。数据分为2部分
1. header 苹果的header和浏览器的header不同的是,他喜欢携带"设备", "签名"类信息
2. body body中的核心数据是用AES256_CBC加密的
整个登陆协议是非常标准的srp 密钥交换协议。 对SRP协议不熟悉的朋友可以参考下rfc文档,苹果并没做比较大的变更。
通讯过程如下
1. reqeust1 : 客户端计算随机数A = g^a mod N 其中 g = 2 , a 随机。 N是一个2048bit的大素数。 A这个数字用base64编码后被放在request body的A2K字段
其余字段比如CPD 主要是描述硬件设备信息, 电脑端和i设备会有一些出入。 这都不参与密码验证的计算
2. response1: 服务器根据SRP协议计算出B 回包如下
回包内容中 s 是一个16字节的salt值,该值是固定的,srp协议要用到。
B 也是一个大数。 客户端根据B 计算M1
3. request2: 客户端提交M1 服务器校验密码的正确性。 SRP协议厉害的地方是对称加密的密钥是通过协商计算出来的。 非传输得到。
根据SRP协议, 服务器拿到M1后,就可以校验客户端的密码是否正确。 并返回结果给用户。 如果正确,会返回M2给用户,这样密码协商就完成。
4.Response2
登陆成功后, 服务器返回了M2, np, spd. 其中np用于校验spd解密。 spd 字段是用aes加密的。 aes的解密key ,我暂时算不出来,通过扣代码的方式,能正确的解出
spd内容。
SPD 字段中你会得到几个ID 和token ,这些token 是用于后续登陆authenticate服务器用。 由于整个登陆过程是比较标准的SRP协议。分析起来有参照。 完全无脑的往后干。
SRP协议中,
hash算法, 苹果使用的hash 比较奇怪,我没能完全的模拟出来, 该hash代码看起来和sha256是一模一样的,很多地方能够重复验证。
但是在计算M1时, 就不行。 后来是通过扣代码的方式将M1计算出来,并得到gsa.apple.com服务器的认证。
在这个会话过程中,暂不涉及到header的复杂计算。 http头的内容,你随便怎么填,苹果服务器也有点累吧,懒得搭理你。你爱咋咋。
为了得到高质量的并发client, 做了很多种失败的尝试。
1. 想去重现苹果的hash算法, 在分析中,发现他的算法虽然像sha256, 但在补位 (sha_ltc_comress)迭代过程中,数据总是对不上。
2. 想完美的将代码柔和到自己的模块中, 直接LoadLibrary加载iTunes 是不行的 x86 和x64 不行, x86拿到x64上也不行。 32->64之后,很多IAT是乱填的不知道为什么
即使x86平台上, LoadLibrary虽然能成功, 但内部依然有很多IAT函数没得到修正, 各种崩。
勉强能用的
1. 多开iTunes, 并注入dll, 架设一个client的服务器, 对M1提供计算服务。 该方法勉强能用, 比较麻烦的是, iTunes中很多代码是用oc编写, 构造出的oc 指针,你需要在合适的时候释放掉。 由此导致的崩溃就不计其数了。
2. 在同一个进程中保存多个会话的instance。 涉及全局变量并不多, 可以在出入口加锁。
这样instance之间不会相互干扰。 如此一来,并发的登录账号服务器就搭建完毕。 在网络畅通的情况下,
2秒左右能得到一个账号的会话token。并支持并发操作。
后续:
后续的会话中,包头需要用到设备信息和signature, 这些算法是苹果的掌中宝, 想窥探其中奥秘是需要花费非常大的时间代价。
尤其keybag的逆向。 keybag 模块提供了signature kbsync sbsync 计算的服务,
涉及加密的东西,最终都会落到keybag。 而整个keybag模块, x86 x64, arm* ,苹果都做了类似的处理,号称几百万行汇编代码。
这些代码中充斥着大量的垃圾运算。 本人才疏学浅,实在没法参透其中奥秘。
以signature为例,
github上有代码是直接getproxy的形式得到了 keybag计算所需要的魔数, 现版本中,该魔数是与会话相关联的,
人为的call函数构造C++类,得到的魔数,在计算的时候,会被认出来, 导致hash失败。 更低级的方式构造魔数,得到的就是crash。
actionSignature计算:
itunes的base = 0
keybag 模块中硬件断点经常会失效, int3断点,偶尔会导致崩溃。
本文由看雪论坛 ppbb 原创 转载请注明来自看雪社区