《九阴真经: iOS黑客攻防秘籍》新书发布,干货满满,快来看看吧!

iOS 安全论坛 - 专注于研究 iOS 安全

 找回密码
 立即注册
查看: 2131|回复: 13

AWZ爱伪装的原理分析与破解

[复制链接]

86

主题

262

帖子

1049

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1049
发表于 2019-8-27 21:25:10 | 显示全部楼层 |阅读模式
简介
爱伪装(AWZ)/爱立思(ALS)是一款iOS越狱系统上的改机工具,可以修改多种系统参数达到伪装设备型号及各种软硬件属性的目的,同时提供了防越狱检测机制,常用于iOS上的推广刷量,配合代理/VPN使用。 除了AWZ以外,该软件商还有类似工具ALS/HBS/IGG/LRN/NZT/AXJ等,功能大体一致。AWZ/ALS支持iOS 7/8/9/10/11/12的全息备份,一键新机功能。

最后授权时间改为2100-01-01,永久使用

AWZ伪装哪些参数?
  • IDFA
  • IDFV
  • 用户名
  • 系统版本
  • 设备型号,固件版本
  • User-Agent
  • 移动网络运营商信息
  • 地理位置
  • uname / sysctl等参数
  • WIFI SSID BSSID
  • IMEI
  • 序列号
  • MAC地址

AWZ有哪些屏蔽刷机检测的手段?
  • VPN隐藏
  • 代理隐藏
  • WIFI隐藏
  • 反越狱检测,越狱文件检测/模块检测/APP检测等

AWZ的Cydia源
als.ucydia.com      ALS     11.0.5
awz.ucydia.com      AWZ     10.0.5
hbs.ucydia.com      HBS     2.0.1           
awz.itouchgo.com    AWZ     10.0.5
apt.awzcn.com       ALS     11.6.5     
apt.awzcn.com       AWZ     8.2.5
apt.awzcn.com       AWZ     10.5.7   
apt.abogeek.com     ALS     11.6.5
apt.abogeek.com     AWZ     8.2.5
apt.abogeek.com     AWZ     10.5.7

分析要点
  这里只做学习讨论改机原理及AWZ自身反逆向机制
  AWZ安装后,有如下文件
  • /Applications/AWZ.app 主程序,用于生成改机参数
  • /Library/LaunchDaemons/dhpdaemon.plist 用于daemon方式执行DHPDaemon,用于帮助AWZ实现一些隐藏操作
  • /usr/bin/DHPDaemon
  • /MobileSubstrate/DynamicLibraries/ALS.{dylib,plist},该tweak通过hook一些可以获取系统属性和app属性的C函数和ObjC函数实现的修改app参数

第一阶段
  • AWZ属性2755防止加载tweak
  • 存在restrict段,防止被加载tweak
  • 存在syscall函数进行ptrace系统调用,存在ptrace函数,以及svc汇编指令实现的ptrace,防止调试器附加

  对于restrict段和汇编指令反调试的处理,解法就是patch文件然后重签名,但是要写一个通用的命令是比较困难的,慢慢收集吧,这里提供的方式如下:
  1. sed -i 's/RESTRICT/RXSTRICT/g' AWZ
  2. sed -i 's/\x80\x52\x01\x10\x00\xd4/\x80\x52\x1f\x20\x03\xd5/g' AWZ
复制代码
对于文件属性和函数级的反调试,方法不再赘述,写tweak即可

第二阶段
在第一阶段破解后,仍然是闪退的,此时反调试已经去除,所以可以加调试器看检测点
  • 砸壳
  • -[NSBundle executablePath]检测主进程文件是否被修改
  • _dyld_get_image_name检测tweak模块
  • sysctl检测进程的p_flag是否有调试器flag
  • isatty检测终端
  • ioctl(TIOCGWINSZ)检测终端
  • fopen检测主进程文件是否被修改(在DHPDaemon中)
  • posix_spawn检测/Application/AWZ.app下是否存在超过3M的文件(补丁啊)

  对于砸壳,因为已经破解所以方法很多,当然我还是推荐我的frida脱壳脚本https://github.com/lichao890427/personal_script/blob/master/Frida_script/ios_dump.js;其他函数检测方法不再赘述,写tweak即可

