iOS逆向 - 应用安全攻防(越狱与非越狱)

iOS 逆向篇章目录 :
• 1️⃣、RSA加密原理&密码学&HASH
• 2️⃣、应用签名原理及重签名 (重签微信应用实战)
• 3️⃣、shell 脚本自动重签名与代码注入
• 4️⃣、重签应用调试与代码修改 (Hook)
• 5️⃣、Mach-O文件
• 6️⃣、Hook / fishHook 原理与符号表
• 7️⃣、LLDB由浅至深
• 8️⃣、lldb高级篇 Chisel 与 Cycript
• 9️⃣、越狱初探
• 🔟、实战篇-钉钉打卡插件
前言
逆向篇章从前导知识到工具使用和原理分析我们都已经讲述完毕了 , 也结合了实际案例来进行巩固 . 那么接下来 , 进入到我们学习逆向的最重要的目标篇章 , 应用安全攻防 .
这是一个大篇章 , 文章如果过长会分两篇讲述 .
学习逆向最重要的就是知道如何防护 , 本文会列举一些目前市面上较为常见的逆向攻击方式应该讲讲如何防护 , 这些做法并不唯一也不一定最好 , 如有心得欢迎交流 .
关于防护
关于应用防护 , 我们首先要有几个前提概念要清楚 .
• 1️⃣ : 没有绝对安全的程序 .
没有绝对安全的应用 , 我们所要做的就是尽最大可能混淆 or 浪费攻击者的时间 , 加大攻击成本 .
• 2️⃣ : 针对检测到调试和注入时的操作 , 尽量不要做非常明显的退出应用 or 提示 等操作 .
o 对于一个经验比较丰富 ( 相对防护者来说 ) 的逆向工程师 , 当发现调试 / 注入代码工程运行时与正版应用正式运行有明显的区别时 , 很容易顺藤摸瓜找到相应的防护或者监测处理逻辑和技术 .
o ( 比如经常也有一些同学问到 , 为什么重签名了之后工程一运行就闪退 , 正版应用就没问题 , 那么就很容易得知很可能是利用了 ptrace 或者引入包监测 / 包名监测之类的处理 ) .
o 相对而言目前市面上许多大厂所使用的的 , 监测到此行为会记录设备 / 账户等信息进行上报和封号等措施则是在无形之中做到了较为有效的防护 .

  1. 动态调试
    进攻 :
    对于非越狱环境来说 , 重签名进行动态调试 , yololib 修改 mach-o 中 Load Commands 让 DYLD 加载攻击者所编写的动态库从而进行 hook 来完成代码注入是最为常见的了 . ( 这里不会详细讲述进攻过程和效果 , 不熟悉的同学可以翻一翻目录中 2,3,4 这三篇文章有详细的操作演示 ) .
    利用重签名工程的特性 , 其实这种解决方案有特别多 , 这里挑几个比较有代表性的防护措施列举一下 .
    防护方式 1 : 干掉 lldb - ptrace
    利用重签名工程运行调试特性 , 我们可以通过禁止开发环境使用 lldb 来实现重签名工程运行闪退的效果 .
    lldb 的原理这里提一点 :
    • lldb 本质上是一个 GUI 断点和命令收集工具 + debug server 通过进程附加到当前运行进程中来实现的 .
    ( Xcode 自带的 Debug - Attach to process 就是根据 DebugServer 来实现的 )
    ptrace
    ptrace 是 命令行工程以及 Mac OS 工程里的 <sys/ptrace.h> 提供的一个函数 , 可以用来来控制进程附加管理 , 它可以实现禁止应用程序进程被附加的效果 . 在 iOS 中并没有暴露出来 , 但是 iOS 是可以使用的 .
    笔者这里将该头文件导出 , ( 链接 - 密码: iaqp ) 下载后导入工程中就可以使用了 .
    使用如下 :
    /**
    arg1: ptrace要做的事情: PT_DENY_ATTACH 表示要控制的是当前进程不允许被附加
    arg2: 要操作进程的PID , 0就代表自己
    arg3: 地址 取决于第一个参数要做的处理不同传递不同
    arg4: 数据 取决于第一个参数要做的处理不同传递不同
    */
    ptrace(PT_DENY_ATTACH, 0, 0, 0);
    复制代码
    处理后效果
    代码添加完毕后 :
    • 运行工程 , 程序闪退 .
    • 从手机点开应用 , 应用正常 .
    • 使用Xcode 自带的 Debug - Attach to process 发现附加失败 .
    防护手段评估
    • 1️⃣ : 越狱环境下 lldb-debug server 同样可以防护 .
    • 2️⃣ : 这种做法比较暴力 , 而且影响本身正向开发 , 只能在正向开发时不使用 , 打包上架时再打开 .
    • 3️⃣ : 这种做法效果比较明显 , 很容易推断出来使用了这个机制 , 一个符号断点就能轻松查到 .
    • 4️⃣ : 破解起来也比较简单 , 使用 fishhook 可以很轻易的 hook 掉 ptrace 这个函数 .
    ( 坊间传闻早期支付宝有使用过这种方式 , 不过并没有实据 , 全当一听 )
    提示
    Cycript 本身是从正在运行的进程中读取数据 , 并不是进程附加的原理 , 并不能通过 ptrace 防护 .
    防护手段破解
    破解这个也有较多方式 , 比如直接修改二进制汇编代码 ( bl -> nop ) , hook 掉 ptrace 等等 .
    最简单的方式就是插入一个动态库 , 在这个库的 load 中使用 fishhook 直接把 ptrace hook 掉即可 . ( 关于 fishhook 参阅 fishHook 原理与符号表 这篇文章有从使用到原理解释的完整内容 , 这里就不再演示了 ) .
    Monkeydev 中默认就已经使用了 fishhook 交换了 ptrace .
    防护方式 2 : sysctl
    sysctl ( system control ) 是由 <sys/sysctl.h> 提供的一个函数 , 它有很多作用 , 其中一个是可以监测当前进程有没有被附加 . 但是因为其特性 , 只是监测当前时刻应用有没有被附加 .
    因此正向开发中我们往往结合定时器一起使用 , 或者 定时 / 定期 / 在特定时期 去使用 .
    使用如下 :
    #import “ViewController.h”
    #import <sys/sysctl.h>
    @interface ViewController ()
    @end

