抓包走起:
我这边习惯用vpn转发方式;
直接抓出来2.0协议了;
上trace url定位吧;
frida-trace -UF -m "+[NSURL URLWithString:]"
11891 ms 堆栈 from:
0x101b67038 /var/containers/Bundle/Application/72A10900-034F-400A-A822-6F5BB4FE6933/tieba.app/tieba!-[ZYURLRequest obtainMostSuitableRequest]
0x101b69044 /var/containers/Bundle/Application/72A10900-034F-400A-A822-6F5BB4FE6933/tieba.app/tieba!-[ZYURLRequest currentRequest]
0x101b69828 /var/containers/Bundle/Application/72A10900-034F-400A-A822-6F5BB4FE6933/tieba.app/tieba!-[ZYURLSession dataTaskWithRequest:]
0x101b6bc50 tieba!0xdd7c50 (0x100dd7c50)
0x101b6bbec tieba!0xdd7bec (0x100dd7bec)
0x101b6b9b8 /var/containers/Bundle/Application/72A10900-034F-400A-A822-6F5BB4FE6933/tieba.app/tieba!-[ZYURLSessionManager dataTaskWithRequest:responseBlock:uploadProgress:downloadProgress:dataBlock:completionHandler:]
0x101b5d9dc /var/containers/Bundle/Application/72A10900-034F-400A-A822-6F5BB4FE6933/tieba.app/tieba!-[ZYRequest zy_sendRequestWithURL:parameters:userInfo:isOrginalResponse:type:constructingBodyWithBlock:progress:success:retry:failure:addressTypeInfo:]
0x101b5f2e4 /var/containers/Bundle/Application/72A10900-034F-400A-A822-6F5BB4FE6933/tieba.app/tieba!-[ZYRequest _postWithURL:parameters:userInfo:isOrginalResponse:progress:success:retry:failure:]
0x101b5f144 /var/containers/Bundle/Application/72A10900-034F-400A-A822-6F5BB4FE6933/tieba.app/tieba!-[ZYRequest postWithURL:parameters:userInfo:isOrginalResponse:progress:success:retry:failure:]
0x101b5eecc /var/containers/Bundle/Application/72A10900-034F-400A-A822-6F5BB4FE6933/tieba.app/tieba!-[ZYRequest postWithURL:parameters:userInfo:progress:success:retry:failure:]
0x101b5ee34 /var/containers/Bundle/Application/72A10900-034F-400A-A822-6F5BB4FE6933/tieba.app/tieba!-[ZYRequest postWithPath:parameters:userInfo:progress:success:retry:failure:]
0x101ce5520 /var/containers/Bundle/Application/72A10900-034F-400A-A822-6F5BB4FE6933/tieba.app/tieba!+[ZYNetWorkManager postWithPath:parameters:userInfo:progress:success:retry:failure:]
0x101a6e23c /var/containers/Bundle/Application/72A10900-034F-400A-A822-6F5BB4FE6933/tieba.app/tieba!-[XCAccountManager xcVerifyCodeRegisterOrLogin:verifyCode:gender:nickName:birth:sign:invite:success:failure:]
0x101a6dd20 /var/containers/Bundle/Application/72A10900-034F-400A-A822-6F5BB4FE6933/tieba.app/tieba!-[XCAccountManager xcVerifyCodeLogin:verifyCode:invite:success:failure:]
0x101ad829c /var/containers/Bundle/Application/72A10900-034F-400A-A822-6F5BB4FE6933/tieba.app/tieba!-[ZYSigninManager verifyCodeSigninWithPhoneNumberStr:verifyCode:inviteCode:]
0x101ae02f0 /var/containers/Bundle/Application/72A10900-034F-400A-A822-6F5BB4FE6933/tieba.app/tieba!-[ZYSigninViewController signWithVerifyCode]
我们砸壳搜一下,第一个地方;
-[ZYURLRequest obtainMostSuitableRequest]
在OC中 方法前面的-代表实例方法,+代表类方法(static)
看到一个sign的关键部位:
最后都归于v222;
这样就看到了,v220 是来自于 encode_aes;
encode_aes来自于导入库,我们需要拿到 TDProtocol 去看下;
追随到 a3, a3为传入的值;
上钩子,hook:
frida -UF -l C:\Users\Codeooo\Desktop\hook_aes.js
这里看出来,密文就是经过这个方法得出来的;
key 0x10 为16个字节,这也符合aes key长度;
进入cipher_encode_aes((const char *)aes_key, a1, a2, v2);
就看到了 标准的OpenSSL库了;
EVP_EncryptInit_ex(&a, v17, 0LL, (const unsigned __int8 *)a1, v10);
v17 = EVP_aes_128_cbc();
(const unsigned __int8 *)a1 则为key;
v10为iv,
rand_vector(15);
LOBYTE(a.cipher) = v9 - v4 + 16;
std::vector::insert((int)v28, (void *)(v28[0] + 1));
v10 = (const unsigned __int8 *)v28[0];
直接hook key 和 iv;
var EVP_EncryptInit_ex = Module.findExportByName("TDProtocol", "EVP_EncryptInit_ex");
Interceptor.attach(EVP_EncryptInit_ex, {
onEnter: function (args) {
console.log('EVP_EncryptInit_ex() key:', hexdump(args[3]));
console.log('EVP_EncryptInit_ex() iv: ', hexdump(args[4]));
}, onLeave: function () {
}
});
在这个地方可以查看明文及密文
我们看到 iv : ab 07 23 dd c6 c6 af 98 98 98 81 81 81 6a 6a 6a
也证明了 iv是随机的, 所以请求头将 iv放在了 最前面 ;
而且这个key是全局申明的,且是app一打开就生成的;
我们点开交叉引用的,aes_key
发现是随机生成的,然后通过rsa进行认证;
x-xc-proto-req: 就是通过key进行rsa签名
返回的响应头:x-xc-proto-res: 进行后续验证处理;
hook这个rsa:
var cipher_encode_rsa = Module.findBaseAddress("TDProtocol").add(0x87FC);
Interceptor.attach(cipher_encode_rsa, {
onEnter: function (args) {
this.args0 = args[0];
this.args1 = args[1];
console.log('cipher_encode_rsa() this.args0 onEnter:', hexdump(this.args0, {length: this.args1.toInt32()}));
}, onLeave: function (retval) {
}
});
这个得 -f spwan去启动,不能用-F 附加了;
frida-ps -Ua 查看包名
frida -U -f 包名 --no-pause -l C:\Users\Codeooo\Desktop\hook_aes.js
而且我们看这个也是 base64编码的;
x-xc-proto-req: duck-1679471514-HgqiT7R2iq346VHkieSE6dsowbiBMJBCpy/Op3noDVXwxSCvmVTAEjgl84TBeOGBUT4IqmT43jBA81ZrzHsOtOEALwMb3RTme5D0AR8YFJw=
var Base64Encode = Module.findBaseAddress("TDProtocol").add(0xDCE8);
Interceptor.attach(Base64Encode, {
onEnter: function (args) {
this.args1 = args[1];
}, onLeave: function (retval) {
console.log('Base64Encode() this.args1 onLeave:', (this.args1.readPointer().readCString()));
}
});
与抓包一致;
我们拿一些rsa的秘钥;
进入
var get_pubic_key = Module.findBaseAddress("TDProtocol").add(0x7F7C);
Interceptor.attach(get_pubic_key, {
onEnter: function (args) {
}, onLeave: function (retval) {
console.log('get_pubic_key() this.args0 onLeave:', retval.readCString());
}
});
好的,饶了一圈回到原点,看下最早我们 sign 怎么生成的吧;
跳回最早界面:-[ZYURLRequest obtainMostSuitableRequest]
好像只有个MD5;
var sign_data = ObjC.classes.libProtocol['+ sign_data:'].implementation;
Interceptor.attach(sign_data, {
onEnter: function (args) {
console.log('sign_data() onEnter:', ObjC.Object(args[2]));
}, onLeave: function (retval) {
console.log('sign_data() retval:', ObjC.Object(retval));
}
});
v2-c8ef477a8be55d9fd63671ea29dbb2ae
这里面操作了 md5sum ,可能进行了魔改,盲猜一般是更改初始化变量;
详见: https://codeooo.blog.csdn.net/article/details/119811015
接下来我们干分析一波MD5,在上面看到是 MD5sum这个位置发现变动,点进来看一波;
这个地方,我们知道,参数1为data, 参数2为 长度, 参数3为返回值也就是常说的buffer;
转化为字符串 v5 ,a1, a2 都是已知的;
MD5Update 中 第一个传入了 v7地址,和刚刚经过string的v5;
那看下 v7 是什么???文章来源:https://www.toymoban.com/news/detail-432865.html
这不就是要魔改的初始化变量;文章来源地址https://www.toymoban.com/news/detail-432865.html
到了这里,关于IOS - 某段子APP分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!