第三阶段
在第二阶段后,不闪退了,但是显示注册码过期
  • 解密栈字符串,AWZ和DHPDaemon几乎全用的栈字符串混淆,蛮体力活的
  • 定位到注册的函数,一方面通过socket通信,用加密本机信息获取软件激活状态,另一方面通过cjson反序列化回写注册状态。
  • 定位get_json_value函数,该函数为c层cjson解析函数,用于从json数据的到key对应的value,该函数刚好位于socket网络通信,解密响应得到json数据后。
  • 还原ObjC函数调用关系
  • system函数会独立向服务器验证激活码,如果校验不过会删除backup文件,这样操作记录都没了,但是并没实际删除,可通过fopen检测绕过

  控制软件注册状态的主要字段是status和expiry_date,分别对应注册状态及过期时间字符串,其中status字段含义为:
  1. enum {
  2.     STATE_LOCKED = 0,        // 已锁定
  3.     STATE_NORMAL = 1,        // 已激活
  4.     STATE_INACTIVE1 = 2,    // 未激活
  5.     STATE_OUTDATE = 3,        // 激活码过期
  6.     STATE_INACTIVE2 = 4,    // 未激活
  7.     STATE_LOGOFF = 5,        // 已注销
  8.     // 其他值为已锁定
  9. };
复制代码

使用网络请求方式更新注册状态的响应中,get_json_value获取的as键对应status,aes键对应于expiry_date,另外一些字段用于激活码验证,如果不通过则结束进程,可以自行在newAppEnvClick函数中研究。
使用cjson反序列化回写注册状态逻辑存在于文件/private/var/mobile/Library/Preferences/com.app1e.mobile.ifawzcommon.plist,解密后仍然是json数据,要修改的字段如下:
  1. @{
  2.     @"authInfo": {
  3.     @"status": @0,
  4.     @"expiry_date": @"21000101080000000"
  5.     }
  6. }
复制代码

最后一点,最大的干扰可能是mapapi.bundle做了一些特殊操作,懒得去分析了,简单绕过,循环写status和date就行了。最终破解的结果就如本文开头的图,无任何限制

第四阶段
  • 捕获按钮触发的功能函数
  • 分析AWZ和DHPDaemon的notify通信,有些重要函数是AWZ调用DHPDaemon执行

  捕获按钮触发,利用frida脚本,https://github.com/lichao890427/personal_script/blob/master/Frida_script/utils.js,这里tranverse_view用于检测当前呈现的界面可以获取的元素,以及对应的响应selector,如果找按钮的回调,又不想触发,可以用这个。另外更通用的得是trace_view函数,可以拦截到所有界面消息以及响应selector,在执行点击等操作后可以得到更全的信息