@implementation ViewController
BOOL isDebug(){
int name[4]; //里面放字节码。查询的信息
name[0] = CTL_KERN; //内核查询
name[1] = KERN_PROC; //查询进程
name[2] = KERN_PROC_PID; //传递的参数是进程的ID
name[3] = getpid(); //获取当前进程ID

struct kinfo_proc info;  //接受查询结果的结构体
size_t info_size = sizeof(info);  //结构体大小
if(sysctl(name, 4, &info, &info_size, 0, 0)){
    NSLog(@"查询失败");
    return NO;
}
/**
查询结果看info.kp_proc.p_flag 的第12位。如果为1,表示调试状态。
(info.kp_proc.p_flag & P_TRACED) 就是0x800, 即可获取第12位
*/
return ((info.kp_proc.p_flag & P_TRACED) != 0);

}

static dispatch_source_t timer;
void debugCheck(){
timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(0, 0));
dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC, 0.0 * NSEC_PER_SEC);
dispatch_source_set_event_handler(timer, ^{
if (isDebug()) {//在这里写你检测到调试要做的操作
NSLog(@“调试状态!”);
}else{
NSLog(@“正常!”);
}
});
dispatch_resume(timer);
}

  • (void)viewDidLoad {
    [super viewDidLoad];
    debugCheck();
    }
    复制代码
    处理后效果
    这个显示层面的效果根据你自定义的结果决定 , 你检测到后决定做上报还是闪退都可以 .
    防护手段评估
    • 1️⃣ : 越狱环境下 lldb-debug server 同样可以检测到 , 但同样会影响本身正向开发 .
    • 2️⃣ : 这种做法比较灵活 , 可以自定义处理结果 , 上报很容易做到无形 .
    • 3️⃣ : 破解起来也相对简单 , 使用 fishhook hoo
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值