欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创]The Game of iGameGuardian7.3.1

[原创]The Game of iGameGuardian7.3.1

引子
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

上传的附件 1.png
2.png
3.png
4.png
5.png
6.png
7.png
8.png
9.png
10.png
11.png
The Game of iGameGuardian7.3.1.pdf
iGGbins.7z

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功