首页
社区
课程
招聘
[原创]分享一些关于苹果iTunes授权流程的东西
2018-7-5 11:40 10150

[原创]分享一些关于苹果iTunes授权流程的东西

2018-7-5 11:40
10150
先简单聊一下苹果通信协议:

众所周知,itunes与手机通信协议内容是一串plist结构(实际是XML)的包,使用TCP协议(send函数)发送给苹果的PC端驱动,再由驱动转成USB

信号传输给手机。plist结构通常是这个样子的:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"

"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    
<key>request name</key>
<data>request data</data>
</dict>

一般这个data节点也可能是string、int之类的,以主要传输的内容定,有的为便于传输会经过base64加密,有的出于安全考虑会经过SSL加密(如

开启/关闭通信服务)。


大体上说一下授权相关流程:

主要分为四步

一、向手机请求一段证书数据,设为Data1:
主要协议包内容:
key=GetValue string=FairPlayCertificate

二、本地生成一个grappaID和对应的grappaData,将grappaData传给手机。(之前这一块困惑了挺长一段时间,之前老的流程是调用一个itunes的导出函数ATHostConnectionSendPowerAssertion,其内部同时做了生成grappaID、grappaData及向手机发送请求两步操作,因为需求要求将这两步操作分离,所以前者使用内部函数ITunesFun0来做,但是发现明明生成了grappaData和grappaID,下面一步的流程却怎么也走不通,可能有不少人卡在这里过,具体如何做的因为可能会涉及客户利益(人家有竞争对手的)不便透露,这里只粗略地讲一下流程)。
主要相关协议包如下:

<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEplistPUBLIC"-//Apple//DTDPLIST1.0//EN""http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plistversion="1.0">
<dict>
<key>Command</key>
<string>RequestingSync</string>
<key>Params</key>
<dict>
<key>DataclassAnchors</key>
<dict>
<key>Keybag</key>
<string>0</string>
</dict>
<key>Dataclasses</key>
<array>
<string>Keybag</string>
</array>
<key>HostInfo</key>
<dict>
<key>Grappa</key>  // 这一段是关键,GrappaData数据
<data>
AQEEkLjCjFKHLVG0AwLStvibAUBNHUBCyRldlZD7w0VyIC2hhsve
7hwgjWe0vPX0NNUFhMPoDGf5kqtCx1Otu/+7nzEiUcGHKwjGpwgO
FFy2808J
</data>
<key>LibraryID</key>
<string>5ac547ba5322b210</string>
<key>SyncHostName</key>
<string>LP0000</string> 
<key>SyncedDataclasses</key>
<array>
<string>Keybag</string>
</array>
<key>Version</key>
<string>12.4.3.1</string> // itunes版本
</dict>
</dict>
<key>Session</key>
<integer>1</integer>
</dict>
</plist>



三、这一步会用到一个PC端的本地授权文件afsync.rq,和一些SCInfo文件。前者经上述流程后会由手机输给PC,itunes的dll会将它保存在固定目录下,后者通过itunes的UI界面操作向苹果官方请求为当前PC授权而获得。
将此文件的内容和上面的Data1、grappaID作为关键输入数据来生成一段数据rsBuffer
此段加密一共涉及五个iTunes内部函数,相关计算参数说明如下:
 int CalcRSBuffer(char *deviceID,
                               int *itunesAttr,
                               unsigned char *fairPlayCer,// 第一步返回的证书数据
                               int fairPlayCerLen, //证书数据长度
                               long long *appidlist, // 要授权的appleid列表
                               int appidcount, // appleid列表长度
                               void *rq_buffer, //输入的rq文件
                               int rq_len, // rq文件长度
                               char *path, // SCInfo文件路径
                               unsigned char **prsBuffer,// 输出的rsbuffer
                               int *rsBufferlen) // 输出的rsbuffer长度
{
          // 依次调用五个内部函数
}

