福建省建设执业资格管理注册中心网站,郑州技术支持seo,wordpress dns,怎样做淘宝商品链接导航网站本期的案例比较简单#xff0c;也许是ios逆向算法本来就比较简单的原因#xff0c;所以前面我就多扯一些爬虫和逆向的东西。之前写的文章都是js逆向和android逆向的案例#xff0c;这也是首篇ios的案例#xff0c;所以会从入门开始讲起。
3大逆向对比
首先爬虫工程师大部…本期的案例比较简单也许是ios逆向算法本来就比较简单的原因所以前面我就多扯一些爬虫和逆向的东西。之前写的文章都是js逆向和android逆向的案例这也是首篇ios的案例所以会从入门开始讲起。
3大逆向对比
首先爬虫工程师大部分都是需要js逆向的会安卓的人不多ios的就更不用说了js逆向中会安卓逆向的保守估计不超过40%因为大部分人搞爬虫都是从js开始的当然少部分会从安卓开始而ios逆向和安卓逆向的比例不超过1:5你去各大社区的论坛帖子数对比下就知道了网上的ios协议分析也是少的可怜。学ios逆向有什么用处呢对我们爬虫工程师来说就是可以增加一个技能让你的简历脱颖而出 很多招聘要求上都有写会安卓逆向的优先会ios逆向的优先。其次ios的逆向及风控要比安卓逆向弱很多如果安卓上业务过不去可以考虑iosios的很多app即使接口有加密也有很多不验证的本篇会验证并且不像安卓跑几次就封账号了。
ios难度与安卓对比
很多人说ios逆向比安卓简单有以下几个原因 1 首先就是闭源安卓开源导致的各种系统定制各大安全厂商不得不对这些系统进行检测对抗就是这样起来的。 2 iphone默认只允许用户从app store下载应用并且上架到了app store的应用都被苹果加了一层壳类似安卓的加固安卓的叫脱壳ios的叫砸壳并且这个砸壳也是有成熟的方案的。对比下安卓的各大厂商的加固虽然现在fart脱壳机可以脱很多整体加固和抽取加固但是由于太过热门现在也有很多厂商检测fart特征的并且未来的第3代加固技术vmp加固你又该怎么办 3 玩ios逆向的人少对抗自然就少了不过我这一篇文章也掀不起什么大风大浪。并且教程少很多社区都没落了。 4 还有就是很多人以为设备的问题ios逆向需要mac其实win也够了不开发插件的话黑苹果也是够用的。还有就是iphone贵现在的iphone6比pixel4便宜太多了两三百就够了。 5 ios逆向处于调用系统加密库的时代而安卓处于魔改算法自写算法白盒时代前些天分析的x-zse-96就是一个魔改严重的AES。如果你用过安卓的算法助手就知道ios的加密类似于这个。 6 ios逆向的话我认为入门的话安卓要简单因为有java层的加密给你体验体验完事后你就得准备硬刚so了。整体来说还是ios要简单的。
正片开始
前提
肯定是需要一部iphone的有预算的话最好不要选择太老的iphone,否则一些大型app你可能运行不起来最好不要低于iphone6.电脑 win mac都可以
环境
需要能越狱的并且在ios上安装好frida同时配置好ssl kill switch2插件类似安卓的justtrustme,这些教程都比较简单网上都有资料相信你都搞逆向了不会连这个配置都完不成吧
抓包
app是从app store下载的目标api是搜索接口 抓了两个包转python后对比一下 第一个关键词是淀粉肠第二个关键词是可口可乐文本对比后发现主要是sign和url中的不一样没有看到搜索的关键词正常人应该都会猜关键词在url中或者sign中先看url中的5reA57KJ6IKg和淀粉肠有什么关系你觉得应该会猜base 64吧因为包在传输过程中有些数据字符或者空格直接传过去可能有问题需要先base64一下。 所以关键就是这个sign了这个sign看着也像是base64过的长度是64并且长度固定转成16进制是96位也就是48字节hash算法好像没有96位的对称加密算法有可能des分组长度8字节aes分组长度16字节这两个都有可能。 前面我们说过ios的很多都是调用的系统函数aes和des都调用的是CCCrypt函数CCCrypt还包括3des和rc4 rc2等等。所以可以先hook这个函数看看 1 frida-trace -UF -i CCCrypt
执行后当前目录会生成一个_handlers_的文件夹子文件夹里有CCCrypt.js文件如果你用过ida中的tracenatives插件就应该知道这个。 修改一下CCCrypt.js文件初始生成的只会打印些简单的东西只有参数的地址或者长度修改成打印出加密的类型key及key的长度是否有iv以及input和input的长度output和output的长度这份代码可以固定住后续如果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 42 43 44 45 46 /* * Auto-generated by Frida. Please modify to match the signature of CCCrypt. * This stub is currently auto-generated from manpages when available. * * For full API reference, see: https://frida.re/docs/javascript-api/ */ { /** * Called synchronously when about to call CCCrypt. * * this {object} - Object allowing you to store state for use in onLeave. * param {function} log - Call this function with a string to be presented to the user. * param {array} args - Function arguments represented as an array of NativePointer objects. * For example use args[0].readUtf8String() if the first argument is a pointer to a C string encoded as UTF-8. * It is also possible to modify arguments by assigning a NativePointer object to an element of this array. * param {object} state - Object allowing you to keep state across function calls. * Only one JavaScript function will execute at a time, so do not worry about race-conditions. * However, do not use this to store function arguments across onEnter/onLeave, but instead * use this which is an object for keeping state local to an invocation. */ onEnter(log, args, state) { log(CCCrypt(op${args[0]}, alg${args[1]}, options${args[2]}, keyLength${args[4]}, iv${args[5]} dataIn${args[6]}, dataInLength${args[7]}, dataOut${args[8]}, dataOutAvailable${args[9]}, dataOutMoved${args[10]})); log(key,hexdump(args[3])); // log(iv,hexdump(args[5])); log(input,hexdump(args[6])); log(input len,args[7]); this.args8args[8]; this.arg10args[10]; }, /** * Called synchronously when about to return from CCCrypt. * * See onEnter for details. * * this {object} - Object allowing you to access state stored in onEnter. * param {function} log - Call this function with a string to be presented to the user. * param {NativePointer} retval - Return value represented as a NativePointer object. * param {object} state - Object allowing you to keep state across function calls. */ onLeave(log, retval, state) { log(output,hexdump(this.args8)); log(output len,hexdump(this.arg10)); } }
改完只会再执行一次命令并且输出到一个文件夹中控制台输出太多会把一些输出冲掉。
frida-trace -UF -i CCCrypt -o 1.txt 这个时候抓包也要开着不然输出太多不好找哪个是你要的。 在这里插入图片描述
把抓包中的sign转成16进制去文件里搜索
有结果输入是fd99ce95acda41c8647d9520a061dba6key的utf-8形式是neteasenewsboard注意如果utf-8是不可见字符的就用16进制形式的。iv是0x0说明没有使用到ivarg10x0说明用的第一种加密模式也就是aesoptions0x3代表PKCS7Padding和ecb模式 拿到cyberchef中加密一下结果也可以对得上。 接下来就是考虑下输入fd99ce95acda41c8647d9520a061dba6是什么了32位考虑md5或者hmac md5这个时候两个你都可以试一下CC_MD5或者CCHmac后者很少碰到优先hook md5这里提一下是为了提醒读者考虑这种情况如果没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 42 43 44 45 46 47 48 49 50 51 52 53 54 /* * Auto-generated by Frida. Please modify to match the signature of CC_MD5. * This stub is currently auto-generated from manpages when available. * * For full API reference, see: https://frida.re/docs/javascript-api/ */ { /** * Called synchronously when about to call CC_MD5. * * this {object} - Object allowing you to store state for use in onLeave. * param {function} log - Call this function with a string to be presented to the user. * param {array} args - Function arguments represented as an array of NativePointer objects. * For example use args[0].readUtf8String() if the first argument is a pointer to a C string encoded as UTF-8. * It is also possible to modify arguments by assigning a NativePointer object to an element of this array. * param {object} state - Object allowing you to keep state across function calls. * Only one JavaScript function will execute at a time, so do not worry about race-conditions. * However, do not use this to store function arguments across onEnter/onLeave, but instead * use this which is an object for keeping state local to an invocation. */ onEnter(log, args, state) { this.args0 args[0]; // 入参 this.args2 args[2]; // 返回值指针 }, /** * Called synchronously when about to return from CC_MD5. * * See onEnter for details. * * this {object} - Object allowing you to access state stored in onEnter. * param {function} log - Call this function with a string to be presented to the user. * param {NativePointer} retval - Return value represented as a NativePointer object. * param {object} state - Object allowing you to keep state across function calls. */ onLeave(log, retval, state) { var ByteArray Memory.readByteArray(this.args2, 16); var uint8Array new Uint8Array(ByteArray); var str ; for(var i 0; i uint8Array.length; i) { var hextemp (uint8Array[i].toString(16)) if(hextemp.length 1){ hextemp 0 hextemp } str hextemp; } log(CC_MD5_arg${this.args0.readUtf8String()}); // 入参 log(CC_MD5_result${str}); // 返回值 log(Thread.backtrace(this.context, Backtracer.ACCURATE) .map(DebugSymbol.fromAddress).join(\n) \n); } }
同时也是开着抓包的。 入参是1E1CE0E2-4FDF-41A1-A9BE-74C5F425B4A61711255091 验证了是标准的md5 入参由两部分组成1E1CE0E2-4FDF-41A1-A9BE-74C5F425B4A6和1711255091前面部分是头部一个固定的值后面的是时间戳。 这样的话sign就被我们成功逆向了仅用frida hook就成功拿到结果了。ios中很多都是这样当然大厂除外。 安卓中的应用后缀是apk,ios中的是ipa安卓中的可以直接扔到jadx中反编译ios的是砸壳后的mach-o文件是扔到ida中的看的是c代码并且这个mach-o文件是很大的如果一个100mb的mach-o文件ida分析都需要好几个小时如果是安卓的so可能也就十几秒的事情。 砸壳的方式有很多种静态砸壳动态砸壳最常用的就是frida-ios-dump
总结
本章案例是比较简单的入门案例感兴趣的可以尝试复现一下有iphone即可。 如果是标准的oc方法ios逆向确实比安卓逆向要简单涉及到自写或者魔改的就需要去看ida中的代码了。