某银行iOS frida检测(例二)

某银行iOS frida检测(例二)

搜索frida等特征关键词后对相关函数进行hook,发现并未调用即闪退。

检测时机较早,对main函数进行hook,发现仍然没执行。

main函数执行前的流程:

1. 程序执行从_dyld_star开始

  • 1.1. 读取macho文件信息,设置虚拟地址偏移量,用于重定向。
  • 1.2. 调用dyld::_main方法进入macho文件的主程序。

2. 配置一些环境变量

  • 2.1. 设置的环境变量方便我们打印出更多的信息。
  • 2.1. 调用getHostInfo()来获取machO头部获取当前运行架构的信息。

3. 实例化主程序,即macho可执行文件

4. 加载共享缓存库

5. 插入动态缓存库

6. 链接主程序

7. 初始化函数

  • 7.1. 经过一系列的初始化函数最终调用notifSingle函数。
  • 7.2. 此回调是被运行时_objc_init初始化时赋值的一个函数load_images
  • 7.3. load_images里面执行call_load_methods函数,循环调用所用类以及分类的load方法。
  • 7.4. doModInitFunctions函数,内部会调用全局C++对象的构造函数,即_ _ attribute_ _((constructor))这样的函数。

8. 返回主程序的入口函数,开始进入主程序的main()函数

关于初始化过程:

https://tenloy.github.io/2021/10/21/dyld-objc.htm

涉及到两个段:

__objc_nlclslist(+ load方法)

__mod_init_func(init 方法)

查看hook __objc_nlclslist段中各个类的load函数

Untitled

Untitled

只发现在Sciapodous类的load函数中有可疑函数

Untitled

基本都是MsgRbKVPGCrUcJUf类的初始化行为,之后分析得知MsgRbKVPGCrUcJUf就是用于风险检测的类,-[MsgRbKVPGCrUcJUf FZyLGPttEmkjUXIg:]函数中存在对特征文件的检测。但是这些函数只是对标志位的设置,并无主动退出行为。

再在__mod_init_func段中找

Untitled

通过对各个init函数hook,在onEnter和onLeave中打log,通过闪退时的日志输出可以找到是哪个函数执行后导致的闪退。

最后发现是InitFunc_27:

MsgRbKVPGCrUcJUf类应该是一个用于风险监测的类,InitFunc_27开头通过获取MsgRbKVPGCrUcJUf中的开关属性(在Sciapodous + load 中设置)判断是否进入监测分支,sub_101013C80函数是判断以下文件是否存在:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
__const:00000001012991D8                                         ; sub_101013C80+28↑o ...
__const:00000001012991D8 ; "/usr/bin/ssh"
__const:00000001012991E0 DCQ aPrivateVarLibA_0 ; "/private/var/lib/apt"
__const:00000001012991E8 DCQ aPrivateVarLibC ; "/private/var/lib/cydia"
__const:00000001012991F0 DCQ aPrivateVarTmpC ; "/private/var/tmp/cydia.log"
__const:00000001012991F8 DCQ aPrivateEtcApt ; "/private/etc/apt"
__const:0000000101299200 DCQ aPrivateEtcSshS ; "/private/etc/ssh/sshd_config"
__const:0000000101299208 DCQ aUsrLibexecSftp ; "/usr/libexec/sftp-server"
__const:0000000101299210 DCQ aUsrLibexecCydi_0 ; "/usr/libexec/cydia/"
__const:0000000101299218 DCQ aUsrSbinFridaSe ; "/usr/sbin/frida-server"
__const:0000000101299220 DCQ aUsrLocalBinCyc ; "/usr/local/bin/cycript"
__const:0000000101299228 DCQ aUsrLibLibcycri ; "/usr/lib/libcycript.dylib"
__const:0000000101299230 DCQ aUsrLibSubstrat ; "/usr/lib/substrate"
__const:0000000101299238 DCQ aApplicationsCy_0 ; "/Applications/Cydia.app"
__const:0000000101299240 DCQ aVarLibCydia ; "/var/lib/cydia"
__const:0000000101299248 DCQ aVarCacheApt ; "/var/cache/apt"
__const:0000000101299250 DCQ aVarLibApt ; "/var/lib/apt"
__const:0000000101299258 DCQ aLibraryMobiles ; "/Library/MobileSubstrate/MobileSubstrat"...
__const:0000000101299260 DCQ aBinBash ; "/bin/bash"
__const:0000000101299268 DCQ aBinSh ; "/bin/sh"
__const:0000000101299270 DCQ aUsrSbinSshd ; "/usr/sbin/sshd"
__const:0000000101299278 DCQ aUsrLibexecSshK ; "/usr/libexec/ssh-keysign"
__const:0000000101299280 DCQ aEtcApt ; "/etc/apt"
__const:0000000101299288 DCQ aEtcSshSshdConf ; "/etc/ssh/sshd_config"

