1.目标
某茅台软件的actParam算法分析还原。
2.使用工具
-
mac系统
-
frida-ios-dump:砸壳
-
已越狱iOS设备:脱壳及frida调试
-
IDA Pro:静态分析
-
Charles:抓包工具
-
Shadowrocket:小火箭,配合Charles使用
3.流程
处理启动闪退
在IDA Pro搜索SVC得到如下函数列表:
NOP掉sub_函数的最后一行汇编后,即可正常运行App
处理登录闪退
启动App,在登录页使用命令frida-trace -UF -m "-[UIViewController viewDidAppear:]"
,然后进入到任意页后再返回登录页,获取到当前类为XXLoginViewController,再使用命令frida-trace -UF -m "-[*LoginViewController *]"
,跟踪该类。点击登录后,啥也没获取到,呵呵。不过,看LoginViewController类有loginButton,在该方法看到登录按钮绑定的事件为LoginViewController类的login方法。使用IDA Pro打开该方法:
1 2 3 4 5 |
|
这么大的exit函数,查看该条件是在什么地方赋值,查看该变量的交叉引用
在sub_1002F52F44函数里对该变量进行赋值。接下来就是处理该函数的赋值逻辑(该方法仅是保证检测环境的qword_100F492E0为0,不排除有其他地方仍然有越狱检测等操作):
1、处理embedded.mobileprovision文件。(重签名后会生成该文件)
1 2 3 4 5 6 7 8 9 10 11 12 |
|
2、对sub_1002F52F44函数里,对该变量进行赋值的地方,一一处理。保证不会执行qword_100F492E0=1,处理完后即可正常登录:
寻找actParam算法
在IDA Pro搜索actParam字符串,没有发现该字符,说明该字符串被处理过了。按之前的套路,既然这在body里,那我们就使用命令frida-trace -U -f com.xxx.xxx -m "*[NSMutableURLRequest setHTTPBody:]" -m "*[NSBundle pathForResource:ofType:]"
获取到关键日志如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
body里正是我们提交里的参数,根据堆栈可知网络请求是在[XXReserveViewController reserve]发起的,使用IDA Pro查看对应的代码可知网络请求类是XXReserveRequest。使用命令frida-trace -U -f com.xxx.xxx -m "*[XXReserveRequest *]" -m "*[NSBundle pathForResource:ofType:]"
跟踪该类,获取到的日志如下:
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 |
|
根据日志可发现actParam在requestParams方法里返回的,继续使用IDA Pro查看该代码
sub函数一直点进去,就会发现(unsigned int)CCCrypt(v6, 0LL, 1LL, &v43, 32LL, v27, v28, v29, v41, v26, &v42) ,接下来就是对该函数进行调试,由于该方法,需要特写时间段才能使用。所以在此,我们查看此sub函数的交叉引用,发现在下单时,也有调用该加密函数。
使用命令frida-trace -U -f com.xxx.xxx -m "*[NSBundle pathForResource:ofType:]" -i CCCrypt
打印该参数,在创建订单时,获取到日志如下:
js代码
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 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
|
日志
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 |
|
日志里的dataOut数据,转换为base64后,和接口里的参数一致(注:日志里的敏感信息被我处理过)。
结果
见CCCrypt日志。在分析过程中,当我们发现参数是base64的时候,也可以先拦截base64EncodedStringWithOptions或CCCrypt函数,运气好的话,也能快速定位到加密算法。