首页
论坛
课程
招聘
[原创]谈谈这次越狱的AppSync Unified for IOS8 的注入过程
2014-11-14 16:56 13934

[原创]谈谈这次越狱的AppSync Unified for IOS8 的注入过程

2014-11-14 16:56
13934

别的话也不多说了,越狱那些破事,都是争得你死我活的.....

首先我拿到 net.angelxwind.appsyncunified.deb,这个deb目录结构如下:
.
├── DEBIAN
│   ├── control
│   ├── postinst
│   └── postrm
├── Library
│   ├── LaunchDaemons
│   │   └── net.angelxwind.asu_inject.plist
│   └── MobileSubstrate
│       └── DynamicLibraries
│           ├── AppSyncUnified.dylib
│           └── AppSyncUnified.plist
└── usr
    └── bin
        └── asu_inject

看到以上这结构,明白的人就能很快知道实现的劫持installd的思路.
我这边也主要解析下作者的思路,我们关注下这结构里的2个地方:

1. Library/LaunchDaemons/net.angelxwind.asu_inject.plist
2. usr/bin/asu_inject

net.angelxwind.asu_inject.plist配置如下
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>KeepAlive</key>
  <false/>
  <key>Label</key>
  <string>net.angelxwind.asu_inject</string>
  <key>ProgramArguments</key>
  <array>
    <string>/usr/bin/asu_inject</string>
  </array>
  <key>RunAtLoad</key>
  <true/>
  <key>StandardErrorPath</key>
  <string>/dev/null</string>
  <key>StandardOutPath</key>
  <string>/dev/null</string>
</dict>
</plist>

这边很详细的说了,在launchctl启动的时候,加载了次配置项去启动/usr/bin/asu_inject(这边如果自己写的话需要注意文件权限,root/wheel),这边看下配置信息也就行了,没什么好说的.

asu_inject
asu_inject主要做的事,就是遍历进程直到发现installd这进程,然后调用Cydia的cynject进行注入.

代码如下:
#include <stdio.h>
#include <limits.h>
#include <dispatch/queue.h>
#include <spawn.h>
#include <libproc.h>
#include <stdlib.h>
#include <unistd.h>

static int g_pidInstalld = 0;
extern char **environ;

int main (int argc, const char * argv[])
{
    // insert code here...
    puts("asu_inject for AppSync Unified 5");
    puts("Karen Tsai (angelXwind) / Linus Yang (laokongzi)");
    puts("AppSync Unified is not for piracy.");
    puts("Creating queue...");
    
    dispatch_queue_t queue = dispatch_queue_create(NULL, NULL);
    puts("Finding installd PID...");
    dispatch_async(queue, ^{
        
        char path[PATH_MAX] = {0};
        int pid_list[0x1000] = {0};
        bool isFind = false;
        
        do {
            
            int cnt = proc_listallpids(pid_list, sizeof(pid_list));
            if (cnt) {
                for (int i = 0; i < cnt; ++i) {
                    int pid = pid_list[i];
                    int name_len = 0;
                    if ((name_len = proc_pidpath(pid, path, sizeof(path))) <= 0) {
                        continue;
                    }
                    
                    if (strstr(path, "installd")) {
                        g_pidInstalld = pid;
                        isFind = true;
                        break;
                    }
                }
            }
            sleep(1);
        } while (isFind == false);
    });
    
    puts("Waiting for queue to come back...");
    dispatch_sync(queue, ^{});
    
    printf(" Pid %d\r\n", g_pidInstalld);
    puts("Injecting AppSyncUnified.dylib into installd...");
    
    pid_t pid;
    char *args[4];
    
    char pidInstalld[32] = {0};

    snprintf(pidInstalld, sizeof(pidInstalld), "%d", g_pidInstalld);
    args[0] = "/usr/bin/cynject";
    args[1] = pidInstalld;
    args[2] = "/Library/MobileSubstrate/DynamicLibraries/AppSyncUnified.dylib";
    args[3] = NULL;
    posix_spawn(&pid, "/usr/bin/cynject", NULL, NULL, args, environ);
    
  return 0;
}


然后总结下,
net.angelxwind.appsyncunified.deb通过cydia安装时候会通过配置的postinst和postrm跑一次
asu_inject实现注入installd,如果设备重启,那就通过launchctl加载启动配置的plist,执行一次asu_inject,实现了注入installd的过程,至于作者为啥没有自己写劫持,而是直接调用Cydia的cynject注入,我想是为了安全,通过cynject注入的,如果插件有冲突,可以通过"电源键 + 音量键+"进入的安全模式(我自己在写测试代码过程中.好几次都在转圈圈,只能通过这方式进入,要是进不去,恭喜你,刷机吧)

讲到这,主要是抛个砖头吧,现在很多插件需要使用这方式去注入,Cydia的MobileSubstrate下的dylib,经常跑不起来,所以以上这方式式很好的辅助注入,既简单有实惠.

