FreeBufiOS逆向之人脸识别绕过


0x00前言
达到目的的手段有很多种 , 也许存在优劣之分 , 我只是选择了其中一种我认为好玩的方式 。 人脸识别校验状态存储在服务端 , 因此即使通过该种方法绕过客户端人脸识别 , 由于并未获得合法session , 因此无任何危害 , 仅做为IOS逆向学习思路 。
0x01 准备本文所使用环境:
越狱IOS手机1个(本文所用为12.4.4)
FreeBufiOS逆向之人脸识别绕过
本文插图
登录时存在人脸识别:
FreeBufiOS逆向之人脸识别绕过
本文插图
FreeBufiOS逆向之人脸识别绕过
本文插图
0x02 脱壳apple在上架应用时 , appstore会为上架的app加一层壳 。 在加壳状态下进行分析极为困难 。 但该层壳较为简单 , 可以通过各种自动化工具进行脱壳 。 如Clutch , CrackerXI+等 。
Clutch-i#查看包名 Clutch -d 包名 #脱壳因为本文所用IOS版本为12.4.4 , Clutch存在兼容性问题 , 故使用CrackerXI+进行脱壳 , 脱出未加壳版本:
FreeBufiOS逆向之人脸识别绕过
本文插图
在CrackerXI+中选择该app脱壳后:
FreeBufiOS逆向之人脸识别绕过
本文插图
把未加壳的ipa包下载到本地:
0x03 破解ipa实际上是个压缩包 , 可以直接通过压缩软件打开 , 解压其中的二进制文件:
用ida反编译ios中的二进制文件
分析代码后发现:XXXXBaseViewController loginSuccessIsNeedBind:WithInfo:
是登录后 , 人脸识别的函数 , 伪代码:
void__cdecl -[XXXXAPPBaseViewController loginSuccessIsNeedBind:WithInfo:](XXXXAPPBaseViewController *self, SEL a2, bool a3, id a4){ BOOL v4; // w22 XXXXAPPBaseViewController *v5; // x21 __int64 v6; // x19 void*v7; // x0 void *v8; // x0 void*v9; // x23 void *v10; // x0 void*v11; // x20 XXXXAPPLoginHelper *v12; // x0 void*v13; // x23 __int64 v14; // x1 __int64 v15; // x1 __int64 v16; // x0 struct objc_object *v17; // x0 void*v18; // x0 void *v19; // x22 void*v20; // x0 void *v21; // x23 int v22; // w24 void*v23; // x0 void *v24; // x0__int64 v25; // x22 void *v26; // x0 __int64 v27; // x23 const char*v28; // x1 void **v29; // [xsp+0h] [xbp-70h] __int64 v30; // [xsp+8h] [xbp-68h] __int64 (__fastcall *v31); // [xsp+10h] [xbp-60h] void*v32; // [xsp+18h] [xbp-58h] XXXXAPPBaseViewController *v33; // [xsp+20h] [xbp-50h]__int64 v34; // [xsp+28h] [xbp-48h] __int64 v35; // [xsp+30h] [xbp-40h] bool v36; // [xsp+38h] [xbp-38h] v4 = a3;//赋值v4 v5 = self; v6 = objc_retain(a4, a2); v7 = objc_msgSend(&OBJC_CLASS___UIApplication, "sharedApplication"); v8 = (void *)objc_retainAutoreleasedReturnValue(v7); v9 = v8; v10 = objc_msgSend(v8, "delegate"); v11 = (void *)objc_retainAutoreleasedReturnValue(v10); objc_release(v9); if ( (unsigned int)-[XXXXAPPBaseViewController needInputIDCardInfomation:](v5, "needInputIDCardInfomation:", v6) ) { +[PCUtil setObject:forKey:](&OBJC_CLASS___PCUtil, "setObject:forKey:", CFSTR("1"), CFSTR("maybeNeedBackLoginGuide")); v12 = +[XXXXAPPLoginHelper sharedInstance](&OBJC_CLASS___XXXXAPPLoginHelper, "sharedInstance"); v13 = (void *)objc_retainAutoreleasedReturnValue(v12); v29 = _NSConcreteStackBlock; v30 = 3254779904LL; v31 = sub_1000B05E4; v32 = &unk_10263F2D8; v33 = v5; v36 = v4; v34 = objc_retain(v11, v14); v35 = objc_retain(v6, v15); objc_msgSend( v13, "setCompleteGuideBlock:", &v29, _NSConcreteStackBlock, 3254779904LL, sub_1000B05E4, &unk_10263F2D8, v5); objc_release(v13); objc_release(v35); v16 = v34;LABEL_9: objc_release(v16); goto LABEL_10; } if ( v4 ) //判断v4(bool)值,确定是否进入人脸识别 { v17 = +[PNCMBankGlobal sharedData](&OBJC_CLASS___PNCMBankGlobal, "sharedData"); v18 = (void *)objc_retainAutoreleasedReturnValue(v17); v19 = v18; v20 = objc_msgSend(v18, "bindType"); v21 = (void *)objc_retainAutoreleasedReturnValue(v20); v22 = (unsigned__int64)objc_msgSend(v21, "isEqualToString:", CFSTR("FACE")); objc_release(v21); objc_release(v19); v23 = objc_msgSend(v11, "rootVC"); v24 = (void *)objc_retainAutoreleasedReturnValue(v23); v25 = (__int64)v24; v26 = objc_msgSend(v24, "navigationController"); v27 = objc_retainAutoreleasedReturnValue(v26); if ( v22 ) v28 = "goToFaceCheckBindVC:info:"; else v28 = "goSmsOrUKBindInfoVC:info:"; objc_msgSend(v5, v28, v27, v6); objc_release(v27); v16 = v25; goto LABEL_9; } -[XXXXAPPBaseViewController AfterBindSuccess:isNeedBind:](v5, "AfterBindSuccess:isNeedBind:", v6, 0LL);LABEL_10: objc_release(v11); objc_release(v6);}


推荐阅读