首页
社区
课程
招聘
[原创]The Game of iGameGuardian7.3.1
2016-11-28 10:34 14949

[原创]The Game of iGameGuardian7.3.1

2016-11-28 10:34
14949
引子
iGG(iGameGuardian)是一款不错的内存修改器。在iOS6的时候就在用,最近心血来潮,用了下,发现新版本要收费了。然购买后却一直不能激活成功,可能是我这个iOS设备上装的东西多,环境太复杂。等待问题解决时,习惯性的把执行文件拖到IDA里看了下,于是一场游戏就这样开始了。
作者的介绍网站在这里
http://igg6-aquawu.rhcloud.com/
Cydia加入下面源进行安装
http://aquawu.github.io/igg/
或者直接安装附件里的deb包。

初次闯关的完败
第一个执行文件/Applications/iGameGuardian.app/loader
idv.aqua.iGameGuardian_7.3.1_iphoneos-arm.deb安装后,gg_daemon.plist文件被复制到
/System/Library/LaunchDaemons和/Library/LaunchDaemons目录下,并启动该服务。
这是一个后台守护进程,服务名为idv.aqua.iGameGuardian.plist,执行文件是/Applications/iGameGuardian.app/loader
cat /Library/LaunchDaemons/gg_daemon.plist 
...
        <string>idv.aqua.iGameGuardian.plist</string>
...
        <key>ProgramArguments</key>
                <string>/Applications/iGameGuardian.app/loader</string>
# launchctl list | grep idv.aqua.iGameGuardian.plist
2078    -44     idv.aqua.iGameGuardian.plist
ps -ef | grep 2078
    0  2078     1   0   0:00.00 ??         0:00.02 /Applications/iGameGuardian.app/loader

第二个执行文件/Applications/iGameGuardian.app/iGameGuardian
这是GUI前台程序,通过点击屏幕上的App图标启动
无论前台程序iGameGuardian是否运行,这个后台守护进程一直在执行。
当GUI前台启动后, -[LoaderManager doConnectDaemon]函数会连接tcp 127.0.0.1:4084
如果连接失败,Syslog提示LM connect failed. GUI界面提示"Please reboot your device"
当然重启后,launchd会扫描到刚才提到的gg_daemon.plist 文件,重新启动这个服务。

loader是socket server,可以把他叫做LM(LoaderManager) Server,bind在4084端口上。他会输出调试信息到stdout,因为他是由lanuchd孵化的,继承父进程属性,stdout被定向到 /dev/null,所以什么也看不到。
在ssh的shell上执行loader,会得到错误信息bind failed: Address already in use。
但是kill这个进程他又会自动重启,本身就是守护进程嘛。
貌似没有插脚的地方,不过我们可以先关闭这个服务。
# launchctl unload /Applications/iGameGuardian.app/gg_daemon.plist
在等端口释放后(这可能需要点时间),再运行。这时运行GUI,可看到loader收到的1014命令字,以及其应答的2141命令字。
# /Applications/iGameGuardian.app/loader
loader-daemon start~~~~~
[C -> S] Message: 1014, 0, 0, 0
[S -> C] Message: 2141, -1, 0, 0
GUI上一直看到的错误"Please contact the developer for help."
是因为 -[DMessage param1]返回的内容是个负数,而这个负数和2141命令字返回的这个-1相关。貌似这个返回值是1的话,GUI就可以正常下去了。
修改这个返回值并不麻烦,但绕开服务器激活真的就这么简单么?

华丽的跪倒:
其实不然,因为这样做又回到了一个熟悉的错误"Please reboot your device"。
但这次错误和之前并不一样,而是在-[DaemonManager doConnectDaemon],他要连接tcp 127.0.0.1:1524
这显然告诉我们一个叫做DM(DaemonManager) Server的存在。但deb安装包里再没有别的执行文件了。

再看看DaemonManager的实例方法,跪了,敢情实现搜索功能的核心代码根本就不在安装包里。
作者说不提供试用测试,这原因这个吧。激活的目的就是要补全这个DM Server?
为了死的瞑目,继续看服务器激活这部分代码,也就是loader中对1014命令字的处理。
首先会判定"/var/mobile/Library/com.apple.gg.record4.plist"文件的内容,这个文件用来保存激活的状态,里面存了一个int32_t的值。
第一次不存在的时候会做一次服务器激活,激活失败的话写入-1,成功写入1。
如果激活失败了,下次启动GUI,触发loader读到这个-1的时候,就进入一个20次的循环。