下面是一些分析结果:
清理safari逻辑在函数中-[IFMagicMainVC cleanSafariClick:]
  1. // 杀死进程
  2. BKSTerminateApplicationForReasonAndReportWithDescription(__bridge CFStringRef)@"com.apple.mobilesafari", 5, 0, NULL);
  3. NSFileManager* man = [NSFileManager defaultManager];

  4. // 清理cookie
  5. NSString cookiepath = @"/var/mobile/Library/Cookies";
  6. if ([man fileExistsAtPath:cookiepath]) {
  7.     NSString* cmd = [NSString stringWithFormat:@"rm -rf %@/*", cookiepath];
  8.     system(cmd);
  9. }
  10. cookiepath = @"/private/var/root/Library/Cookies";
  11. if ([man fileExistsAtPath:cookiepath]) {
  12.     NSString* cmd = [NSString stringWithFormat:@"rm -rf %@/*", cookiepath];
  13.     system(cmd);
  14. }

  15. // 获取safari的沙盒路径
  16. NSString* safaricontainer = nil;
  17. NSString* installplist = @"/var/mobile/Library/Caches/com.apple.mobile.installation.plist";
  18. if ([man fileExistsAtPath:]) {
  19.     NSDictionary* plist = [NSDictionary dictionaryWithContentsOfFile:installplist];
  20.     id obj = plist[@"User"][@"com.apple.mobilesafari"];
  21.     if (obj == nil) {
  22.         obj = plist[@"System"][@"com.apple.mobilesafari"];
  23.     }
  24.     if (obj != nil) {
  25.         safaricontainer = obj[@"Container"];
  26.     }
  27. } else {
  28.     Class* LSApplicationProxy = NSClassFromString(@"LSApplicationProxy");
  29.     id obj = [LSApplicationProxy performSelector:applicationProxyForIdentifier: withObject:@"com.apple.mobilesafari"]);
  30.     if (obj != nil && [obj respondsToSelector:@selector(dataContainerURL)]) {
  31.         safaricontainer = [[obj performSelector:@selector(dataContainerURL)] path];
  32.     }
  33. }

  34. // 清理library
  35. NSString* libpath = [safaricontainer stringByAppendingPathComponent:@"Library"];
  36. NSString* libcachepath = [libpath stringByAppendingPathComponent:@"Caches"];
  37. if ([man fileExistsAtPath:libcachepath]) {
  38.     NSString* cmd = [NSString stringWithFormat:@"rm -rf %@/*", libcachepath];
  39.     system(cmd);
  40. }
  41. NSString* libsafaripath = [libpath stringByAppendingPathComponent:@"Safari"];
  42. if ([man fileExistsAtPath:libsafaripath]) {
  43.     NSString* cmd = [NSString stringWithFormat:@"rm -rf %@/History.*", libsafaripath];
  44.     system(cmd);
  45.     cmd = [NSString stringWithFormat:@"rm -rf %@/SuspendState.*", libsafaripath];
  46.     system(cmd);
  47. }
复制代码
清理keychain逻辑在函数中-[IFMagicMainVC cleanKeychainClick:]
  1. NSFileManager* man = [NSFileManager defaultManager];
  2. if ([man fileExistsAtPath:@"/var/Keychains/keychain-2.db"]) {
  3.   system("cp /var/Keychains/keychain-2.db /tmp/");
  4.   void* ppDb = 0;
  5.   char cmd[256];
  6.   if (0 == sqlite3_open("/tmp/keychain-2.db", &ppDb)) {
  7.     strcpy(cmd, "DELETE FROM cert WHERE agrp<>'apple' and agrp not like '%apple%' and agrp <> 'ichat' and agrp <>'lockdown-identities'");
  8.     sqlite3_exec(ppDb, cmd, 0, 0, 0);
  9.     strcpy(cmd, "DELETE FROM keys WHERE agrp<>'apple' and agrp not like '%apple%' and agrp <> 'ichat' and agrp <>'lockdown-identities'");
  10.     sqlite3_exec(ppDb, cmd, 0, 0, 0);
  11.     strcpy(cmd, "DELETE FROM inet WHERE agrp<>'apple' and agrp not like '%apple%' and agrp <> 'ichat' and agrp <>'lockdown-identities'");
  12.     sqlite3_exec(ppDb, cmd, 0, 0, 0);
  13.     system("cp /tmp/keychain-2.* /var/Keychains/");
  14.   }
  15. }
