IOS逆向入门与技巧分享-以ByteCTF的极限逃脱为例
字数 1244 2025-08-22 12:23:30
iOS逆向入门与技巧分享 - 以ByteCTF的极限逃脱为例
一、iOS逆向基础流程
-
标准逆向流程:
- 脱壳 -> class-dump -> 抓包 -> 逆向分析
- 分析软件核心算法
-
iOS应用特点:
- 苹果市场会对应用进行加壳
- 可使用frida进行dump脱壳
- iOS函数参考可在Apple Development上查找
二、常用工具推荐
硬件选择
-
Android设备:
- 推荐Pixel/Nexus系列
- 系统版本6~13
- 通过Magisk进行root
-
iOS设备:
- 推荐iPhone 6、iPhone 8/X/SE等
- 系统版本13或14
- 注意是否有ID锁和刷机可能性
iOS越狱后必备插件
- Apple File Conduit"2":激活助手类工具的访问权限
- AppSync Unified:绕过应用签名验证
- Filza File Manager:文件管理器
- SSL Kill Switch 2:iOS版的justtrustme
- OpenSSH:用于电脑连接
电脑端工具
- IDA:经典逆向分析工具
- ifunbox:iPhone文件管理
- frida:动态分析框架
- frida-ios-dump:一键脱壳工具
- class-dump:提取头文件
- iproxy:端口转发工具
三、ByteCTF极限逃脱题目分析
1. 题目特点
- 直接提供ipa文件
- 解压ipa后可直接用IDA分析
2. 逆向分析逻辑
第一部分:随机数验证
void __cdecl -[ViewController firsButtonClicked:](ViewController *self, SEL a2, id a3) {
uint32_t v4 = arc4random_uniform(0x1F4u); // 生成随机数
// ...省略部分代码...
if ( v12 == (void *)v4 ) { // 输入值与随机数比较
// 验证成功逻辑
// 显示提示信息"恭喜你拿到入场券"
// 解锁后续功能
} else {
// 验证失败逻辑
// 显示"咒语错误"
}
}
关键点:
- 使用
arc4random_uniform生成随机数 - 需要绕过随机数验证才能进入第二部分
第二部分:Flag验证
输入处理流程:
-
检查输入格式:
CFSTR("^ByteCTF\\{([0-9a-z]){8}-([0-9a-z]){4}-([0-9a-z]){4}-([0-9a-z]){4}-([0-9a-z]){12}")- 标准格式:
ByteCTF{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
- 标准格式:
-
去除格式标记:
- 去掉"ByteCTF"前缀
- 去掉花括号"{"和"}"
- 按"-"分隔字符串
字符串重构:
-
获取五个固定字符串:
id __cdecl -[ViewController first](ViewController *self, SEL a2) { return CFSTR("ffb53588"); } id __cdecl -[ViewController second](ViewController *self, SEL a2) { return CFSTR("b092"); } id __cdecl -[ViewController third](ViewController *self, SEL a2) { return CFSTR("bd3e"); } id __cdecl -[ViewController fourth](ViewController *self, SEL a2) { return CFSTR("e777"); } id __cdecl -[ViewController fifth](ViewController *self, SEL a2) { return CFSTR("a67be199da4b"); } -
按5-2-3-4-5格式重构字符串:
- 最终格式:
a67be199da4b-b092-bd3e-e777-a67be199da4b
- 最终格式:
加密处理:
-
对重构字符串进行SHA256加密:
CC_SHA256(v47, v48, (unsigned __int8 *)md);- 得到哈希值:
6c9838a3c6810bdb2633ed5910b8547c09a7a4c08bf69ae3a95c5c37f9e8f57e
- 得到哈希值:
-
字符串处理:
- 取前32位:
6c9838a3c6810bdb2633ed5910b8547c
- 取前32位:
最终Flag构造:
flag = "6c9838a3c6810bdb2633ed5910b8547c"
print("ByteCTF{",end="")
print(flag[1:9],end="-") # 第1-9字符,长度8
print(flag[9:9+4],end="-") # 第9-13字符,长度4
print(flag[5:5+4],end="-") # 第5-9字符,长度4
print(flag[5:5+4],end="-") # 第5-9字符,长度4
print(flag[5:5+12],end="}") # 第5-17字符,长度12
最终Flag:
ByteCTF{c9838b3c-6810-8a3d-8a3c-8a3c6810bdb2}
四、总结
-
iOS逆向与Android逆向流程相似,主要区别在于:
- 文件格式不同
- 使用的库函数不同
-
关键技巧:
- 熟悉Objective-C方法调用模式
- 掌握iOS特有的加密和字符串处理方式
- 理解iOS应用的沙盒机制和权限系统
-
对于熟悉Android逆向的开发者,过渡到iOS逆向并不困难,主要需要适应不同的工具链和API。