这个循环导致连续启动20次GUI都会看到错误 "Please contact the developer for help."
帮助文档里也说,遇到这个错误你需要连续启动iGG 20次。
https://www.zybuluo.com/twjacy/note/481705
iGG 提示 Please contact the developer for help.(请联系开发者)
打开 iGG 点击 Close,循环操作 20 次,之后会提示 Loading... 完成后可能会提示 Please reboot your device.(请重启你的设备),请直接点击 Close,再次打开 iGG 即可。
话说我当时看到这个信息,一下就蒙B了,不带这么折腾人的吧。
这样做的好出,难道就是降低激活服务器的负载?
但代码告诉我们,可以删掉这个文件,或者添加一个叫做"/Applications/iGameGuardian.app/FORCE2"的文件,来强制触发激活操作。

激活的过程中,会向服务器"igg6-aquawu.rhcloud.com" 的CGI Authentication73,做post。提交的信息有24个字节,从下面的00 00 07 00开始

00 00 07 00    固定值,标定版本iGG 7.x ?
d1 2c 45 1a    iGameGuardian文件的checksum
72 76 ef d4    loader文件的checksum
00 00 00 00    fixed
xx xx xx xx xx xx  wifi mac addr
00 00      fixed

checksum的计算方法:
int igg_checksum(const char *fname, uint32_t *checksum)
{
  uint8_t *buf;
  uint32_t sum = 0x1505;
  int i, fsize;
  
  buf = load_file(fname, &fsize);
  if(NULL == buf)
    return -1;
  for(i=0; i<fsize; i++)
    sum = buf[i] + 33*sum;
  *checksum = sum;
free(buf);
  return 0;
}
1. 如果修改过这两个文件,显然服务器会知道。
2. 如果服务器里没有wifi mac地址的购买记录,他也会不应答,如下:

3. 如果服务器查到购买记录,应答的数据是一个执行文件,被保存在/tmp/service目录并执行,执行后这个文件会自动删除。
4. 从帮助文档里看到一个激活重置的概念,如果做过激活操作,服务器进行了记录,不再应答该mac的CGI Authentication73的请求(看到上面4个00就是了)。这时需要申请做重置。

这里还要扒一扒"/Applications/iGameGuardian.app/timestamp"这个文件。
每次GUI启动,请求loader的1014命令时,会检查这个文件,文件的内容是uint32的值,保存一个时间值。如果这个值比当前时间早7天以上,先用当前时间覆盖,然后会触发
"igg6-aquawu.rhcloud.com" 的CGI Weekly73请求,同样下载一个程序放在/tmp/service目录执行。
所以说,如果你装了iGG731,不管你是否激活成功,恭喜你,你已经开启了一个每7天就可能触发一次的远程执行漏洞,root权限的...
作者可能本意只是想告诉大家,有新版本的到来吧。但是想干什么完全取决于服务器上放的mach-o文件。

现在看的很清楚,快用复活币吧,什么?你不想花钱?Game Over!

满血复活
当复活币带着清脆的声响投入时,仿佛听到背景音乐响起,“在这个风起,云涌的战场上,暴风少年登场...”.
排除万难,有一天终于激活成功了,虽然没捕获到/tmp/service样本,但这个文件的执行结果告诉我们,他获取了iOS设备的wifimac地址信息,以及iGG731在安装时,loader文件创建的时间这两个参数。作者要求提供蓝牙mac地址,这可能是预留给以后用的吧。同时也说明,重装等任何导致loader文件创建的时间变化的行为,都会最终导致重新激活。

/tmp/service的执行,给我们安装了下面六个文件:
/usr/libexec/gg_trigger
/Library/LaunchDaemons/com.apple.gg.daemon.plist
/System/Library/LaunchDaemons/com.apple.gg.daemon.plist
/System/Library/LaunchDaemons/com.apple.gg.gate1.plist
/System/Library/LaunchDaemons/com.apple.gg.gate2.plist
/System/Library/LaunchDaemons/com.apple.gg.gate3.plist

com.apple.gg.daemon.plist文件是/usr/libexec/gg_trigger守护进程的服务描述,该服务由loader接受1014名字字时通过launchctl启动。
他是不是就是上面提到的bind在1524端口上的DM Server呢?
非也,没看到还有3个gate文件么?
三才者,天地人。三光者,日月星... 
为什么是3个文件,搞不明白,但显然我们要穿过这三个门。
gg_trigger的任务是从gate1.plist里解出/tmp/gate1来执行,gate1解/tmp/gate2,gate2解/tmp/gate3。
gate3就是那个bind在1524端口上的DM Server,用来接受GUI的搜查请求,完成搜索。
这种架构可以写一个PC上的GUI端,这样进行操作和扩展的时候,可能更方便一些。

既然这些gate是关键所在,所以代码上是做了些保护的。主要反映在反调试上。
首先是ptrace(PT_DENY_ATTACH, 0, 0, 0);禁止attach
其次是通过systcl CTL_KERN,KERN_PROC、KERN_PROC_PID获取进程状态,判断p_flag的P_TRACED位,来判断进程是否被调试。
最后是检查nvram中的wifiaddr,在老的iOS版本中,wifi驱动会获取这个参数替换实际mac地址,而wifimac又是做设备唯一性判断的条件,检查这个也是顺理成章的。