复制代码
清理pasteboard逻辑在函数中-[IFMagicMainVC cleanPastboardClick:]
  1. UIPasteboard* pb = [UIPasteboard generalPasteboard];
  2. if (pb != nil) {
  3.     NSArray* items = [pb items];
  4.     if (items != nil) {
  5.         [items removeAllObjects];
  6.     }
  7.     [pb setItems:items];
  8. }

  9. NSFileManager* man = [NSFileManager defaultManager];
  10. NSProcessInfo* proc = [NSProcessInfo processInfo];
  11. BOOL isbe8 = FALSE;
  12. NSOperatingSystemVersion ver;
  13. ver.majorVersion = 8;
  14. ver.minorVersion = 0;
  15. ver.patchVersion = 0;
  16. if ([proc respondsToSelector:@selector(isOperatingSystemAtLeastVersion:&ver)]) {
  17.     isbe8 = [proc isOperatingSystemAtLeastVersion:&ver];
  18. }

  19. NSString* pbplist = nil;
  20. NSString* pbbundle = nil;
  21. if ([man fileExistsAtPath:@"/System/Library/LaunchDaemons/com.apple.UIKit.pasteboardd.plist"]) {
  22.     pbplist = @"/System/Library/LaunchDaemons/com.apple.UIKit.pasteboardd.plist";
  23.     pbbundle = @"com.apple.UIKit.pasteboardd";
  24. }
  25. else if ([man fileExistsAtPath:@"/Library/LaunchDaemons/com.apple.UIKit.pasteboardd.plist"]) {
  26.     pbplist = @"/Library/LaunchDaemons/com.apple.UIKit.pasteboardd.plist";
  27.     pbbundle = @"com.apple.UIKit.pasteboardd";
  28. }
  29. else if ([man fileExistsAtPath:@"/System/Library/LaunchDaemons/com.apple.pasteboard.pasted.plist"]) {
  30.     pbplist = @"/System/Library/LaunchDaemons/com.apple.pasteboard.pasted.plist";
  31.     pbbundle = @"com.apple.pasteboard.pasted";
  32. }

  33. BOOL pbdbexist = [man fileExistsAtPath:@"/var/mobile/Library/Caches/com.apple.UIKit.pboard/pasteboardDB"];
  34. NSString* pbcontainer = nil;
  35. if ([man fileExistsAtPath:@"/var/mobile/Library/Caches/com.apple.UIKit.pboard"]) {
  36.     pbcontainer = @"/var/mobile/Library/Caches/com.apple.UIKit.pboard";
  37. } else if ([man fileExistsAtPath:@"/var/mobile/Library/Caches/com.apple.Pasteboard"]) {
  38.     pbcontainer = @"/var/mobile/Library/Caches/com.apple.Pasteboard";
  39. }
  40. if (!isbe8 && [man fileExistsAtPath:pbplist]) {
  41.     system("launchctl unload -w");
  42. }
  43. if (pbcontainer != nil && [man fileExistsAtPath:pbcontainer]) {
  44.     NSString* cmd = [NSString stringWithFormat:@"rm -rf %@/*", pbcontainer];
  45.     system([cmd UTF8String]);
  46. }
  47. if (pbdbexist) {
  48.     NSString* cmd = [NSString stringWithFormat:@"cp %@ %@", @"/Applications/AWZ.app/pb.dat", @"/var/mobile/Library/Caches/com.apple.UIKit.pboard/pasteboardDB"];
  49.     system([cmd UTF8String]);
  50.     cmd = [NSString stringWithFormat:@"chown mobile:mobile %@", @"/var/mobile/Library/Caches/com.apple.UIKit.pboard/pasteboardDB"];
  51.     system([cmd UTF8String]);

  52. }
  53. if (pbplist != nil && !isbe8 && [man fileExistsAtPath:pbplist]) {
  54.     system("launchctl load -w");
  55. }
  56. if (isbe8 && pbbundle != nil) {
  57.     NSString* cmd = [NSString stringWithFormat:@"launchctl kickstart -k system/%@", pbbundle];
  58.     system([cmd UTF8String]);
  59. }
复制代码
我自己也是在逆向中不断学习新的东西,在分析过程中见到了更多的反逆向技术,还有改机方式,深有感悟。而AWZ本身也缺失很多功能,一直在更新的不是功能而是反逆向能力。。。,如代理屏蔽,appid隐藏,流量伪造,mac伪造,磁盘容量,内存容量,没有修改语言,音量,亮度等参数,一应俱无。



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

3

主题

21

帖子

81

积分

注册会员

Rank: 2

积分
81
发表于 2019-8-28 16:15:11 | 显示全部楼层
大佬,请问关于awz原理分析的第一阶段,那是什么意思呢?
回复

使用道具 举报

86

主题

262

帖子

1049

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1049
 楼主| 发表于 2019-8-28 16:22:22 | 显示全部楼层
