当前位置: 首页 > news >正文

10.苹果ios逆向-FridaHook-ios中的算法-CCMD5

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动!

内容参考于:图灵Python学院

工具下载:

链接:百度网盘 请输入提取码

提取码:zy89

复制这段内容后打开百度网盘手机App,操作更方便哦

上一个内容:9.苹果ios逆向-FridaHook-ios中的算法(CCCrypt)

上一个内容中通过CCCrypt算法拦截到了入参,如下图,搜索加密的数据

然后通过搜索加密的数据找它的被加密数据,7297aae7048485ac95238be125de0a1b,它的长度32位像是MD5加密,所以接下来开始拦截MD5加密

然后hookMd5算法使用,frida-trace -Up 进程id(使用frida-ps -Ua指令查询) -i CC_MD5 指令

它也是会给我创建一个文件

文件内容

还是全选复制给大模型,让大模型给我们介绍,给我们说明

onEnter说明,可以看出args[0]是要被md5加密的数据

onLeave说明

然后让大模型给我写代码,让它输出明文和密文,

/** 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) {var input = args[0].readUtf8String();log('明文: ' + input);this.input = input;log('CC_MD5()');},/*** 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) {// 假设retval指向MD5结果的16字节缓冲区var hex = '';for (var i = 0; i < 16; i++) {var b = retval.add(i).readU8();hex += ('0' + b.toString(16)).slice(-2);}log('密文(十六进制): ' + hex);}
}

效果图:通过上方的MD5成功在MD5拦截里找到了

被MD5加密的数据

总结:

第一步使用 EC74E1D8-7511-4D03-8836-534842029CAE1754189311 做MD5加密

第二步获取MD5加密的值

第三步把MD5加密后的数据进行AES的CBC模式IV是0,然后加密就可以了

# 导入需要的工具包
# hashlib:用来做MD5加密的工具
# AES:用来做AES加密的工具
# binascii和base64:用来转换加密结果格式的工具
import hashlib
from Crypto.Cipher import AES
import binascii
import base64def aes_encrypt(key, data, mode, iv=None):"""这个函数是用来做AES加密的key:加密用的"钥匙"(必须是字节形式)data:要加密的数据(必须是字节形式)mode:加密模式(就像不同类型的锁)iv:初始化向量(某些锁需要这个辅助工具)"""# 根据选择的模式创建加密器(就像选不同的锁)if mode == AES.MODE_ECB:# ECB模式的锁比较简单,不需要ivcipher = AES.new(key, mode)else:# 其他模式(比如CBC)需要iv才能工作cipher = AES.new(key, mode, iv=iv)# 用创建好的加密器加密数据encrypted_data = cipher.encrypt(data)return encrypted_dataif __name__ == "__main__":# 我们要处理的原始字符串(可以想象成一封明文信)original_str = "EC74E1D8-7511-4D03-8836-534842029CAE1754193769"print(f"原始字符串: {original_str}")# 第一步:用MD5处理原始字符串# MD5就像把信揉成一个固定大小的纸团# 不管原来的信有多长,揉完都是32个字符md5_hash = hashlib.md5()# 把字符串变成计算机能处理的字节形式(加utf-8编码)md5_hash.update(original_str.encode('utf-8'))# 得到MD5处理后的结果(32个字符的字符串)md5_hex = md5_hash.hexdigest()print(f"MD5加密结果(十六进制): {md5_hex}")print(f"MD5十六进制长度: {len(md5_hex)}字符")  # 这里会显示32# 第二步:把MD5结果变成字节形式# 因为计算机只认识字节(0和1组成的信号)md5_bytes = md5_hex.encode('utf-8')print(f"MD5十六进制转字节后长度: {len(md5_bytes)}字节")  # 这里会显示32# 第三步:给数据"补零"# AES加密有个规矩:数据长度必须是16的倍数(就像快递必须用标准箱子)# 计算需要补多少个0才能凑够16的倍数pad_length = (16 - (len(md5_bytes) % 16)) % 16# 补充0字节(这里32正好是16的2倍,所以其实不用补,但代码还是做了准备)data = md5_bytes + b'\x00' * pad_lengthprint(f"补全后的数据长度: {len(data)}字节")  # 这里会显示32print(f"补全后的数据(十六进制): {binascii.hexlify(data).decode('utf-8')}")# 第四步:准备AES加密的"钥匙"key_str = "neteasenewsboard"  # 钥匙的字符串形式key = key_str.encode('utf-8')  # 转成计算机能认的字节形式print(f"AES密钥: {key.hex()} ({key_str})")# 准备几个不同的"辅助钥匙"(IV)# IV是CBC模式需要的辅助工具,必须是16字节iv1 = b'\x00' * 16  # 全是0的辅助钥匙iv2 = key[:16]      # 用主钥匙的前16个字节做辅助钥匙iv3 = data[:16]     # 用数据的前16个字节做辅助钥匙# 准备尝试不同的加密模式(不同类型的锁)modes = [("ECB模式", AES.MODE_ECB, None),  # ECB模式不需要辅助钥匙("CBC模式 (全0辅助钥匙)", AES.MODE_CBC, iv1),("CBC模式 (用主钥匙做辅助钥匙)", AES.MODE_CBC, iv2),("CBC模式 (用数据做辅助钥匙)", AES.MODE_CBC, iv3)]# 逐个尝试这些加密模式for mode_name, mode, iv in modes:try:# 执行AES加密encrypted = aes_encrypt(key, data, mode, iv)# 把加密结果转成十六进制字符串(方便查看)encrypted_hex = binascii.hexlify(encrypted).decode('utf-8')# 把加密结果转成Base64格式(另一种常用格式)encrypted_base64 = base64.b64encode(encrypted).decode('utf-8')# 显示加密结果print(f"\n{mode_name}:")print(f"使用的辅助钥匙: {binascii.hexlify(iv).decode('utf-8') if iv else '不需要'}")print(f"加密结果(十六进制): {encrypted_hex}")print(f"加密结果(Base64): {encrypted_base64}")except Exception as e:# 如果加密失败,显示错误信息print(f"❌ {mode_name} 加密失败: {str(e)}")

上方的代码是通过把下图红框的内容复制给ai大模型,它生成的,注意下方的代码是MD5后的,上方的代码是先用下图红框的内容生成AES加密,然后再告诉ai大模型md5的逻辑,然后在整合到aes加密里

效果图:

 


img

http://www.dtcms.com/a/314562.html

相关文章:

  • curl发送文件bodyParser无法获取请求体的问题分析
  • RAG From Scratch 系列教程-3: Routing
  • 将AAL图谱对应到Yeo7大网络中【原理,代码分析】
  • 断点续传Demo实现
  • 16.8 华为昇腾CANN架构深度实战:3大核心引擎解析与性能优化216%秘籍
  • C++高频知识点(十四)
  • 如果发送的数据和接受的数据不一致时,怎么办?
  • 从 Hive 数仓出发,全面剖析 StarRocks、MySQL、HBase 的使用场景与区别
  • Linux-Day02.Linux指令
  • Vue 3 + AntV X6 实现流程编辑功能
  • C语言-指针[指针数组和数组指针]
  • 【web应用】Maven:Java 生态的构建与依赖管理利器
  • LeetCode算法日记 - Day 1: 移动零、复写零
  • 排序算法——归并排序(图文演示)
  • 最小二乘法MSE
  • 【Linux】重生之从零开始学习运维之GTID复制
  • 【动态规划 | 回文字串问题】动态规划解回文问题的核心套路
  • docker镜像源配置教程,以及解决安装好docker配置镜像源后,出现报错。Job for docker.service failed
  • 在 C++ 中实现类似 Vue 3 的 Pinia 状态管理库
  • C++模板知识点3『std::initializer_list初始化时逗号表达式的执行顺序』
  • 2025-08月特辑---私有化部署gitea仓库
  • Android UI 组件系列(九):ListView 性能优化与 ViewHolder 模式实战
  • 信息安全概述
  • LightRAG:大模型时代的低成本检索利器
  • HCIP笔记1
  • OpenCV计算机视觉实战(18)——视频处理详解
  • 经典设计模式
  • 电商系统想撑住大流量?ZKmall开源商城靠微服务 + Spring Boot3 解决单体架构难题
  • VS2019 Qt5.14.2 OpenCV4.4.0 全流程安装及开发环境搭建与配置(工业相机环境配置)
  • SpringMVC在前后端分离架构中的执行流程详解