ios逆向某新闻 md5+aes

news2025/1/11 0:01:27

本期的案例比较简单,也许是ios逆向算法本来就比较简单的原因,所以前面我就多扯一些爬虫和逆向的东西。之前写的文章都是js逆向和android逆向的案例,这也是首篇ios的案例,所以会从入门开始讲起。

3大逆向对比

首先爬虫工程师大部分都是需要js逆向的,会安卓的人不多,ios的就更不用说了,js逆向中会安卓逆向的保守估计不超过40%,因为大部分人搞爬虫都是从js开始的,当然少部分会从安卓开始,而ios逆向和安卓逆向的比例不超过1:5,你去各大社区的论坛帖子数对比下就知道了,网上的ios协议分析也是少的可怜。学ios逆向有什么用处呢?对我们爬虫工程师来说就是可以增加一个技能,让你的简历脱颖而出,
很多招聘要求上都有写,会安卓逆向的优先,会ios逆向的优先。其次,ios的逆向及风控要比安卓逆向弱很多,如果安卓上业务过不去可以考虑ios,ios的很多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.args8=args[8];

    this.arg10=args[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进制去文件里搜索

有结果,输入是fd99ce95acda41c8647d9520a061dba6,key的utf-8形式是neteasenewsboard,注意,如果utf-8是不可见字符的就用16进制形式的。iv是0x0,说明没有使用到iv,arg1=0x0说明用的第一种加密模式也就是aes,options=0x3代表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中的代码了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2257073.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot【一】零基础入门 springboot 及 idea 搭建

一、前言 springboot是什么&#xff1f; Spring Boot是由Pivotal团队提供的全新框架&#xff0c;其设计目的是用来简化新Spring应用的初始搭建以及开发过程。 该框架使用了特定的方式来进行配置&#xff0c;从而使开发人员不再需要定义样板化的配置。用我的话来理解&#xff0…

2024年超大跨径钢结构桥梁创新技术论坛暨钢桥联盟年度工作会议顺利召开

12月5日&#xff0c;由中交公路规划设计院有限公司、装配化钢结构桥梁产业技术创新战略联盟主办&#xff0c;保利长大工程有限公司、中交第二航务工程局有限公司、中交第二公路工程局有限公司、中交路桥建设有限公司、中交西安筑路机械有限公司、南京现代综合交通实验室、巨力锁…

win10上部署win11记事本

win10上部署win11记事本 原因 win10的老用户们, 不肯升级win11, 绝对是有留恋的东西吧,就想win7用户那样, 但是win11在日益更新, 特别是记事本, 增加了很多好用的功能, 比如多标签页, 但是不想升级win11, 还想用, 怎么办? 我在网上找到了解决方案, 接下来, 我们来操作一下吧…

记录:ubuntu24.04源码安装nginx

一. 下载Nginx源码 两个地址二选一即可 Nginx官网Nginx官网 Github eg&#xff1a;nginx-1.27.3.tar.gz 下载到 ubuntu24.04 的 Downloads &#xff0c;解压 cd Downloads tar -zxvf nginx-1.27.3.tar.gz二. 编译安装 Note: 编译最好用 root 权限&#xff0c; 使用下面命令…

【前端】深入理解 JavaScript 中的数组与对象

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: 前端 文章目录 &#x1f4af;前言&#x1f4af;数组与对象的基本概念数组&#xff08;Array&#xff09;数组示例 对象&#xff08;Object&#xff09;对象示例 &#x1f4af;数组与对象的对比核心区别如何选择&#…

31.下一个排列 python

下一个排列 题目题目描述示例 1&#xff1a;示例 2&#xff1a;示例 3&#xff1a;提示&#xff1a;题目链接 题解解题思路python实现代码解释&#xff1a;提交结果 题目 题目描述 整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。 例如&#xff0c;arr [1,2,3…

Codeforces Round 992 (Div. 2)

这场cf只在b卡了一下&#xff0c;因为b真是犯蠢了&#xff0c;我以为会向下取整&#xff0c;结果是完全就不取整&#xff0c;或者说是向上取整&#xff0c;卡了我半个小时&#xff0c;要不是紧急看了题一下&#xff0c;昨天那场就毁了 话不多说&#xff0c;直接开讲 A. Game …

vue入门实战(二)父子组件显示,参数传递

经过上次的写法&#xff0c;我们已经写出每个list项&#xff0c;现在要在每个父组件下面加入自己的子项 一、新建子组件&#xff1a; smallItem.vue&#xff1a; <script> export default{props:[text,id,status] //父组件传来的参数 } </script> <template>…

批量验证指定漏洞思路和流程

免责申明 本文仅是用于学习研究POC的地址收集与漏洞验证原理,请勿用在非法途径上,若将其用于非法目的,所造成的一切后果由您自行承担,产生的一切风险和后果与笔者无关;本文开始前请认真详细学习《‌中华人民共和国网络安全法》【学法时习之丨网络安全在身边一图了解网络安…

Android 事件分发机制详解/ 及Activity启动流程浅谈

目前网上的事件分发机制文章很多&#xff0c;可能大家看了很多&#xff0c;还是很懵逼&#xff0c;这篇文章是我自己总结的事件分发机制&#xff0c;提取了在事件分发机制中&#xff0c;最精华的部分&#xff0c;如果对事件分发还是不太清楚&#xff0c;可以看看这篇文章 更多…

蓝桥杯刷题日记02-小球反弹

问题描述 有一长方形&#xff0c;长为 343720343720 单位长度&#xff0c;宽为 233333233333 单位长度。在其内部左上角顶点有一小球 (无视其体积)&#xff0c;其初速度如图所示且保持运动速率不变&#xff0c;分解到长宽两个方向上的速率之比为 dx:dy15:17dx:dy15:17。小球碰…

SkyWalking 和 ELK 链路追踪实战

一、背景 最近在给项目搭建日志平台的时候&#xff0c;采用的方案是 SkyWalking ELK 日志平台&#xff0c;但发现 ELK 日志平台中的日志没有 Trace ID&#xff0c;导致无法追踪代码报错的整体链路。 空哥提示&#xff1a;Trace ID 是分布式追踪中用来唯一标识一个服务请求或事…

Ubuntu22.04深度学习环境安装【cuda+cudnn】

为了复现一篇深度学习论文&#xff0c;特意安装了Linux系统。前一天已经安装Linux显卡驱动&#xff0c;现在需要安装cuda、cudnn等。 论文代码 论文PDF 确定包版本&#xff1a; 根据论文提供的代码。在requirements.txt中发现cuda版本为11.7,cudnn为8.5.0&#xff0c;python没…

ue5 motion matching

ue5.5 gameanimationsample 先看动画蓝图 核心两个node 第一个是根据数据选择当前的pose 第二个是缓存一段历史记录&#xff0c;为第一个node选择的时候提供数据。 在animinstance的update方法中 每帧都更新这个函数&#xff0c;每帧更新trajectory的数据 看看第一个node的…

mycat2 分库分表

mycat2读写分离 mysql主从复制 mycat2 分库分表 实在 配置mycat2 读写分离 及主从复制的基础上完成的 以下所有操作 在mycat 登录后执行 一、配置分库分表数据源 name:数据名称 一般以以最后一个字母判断 r 是读 w是写 url&#xff1a; 真实数据源ip地址 理论上是每一个ip都…

python pandas数据处理,对比两个xlsx文档的两列数据做对比匹配,然后复制单元格值

1&#xff0c;文档数据 文档A 批次编号编号风险等级意见ps001code1低风险同意ps001code2中风险同意ps001code3低风险同意ps001code4低风险同意ps001code5低风险同意ps001code6低风险同意ps002code11低风险同意ps002code12中风险否决ps002code13低风险否决ps002code14低风险否决…

Pytorch 手写数字识别 深度学习基础分享

本篇是一次内部分享&#xff0c;给项目开发的同事分享什么是深度学习。用最简单的手写数字识别做例子&#xff0c;讲解了大概的原理。 手写数字识别 展示首先数字识别项目的使用。项目实现过程: 训练出模型准备html手写板flask 框架搭建简单后端 简单手写数字识别 深度学习必…

WPS EXCEL 使用 WPS宏编辑器 写32位十六进制数据转换为浮点小数的公式。

新建EXCLE文件 另存为xlsm格式的文件 先打开WPS的开发工具中的宏编辑器 宏编辑器编译环境 在工作区添加函数并编译&#xff0c;如果有错误会有弹窗提示&#xff0c;如果没有错误则不会弹 函数名字 ”HEXTOFLOAT“ 可以自己修改。 function HEXTOFLOAT(hex) { // 将十六…

沃丰科技智能客服在跨境电商独立站中的核心角色

随着全球化进程的加速和互联网技术的不断发展&#xff0c;跨境电商行业蓬勃兴起&#xff0c;为消费者提供了更广阔、更便捷的购物选择。在这样一个竞争激烈的市场环境中&#xff0c;优质的客户服务成为了企业脱颖而出的关键。沃丰科技智能客服凭借其先进的技术和人性化的设计理…

langgraph实现无观测推理 (Reasoning without Observation)

图例 1. 图状态 在 LangGraph 中&#xff0c;每个节点都会更新一个共享的图状态。当任何节点被调用时&#xff0c;状态就是该节点的输入。 下面&#xff0c;我们将定义一个状态字典&#xff0c;用以包含任务、计划、步骤和其他变量。 from typing import List from typing…