原文地址:http://ibcker.me/how-to-make-a-xcodeghost/
前奏
这两天已经被这货刷屏了,大家都在讨论影响却无人提及原理。我斗胆出来写下实现过程,让大伙有个深入了解,以后也能更好的防范
分析过程
开始写这篇博客时,已经有各公司的分析过好几遍了,例如乌云的文章,加上昨天源码也已经开源,功能上神秘的面纱基本揭开。但是问题在于作者只开源功能代码,并没提及注入原理,也就是这个代码是如何被注入到你写的APP里的~
寻找受感染的Xcode
由于鄙人比较倒霉,花了真真两天也没找到,这归功于百度网盘,把所有xcode的分享全取消分享了,加上作者也在清理犯罪证据,所以···
不过好在最后还是弄到了一份,可以继续了···
首先用有问题Xcode建立了个Demo。为了验证Demo是否编译后会被注入后门,我打算用比较简单点的办法,打个断点··· 阅读源码后发现发部分逻辑是在UIWindow的category里写的,例如这个方法明显UIWindow里没有:
-(void)Check{
if ([self Debugger]) {
return;
}
if ([UIApplication sharedApplication].applicationState!=UIApplicationStateActive)
return;
NSInteger timestamp = [[NSDate date] timeIntervalSince1970];
...
}
所以下断点
运行,果然断下来了
所以表明这个Xcode确实有问题,并且category名也和源码里的完全吻合。所以可以入手这篇博客的主题了-如何制造一个XcodeGhost
开工
制造一个XcodeGhost的关键点其实是如何写一个Framework并在编译时链接进去。
所以问题主要只有两个:
1.写一个framework
2.编译时如何链接
问题1有很多现成的教程,在此简单过一下就好
1.新建工程,选动态库,起个名字并保存
2.新建个UIWindow的category,写入hook代码
@implementation UIWindow (hook)
+ (void)load
{
NSLog(@"hello,This is a XcodeGhost test");
}
@end
把framework改为静态类型
2.编译后得到目标framework
注意选择对应要测试的目标设备(真机还是模拟器,测试阶段为了简单就不合并了)
问题一解决,把写好的framework放到Demo工程里测试,结果OK(记得先加上-ObjC 的flag)
问题二比较棘手,由于不熟悉Xcode的内部结构,不太清楚如果定位修改那里会导致编译时自动链接自己写的gohst,不过好久好在有一个有问题的Xcode,尝试看下编译日记,发现了如下线索
然后grep整个xcode目录去寻找CoreService,在
/Applications/Xcode.app/Contents/PlugIns/Xcode3Core.ideplugin/Contents/SharedSupport/Developer/Library/Xcode/Plug-ins/CoreBuildTasks.xcplugin/Contents/Resources/Ld.xcspec
中定位到
接下来就是替换尝试了,紧跟后面加上
-force_load $(PLATFORM_DEVELOPER_SDK_DIR)/Library/Frameworks/MyXcodeGhost.framework/MyXcodeGhost
并把MyXcodeGhost.framework拷贝到
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/Library/Frameworks/MyXcodeGhost.framework
重启Xcode后run,结果成功完成了注入~~
根据Ld.xcspec的这个ALL_OTHER_LDFLAGS
配置项的字面意思应该不难理解,这项控制的应该和咱们平时用的Ohter Linker Flags
差不多,只不过这个相当于默认配置,一般用户无感知,隐藏性更好,也就更加危险。
{
Name = ALL_OTHER_LDFLAGS;
Type = StringList;
DefaultValue = "$(LD_FLAGS) $(SECTORDER_FLAGS) $(OTHER_LDFLAGS) $(OTHER_LDFLAGS_$(variant)) $(OTHER_LDFLAGS_$(arch)) $(OTHER_LDFLAGS_$(variant)_$(arch)) $(PRODUCT_SPECIFIC_LDFLAGS) -force_load $(PLATFORM_DEVELOPER_SDK_DIR)/Library/Frameworks/MyXcodeGhost.framework/MyXcodeGhost";
CommandLinePrefixFlag = "";
}
本文重在探索学习,请勿滥用~
感谢XcodeGhost给我们所有人上了一课!尼玛,城里人真会玩!