对于gatexxx.plist文件,使用128Bits AES CBC进行了加密。
首先作者并没有使用系统库自带的CCC加密函数,这样做太容易被分析。
仔细把玩,发现所使用的代码和下面这份完全一致。
https://github.com/Proxmark/proxmark3/blob/master/armsrc/aes.c
作者不用AesCtxIni而是使用内部函数AesGenKeySched进行初始化,有可能就是为了增加分析的难度。
作者在算法的使用上进行了调整,29个数据块中,有一个使用和0xaa的xor来代替aes。

IV隐藏的非常巧妙,在代码段中。


乍看这个函数,也没多想,只是觉得R12没有赋值就跳转,难道不会Crash?
仔细想,其实sub_9580只被赋值给R1,并没有执行,对吧,没说是sub就一定要执行啊。
切换到hexview页面,了然了:

gg_tigger、gate1、gate2使用上面同样的IV,key却都不相同,但key的产生都是围绕着wifi mac地址,和loader文件的创建时间。
gg_tigger的key

gate1的key

gate2的key


BOSS掉落
本地激活的实现流程:
1. 检查是否安装了iGG,以及版本是否正确
2. 检查是否nvram中设置了wifimac参数
3. 获取wifi mac地址,和loader的安装时间
4. 直接释放
/usr/libexec/gg_trigger
/Library/LaunchDaemons/com.apple.gg.daemon.plist
/System/Library/LaunchDaemons/com.apple.gg.daemon.plist
5. 根据IV和相应的Key做加密,生成
/System/Library/LaunchDaemons/com.apple.gg.gate1.plist
/System/Library/LaunchDaemons/com.apple.gg.gate2.plist
/System/Library/LaunchDaemons/com.apple.gg.gate3.plist
6. 更新/var/mobile/Library/com.apple.gg.record4.plis的内容为1,告诉程序,已经激活。
7. 更新/Applications/iGameGuardian.app/timestamp为当前时间加上5年,跳过7天的服务器检查,你可以加一万年只要不溢出
That's All.

流程的优化:
逻辑上说可以删掉上面第5步骤,4中用gate3的内容来填充gg_trigger,实际测试发现的确可以这样做。

这样就跟iOS设备的mac地址,以及loader安装时间无关了。
而且只是释放和修改文件,似乎可以合并到deb包里。

代码在
https://github.com/jerryxjtu/iggLocalActivator

可使用附件中预编译好的文件。
# ./iggactivatorM1
iGameGuardian7.3.1 local activator, by jerryxjtu

+ check igg version
nvram: Error getting variable - 'wifiaddr': (iokit/common) data was not found
+ check wifi mac setting in nvram
+ get wifi mac
+ get installed timestame
+ install /usr/libexec/gg_trigger
+ install /Library/LaunchDaemons/com.apple.gg.daemon.plist
+ install gate1/2/3
+ update /var/mobile/Library/com.apple.gg.record4.plist
+ update /Applications/iGameGuardian.app/timestamp
+ done!

# ./iggactivatorM2 
iGameGuardian7.3.1 local activator, by jerryxjtu

+ check igg version
+ get installed timestame
+ install /usr/libexec/gg_trigger
+ install /Library/LaunchDaemons/com.apple.gg.daemon.plist
+ update /var/mobile/Library/com.apple.gg.record4.plist
+ update /Applications/iGameGuardian.app/timestamp
+ done!

Enjoy playing games in your own way!
Have Fun

附件:
The Game of iGameGuardian7.3.1.pdf
iGGbins.7z

阿里云助力开发者!2核2G 3M带宽不限流量!6.18限时价,开 发者可享99元/年,续费同价!

上传的附件:
收藏
点赞1
打赏
分享
最新回复 (5)
雪    币: 174
活跃值: (205)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
rainyx 1 2016-11-28 10:38
2
0
坐着沙发慢慢看
雪    币: 10263
活跃值: (2285)
能力值: ( LV5,RANK:71 )
在线值:
发帖
回帖
粉丝
joker陈 2016-11-28 10:45
3
0
恭喜楼主,精华+1
雪    币: 534
活跃值: (988)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
eroy 2016-11-28 21:35
4
0
精辟的IOS9001 2000服务!
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
nkodder 2017-2-21 14:06
6
0

good

雪    币: 210
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
sunjunps 2017-6-11 03:29
7
0
貌似还有暗桩。安装后第一次能进,搜索一次内存后,再次切换时,还是提示初始化失败那个英文。。。之后无论怎么执行Iggactivator都无效了。
游客
登录 | 注册 方可回帖
返回