s2339956 发表于 2019-8-28 16:15
大佬,请问关于awz原理分析的第一阶段,那是什么意思呢?

哪一句话不明白的?
回复

使用道具 举报

3

主题

21

帖子

81

积分

注册会员

Rank: 2

积分
81
发表于 2019-8-28 20:43:51 | 显示全部楼层
exchen 发表于 2019-8-28 16:22
哪一句话不明白的?

sed -i 's/RESTRICT/RXSTRICT/g' AWZ
sed -i 's/\x80\x52\x01\x10\x00\xd4/\x80\x52\x1f\x20\x03\xd5/g' AWZ

这些是怎知道的?
回复

使用道具 举报

86

主题

262

帖子

1049

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1049
 楼主| 发表于 2019-8-28 21:13:30 | 显示全部楼层
sed -i 's/RESTRICT/RXSTRICT/g' AWZ
这条命令是把AWZ文件里的 RESTRICT 替换成 RXSTRICT,这个是用来过反注入的。RESTRICT 说明你可以参考《九阴真经:iOS黑客攻防秘籍》书中的12.7节。

sed -i 's/\x80\x52\x01\x10\x00\xd4/\x80\x52\x1f\x20\x03\xd5/g' AWZ
这条命令是把AWZ文件里的 0x80,0x52,0x01,0x10,0x00,0xd4 替换成 0x80,0x52,0x1f,0x20,0x03,0xd5,用这种patch文件的方式来过反调试用的。

相当于第一阶段是过反注入和过反调试。上面的解释要是还不明白的话,你需要系统性学习下基础知识。
回复

使用道具 举报

0

主题

3

帖子

10

积分

新手上路

Rank: 1

积分
10
发表于 2019-8-29 21:27:35 | 显示全部楼层
新手学习 想问下执行 完
sed -i 's/RESTRICT/RXSTRICT/g' AWZ
sed -i 's/\x80\x52\x01\x10\x00\xd4/\x80\x52\x1f\x20\x03\xd5/g' AWZ

这两行代码了  app开始闪退了 后续应该怎么操作恩
回复

使用道具 举报

86

主题

262

帖子

1049

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1049
 楼主| 发表于 2019-8-29 22:47:48 | 显示全部楼层
ios爱好者 发表于 2019-8-29 21:27
新手学习 想问下执行 完
sed -i 's/RESTRICT/RXSTRICT/g' AWZ
sed -i 's/\x80\x52\x01\x10\x00\xd4/\x80\x5 ...

继续看第二阶段。
在第二阶段已经说了,在第一阶段破解后,仍然是闪退的。
回复

使用道具 举报

0

主题

3

帖子

10

积分

新手上路

Rank: 1

积分
10
发表于 2019-8-30 08:33:34 | 显示全部楼层
exchen 发表于 2019-8-29 22:47
继续看第二阶段。
在第二阶段已经说了,在第一阶段破解后,仍然是闪退的。 ...

第二阶段不是很明白是  先砸壳 还是 先反调试呢?
反调试的话有没有详细介绍啊
回复

使用道具 举报

86

主题

262

帖子

1049

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1049
 楼主| 发表于 2019-8-30 11:27:03 | 显示全部楼层
第一阶段已经去除了反调试了。第二阶段的砸壳可以忽略,越狱应用无需砸壳,这一点写错了。
回复

使用道具 举报

0

主题

3

帖子

10

积分

新手上路

Rank: 1

积分
10
发表于 2019-8-30 15:42:17 | 显示全部楼层
exchen 发表于 2019-8-30 11:27
第一阶段已经去除了反调试了。第二阶段的砸壳可以忽略,越狱应用无需砸壳,这一点写错了。 ...

软件闪退怎么反调试?
静态调试 ida吗?还是什么呢 新手多见谅哈
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|iOSHacker

GMT+8, 2019-11-15 08:36 , Processed in 0.059620 second(s), 21 queries .

iOS安全论坛

© 2017-2019 iOS Hacker Inc.

快速回复 返回顶部 返回列表