sub_101006B80函数进行如下检测:

Untitled

Untitled

判断传入的函数名的函数头是否被修改为跳转指令(是否被hook)

Untitled

sub_101006FEC函数是对方法Swizzling Hook的检测。

对以下函数分别使用sub_101006B80和sub_101006FEC函数进行frida hook和Swizzling Hook的检测:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
v18 = NSStringFromSelector("nkGUHXJzuioWfEml");
v59 = objc_retainAutoreleasedReturnValue(v18);
v60[0] = (__int64)v59;
v19 = NSStringFromSelector("FZyLGPttEmkjUXIg:");
v58 = objc_retainAutoreleasedReturnValue(v19);
v60[1] = (__int64)v58;
v20 = NSStringFromSelector("OYwDyZUfXCNXiOuv");
v57 = objc_retainAutoreleasedReturnValue(v20);
v60[2] = (__int64)v57;
v21 = NSStringFromSelector("oCJCZGmYYtmdhspo");
v56 = objc_retainAutoreleasedReturnValue(v21);
v60[3] = (__int64)v56;
v22 = NSStringFromSelector("EujUBbCTRLuXCRqu");
v55 = objc_retainAutoreleasedReturnValue(v22);
v60[4] = (__int64)v55;
v23 = NSStringFromSelector("VXyTlyycVmvcUQXP");
v54 = objc_retainAutoreleasedReturnValue(v23);
v60[5] = (__int64)v54;
v24 = NSStringFromSelector("IHECuOYOxebNvDDH");
v25 = objc_retainAutoreleasedReturnValue(v24);
v60[6] = (__int64)v25;
v26 = NSStringFromSelector("cMEtWZwNDrxuizwJ");
v27 = objc_retainAutoreleasedReturnValue(v26);
v60[7] = (__int64)v27;
v28 = NSStringFromSelector("yuVnaUTHTXIAtPAG");
v29 = objc_retainAutoreleasedReturnValue(v28);
v60[8] = (__int64)v29;
v30 = NSStringFromSelector("wnosSMcuAlAibwoo");
v31 = objc_retainAutoreleasedReturnValue(v30);
v60[9] = (__int64)v31;
v32 = NSStringFromSelector("PqyDnmKPYthqfJbi");
v33 = objc_retainAutoreleasedReturnValue(v32);
v60[10] = (__int64)v33;
v34 = NSStringFromSelector("pyPCPVcvgUNZLlJv");
v35 = objc_retainAutoreleasedReturnValue(v34);
v60[11] = (__int64)v35;
v36 = NSStringFromSelector("ZAPICCvNifItLLFY");
v37 = objc_retainAutoreleasedReturnValue(v36);
v60[12] = (__int64)v37;
v38 = NSStringFromSelector("aKThUCDFaNPXSLuc");
v39 = objc_retainAutoreleasedReturnValue(v38);

绕过InitFunc_27函数后发现仍然闪退,继续分析发现InitFunc_28中存在对InitFunc_27是否被hook的检测:

(sub_101006E08函数和sub_101006B80的检测方式相同)

Untitled

InitFunc_29中存在对InitFunc_28是否被hook的检测:

Untitled

InitFunc_30中存在对sub_100FF8E64和sub_101001764函数是否被hook的检测:

(sub_100FF8E64函数是检测27042端口是否占用,sub_101001764对frida文件检测)

Untitled

InitFunc_31中同样是使用sub_101006E08和sub_101006FEC对指定的函数进行hook检测;

InitFunc_32延迟执行sub_100FFC0FC和sub_100FFC208,其中包含一些对标志位的判断;

InitFunc_33延迟执行sub_100FFC3EC,同样是使用sub_101006E08和sub_101006FEC对指定的函数(DTRpcOperation、DTURLRequestOperation)进行hook检测。

绕过以上函数后发现仍然闪退,关闭frida后仍然闪退,应该是越狱检测,越狱检测不再赘述,使用插件绕过越狱检测后运行正常。