至于AppSync Unified for IOS8 这个的实现我想有心人都写过吧,这玩意也不难.


第五届安全开发者峰会(SDC 2021)议题征集正式开启!

收藏
点赞0
打赏
分享
最新回复 (5)
雪    币: 235
活跃值: 活跃值 (27)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
piratelzs 活跃值 2014-11-14 17:10
2
0
沙发,顶,多谢分享~~
雪    币: 248
活跃值: 活跃值 (27)
能力值: ( LV15,RANK:340 )
在线值:
发帖
回帖
粉丝
木桩 活跃值 8 2014-11-14 17:27
3
0
赞一个!前几天AppSync不稳定,还在想研究下怎么回事呢。
关于作者没有和以前版本一样用Cydia Substrate直接写劫持,原因是iOS8上Cydia Substrate无法正确注入代码到守护进程中:

However, there is still a major roadblock - which is Cydia Substrate. As of Cydia Substrate version 0.9.5016, Cydia Substrate cannot properly inject code into daemons that are running as mobile, installd being one of them. Therefore, AppSync Unified 5.0 has to inject itself via a rather hacky method, which is basically just calling cynject manually


当时想了好久也没理解怎么手动调用cynject插入installd,今天开了LZ分析的过程豁然开朗!

顺带一说,作者2天前更新了AppSync,asu_inject的源码在这里。还有个新的appinst,看上去用于命令行安装IPA
雪    币: 986
活跃值: 活跃值 (423)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
小调调 活跃值 2014-11-14 17:41
4
0
哈哈,谢谢啊,AppSync里有些东西我还没看完全明白,有源码组号啊~
雪    币: 245
活跃值: 活跃值 (62)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
airbus 活跃值 2014-11-14 17:45
5
0
前排,学习一下哈.
雪    币: 248
活跃值: 活跃值 (27)
能力值: ( LV15,RANK:340 )
在线值:
发帖
回帖
粉丝
木桩 活跃值 8 2014-11-14 20:43
6
0
读完了iOS8的 https://github.com/angelXwind/AppSync 的代码,依然有2个不明白的地方,求各位大侠解惑

1. AppSyncUnified.x里的 SignerCertificate = <a113> 是什么?为什么伪造签名用这个kSecMagicBytes就可以绕过?

通过DEBUG输出的伪造签名如下:
Nov 14 19:01:00 heimaodekaifaji installd[61] <Warning>: AppSync Unified: Ahh, nil info, fake it
Nov 14 19:01:00 heimaodekaifaji installd[61] <Warning>: AppSync Unified: Security.framework injected
Nov 14 19:01:00 heimaodekaifaji installd[61] <Warning>: AppSync Unified: bundle path: /private/var/mobile/Library/Caches/com.apple.mobile.installd.staging/temp.ZhSh9J/extracted/Payload/RankingLog.app
Nov 14 19:01:00 heimaodekaifaji installd[61] <Warning>: AppSync Unified: bundle id: com.zzz.RankingLog
Nov 14 19:01:00 heimaodekaifaji installd[61] <Warning>: AppSync Unified: bundle exec: /var/mobile/Library/Caches/com.apple.mobile.installd.staging/temp.ZhSh9J/extracted/Payload/RankingLog.app/RankingLog
Nov 14 19:01:00 heimaodekaifaji installd[61] <Warning>: AppSync Unified: faked info: {
  Entitlements = {
    "application-identifier" = "my.company.RankingLog";
    "get-task-allow" = 1;
  };
  SignerCertificate = <a113>;
  SigningID = "com.zzz.RankingLog";
  SigningTime = "2014-11-14 11:01:00 +0000";
  ValidatedByProfile = 0;
}


SigningID和Entitlements是用新加的dump.cpp从IPA里读的,不过SignerCertificate却不明白为什么是 0xA1, 0x13 ?

正常程序的签名:
Nov 14 19:05:48 heimaodekaifaji installd[61] <Warning>: AppSync Unified: Hooray, info is okay
Nov 14 19:05:48 heimaodekaifaji installd[61] <Warning>: AppSync Unified: orig info: {
  Entitlements = {
    "application-identifier" = "H8GX49UM4B.com.jonathanlanis.boost";
    "keychain-access-groups" = (
      "H8GX49UM4B.com.jonathanlanis.boost"
    );
  };
  SignerCertificate = <30820383 3082026b a0030201 0202011e 300d0609 ...>;
  SigningID = "com.jonathanlanis.boost";
  SigningTime = "2014-11-14 11:05:47 +0000";
  ValidatedByProfile = 0;
}


2. asu_inject.c为什么不像postinst/misc.c里一样,cynject MobileSubstrate.dylib而是直接注入AppSyncUnified.dylib?是有什么特殊用意吗?
游客
登录 | 注册 方可回帖
返回