四、以rsBuffer和grappaID作为主要输入参数调用内部函数ITunesFun2生成一段数据sigBuffer, 将 sigBuffer 数据作为内容生成一个afsync.rs.sig文件,将此文件传给手机即完成授权全部过程。 既完成整个授权流程。
生成sigbuffer相关函数声明如下:
void ITunesFun2 (
unsigned char*  pRsBuffer, / / 上面生成的rsbuffer
int pRsBufferLen, // rsbuffer长度
uint32_t GrappaID,  // 上面的grappaID
unsigned char *sigBuff,  // 输出的sigBuffer
int *sigLength); // sigBuffer长度

有一些要说明的地方:

一、上述几段流程都会调用到itunes的内部函数,这些内部函数在底层是相互有关联的,所有如果grappaID或Data1、rsBuffer等数据若不正确会导
致相应的流程走不通。

二、itunes与加密有关的内部函数最终都会调用一个叫CoreFP.dll的动态库,此动态库中的代码作了大量的加密混淆、乱序等(听说苹果为了做这块混淆专门去收购了一家做代码加密的公司)。调用CoreFP的相关函数所使用到的输入参数也都是经过加密混淆的,不过还是可以搞一搞,CoreFP建议就不要去搞它了。出于精简程序的目的,上面的几个内部函数都可以完整逆出源码来,最后只需保留一个CoreFP.dll既可。

三、关于处理苹果的代码加密,如果工期催得比较紧的话,可以考虑先处理代码乱序(记得好像是通过一个全局随机种子去生成跳转地址的,在跳转之前是有一
段特征的,都可以清理掉),这样就能把汇编抠下来直接用。先把功能实现,接下来优化过程再去处理其它的代码混淆膨胀问题,最后再还原成高级语言代码。

[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。

最后于 2018-7-5 12:58 被鸡蛋面编辑 ,原因:
收藏
点赞1
打赏
分享
最新回复 (11)
雪    币: 18
活跃值: (974)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
猪会被杀掉 1 2018-7-5 16:44
2
1
暗示:Github自己找。
最后于 2018-7-5 16:45 被猪会被杀掉编辑 ,原因:
雪    币: 2371
活跃值: (2232)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
gtict 2018-7-5 22:56
3
0
可以通过模拟pc端文件,,绕过验证么?
雪    币: 5
活跃值: (356)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
鸡蛋面 2018-7-6 09:53
4
0
不大明白你说的意思
雪    币: 6818
活跃值: (153)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
聖blue 2018-7-9 23:24
5
0
雪    币: 18
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
xcoder2000 2019-4-11 23:30
7
0
能加我扣扣详谈吗
270298647
雪    币: 16
活跃值: (97)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
hcw 2019-11-23 15:24
8
0
确实会卡住,直接call 函数,EAX = FFFF59C6,Grappa key could not be established。
调接口倒是可以跑的通。不知道问题出在哪。
雪    币: 16
活跃值: (97)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
hcw 2019-12-3 16:40
9
0
hcw 确实会卡住,直接call 函数,EAX = FFFF59C6,Grappa key could not be established。 调接口倒是可以跑的通。不知道问题出在哪。
已解决,第一次的那个CALL只能调一次。
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
safesupport 2020-9-24 09:03
10
0
你好,请问像 iPhone XR 这种没有 40 位 UDID 的设备需要如何适配?试过在生成 afsync.rs 的时候会失败,具体是内部函数生成的 PrivateKey 不可用。
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
怯花颜 2023-6-1 10:49
11
0
https://github.com/iOS-Auth/iOSAuthRuntime
这里有开源服务端版本,包括新UDID编码,Grappa获取,RS生成,帐号ID授权。
雪    币: 2
活跃值: (330)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
慈悲佛祖 2024-1-27 22:05
12
0

之前研究过itunes注册和itunes登录。有kbsync算法和x_apple_ActionSignature算法。

最后于 2024-1-27 22:05 被慈悲佛祖编辑 ,原因:
游客
登录 | 注册 方可回帖
返回