如何通过针对iOS的动态分析技术绕过反调试机制

news2025/3/11 15:23:25

在这篇文章中,我们将跟大家介绍和分析一种针对iOS的新型安全研究技术,该技术能够让iOS应用程序的调试过程更加轻松,并解决那些可能会延缓我们步伐的阻碍。

如果你要对一个采用了反调试技术的iOS应用程序或二进制文件进行调试的话,可能你会感觉困难重重。作为一名安全研究人员,你可能也需要经常面对黑盒测试的场景,而且大多数还会故意对代码进行混淆处理。这样一来,想要简化分析流程就会非常困难,而且很多调试工具和技术都会失效,将本应简单的任务变成了复杂的难题。

在这篇文章中,我们将给大家演示并详细介绍Corellium团队开发的一种新技术,这种技术可以加快iOS应用程序的代码动态分析工作,并解决代码调试过程中可能遇到的各种难题。

什么是反调试技术?

OWASP移动应用程序安全验证标准(MASVS)是一个用于确保移动应用程序安全性的综合标准框架,该标准框架由开放式Web应用程序安全项目(OWASP)设计研发,由各种级别的安全要求和建议组成,提供了移动应用程序安全的基线。在其指导标准中,MASVS解决了移动应用程序实现反逆向工程和调试措施的需要,并强调了这些活动是对应用程序安全和用户隐私的潜在威胁。

尤其是,它强调了整合调试检查机制的重要性。其中包括部署检测和响应调试器,以确保代码和敏感数据在调试会话期间不会暴露,并防止调试工具修改或篡改应用程序。通过实现这些安全实践建议,开发人员可以更好地保护其应用程序免受未经授权的分析和利用,这对于维护应用程序及其用户数据的完整性和机密性至关重要。

下面给出的是目前社区广泛采用的一些反调试技术:

1、使用sysctl检测是否设置了ptrace标志,该标志可能会导致应用程序在内省(在程序运行时确定对象类型的一种能力)状态下终止运行或表现有差异;

2、直接使用ptrace设置PTRACE_DENY_ATTACH,并防止父进程对其进行调试;

3、使用getppid()确定应用程序是否由launchd(pid 1)启动执行;

iOSSecuritySuite库就以非常简洁直接的形式实现了这些检查,并且可以轻松地将其应用到iOS应用程序中。在演示过程中,我们会将其中一个检查以简单二进制文件的形式重新编码实现,并且可以直接从iOS控制台运行。该应用程序也非常简单,其运行流程如下:

1、给一个NSString设置一个随机8字节标记;

2、打印关于用户空间进程的某些有用的调试信息,例如可执行程序的基地址和标记地址;

3、等待用户输入(主要是暂停并绑定调试器);

4、退出;

首先,我们直接运行该应用程序,并且没有启用任何调试保护机制:

iphone:/ root# ./main-allow  

2024-01-24 08:50:08.234 main-allow[736:32888] Flag value: aX1ZWAec

2024-01-24 08:50:08.234 main-allow[736:32888] PID: 736

2024-01-24 08:50:08.234 main-allow[736:32888] Base Address of Main: 0x10000423c

2024-01-24 08:50:08.234 main-allow[736:32888] Address of NSString: 0x16fdff2f8

2024-01-24 08:50:08.235 main-allow[736:32888] Address of actual NSString contents: 0x9142043a0 <--- save this for later

2024-01-24 08:50:08.235 main-allow[736:32888] Pausing for user input...

然后,直接给进程绑定一个debugserver,并给需要交互的远程lldb客户端打开一个端口:

iphone:/ root# ./debugserver16-3 0.0.0.0:3333 -a 736

debugserver-@(#)PROGRAM:LLDB  PROJECT:lldb-1400.2.13.2

 for arm64.

Attaching to process 736...

Listening to port 3333 for a connection from 0.0.0.0...

通过使用二进制代码提供的调试信息,我们可以打印出标志的内容:

(lldb) process connect connect://10.11.0.12:3333                                                                                                                                                                 Process 736 stopped

* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP

    frame #0: 0x00000001c5fe8e84 libsystem_kernel.dylib`__read_nocancel + 8

libsystem_kernel.dylib`:

->  0x1c5fe8e84 <+8>:  b.lo   0x1c5fe8ea4               ; <+40>

    0x1c5fe8e88 <+12>: pacibsp  

    0x1c5fe8e8c <+16>: stp    x29, x30, [sp, #-0x10]!

    0x1c5fe8e90 <+20>: mov    x29, sp

Target 0: (main-allow) stopped.

(lldb) x 0x9142043a0

0x9142043a0: 61 58 31 5a 57 41 65 63 00 00 00 00 00 00 00 00  aX1ZWAec........

0x9142043b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

(lldb)  

没错,我们就可以查看到NSString对象的内容了(程序提供的地址右边)。

现在,我们需要在我们自己的应用程序中重新实现IOSSecuritySuite中的.denyDebugger()方法:

static void denyDebugger() {

    // Dynamic loading of ptrace

    void *handle = dlopen(0, RTLD_GLOBAL | RTLD_NOW);

 

    pid_t pid = getpid();

 

    if (handle) {

        typedef int (*PtraceType)(int request, pid_t pid, caddr_t addr, int data);

        PtraceType ptraceFunction = (PtraceType)dlsym(handle, "ptrace");

 

        if (ptraceFunction) {

            // PT_DENY_ATTACH == 31

            int ptraceRet = ptraceFunction(31, 0, 0, 0);

 

            if (ptraceRet != 0) {

                NSLog(@"Error occurred when calling ptrace(). Denying debugger may not be reliable");

            }

        }

        dlclose(handle);

    }

}

如果我们重新运行附加了额外功能函数的应用程序,我们将能够得到一次完全不一样的体验:

iphone:/ root# ./debugserver16-3 0.0.0.0:3333 -a 739

debugserver-@(#)PROGRAM:LLDB  PROJECT:lldb-1400.2.13.2

 for arm64.

Attaching to process 739...

Segmentation fault: 11

iphone:/ root#  

通过设置PT_DENY_ATTACH标志,debugserver/lldb将无法绑定到目标进程上。但这种技术并不是万能的,因为我们也可以通过钩子和代码修补的组合方式来绕过这种技术。然而,应用程序也可以使用一些技术方法来检测它们当前是否正在被其他工具检测,或应用程序完整性是否被破坏。

那么,我们如何在不给目标应用程序“知情”的情况下对其进行调试呢?

使用Corellium进行调试

Corellium能够提供一个内核级的gdb-stub,我们可以将其与gdb和lldb一起使用。对于想要深入了解iOS内部细节或执行安全漏洞研究的人来说,内核调试器是非常有价值的工具。如果你必须处理云环境中的潜在问题,以提供更快速的调试体验,我们也可以将其与Corellium调试加速器结合使用。

Corellium VM在service_ip:4000上会暴露公内核调试桩,我们可以使用任何适配gdb协议的东西连接到该调试桩。在下面的例子中,我们将使用lldb进行演示:

(lldb) gdb-remote 10.11.1.12:4000

Kernel UUID: EE3449F0-DB47-3596-B253-084A0EBDBDC5

Load Address: 0xfffffff00700c000

WARNING: Unable to locate kernel binary on the debugger system.

Process 1 stopped

* thread #1, stop reason = signal SIGINT

    frame #0: 0xfffffff007d2d0f0

->  0xfffffff007d2d0f0: cbz    x30, -0xff82d2f08

    0xfffffff007d2d0f4: ret     

    0xfffffff007d2d0f8: mov    x0, #0x1

    0xfffffff007d2d0fc: bl     -0xff816d978

Target 0: (No executable module.) stopped.

(lldb) c

Process 1 resuming

我们还可以使用内核调试器来调试用户空间进程,利用监控器过滤功能,我们可以通过进程名称、PID或TID来指定一个用户空间进程,而且还可以使用boe标志(可选)来中断正在进入用户空间的进程:

(lldb) process plugin packet monitor filter user pid:814 boe

接下来,我们将控制内核进入使用pid:标志指定的进程:

(lldb) process plugin packet monitor filter user pid:745 boe

  packet: qRcmd,66696c7465722075736572207069643a37343520626f65

response: OK

Process 1 stopped

* thread #2, stop reason = signal SIGSTOP

    frame #0: 0x00000001c5fe8e84

->  0x1c5fe8e84: b.lo   0x1c5fe8ea4

    0x1c5fe8e88: pacibsp  

    0x1c5fe8e8c: stp    x29, x30, [sp, #-0x10]!

    0x1c5fe8e90: mov    x29, sp

Target 0: (No executable module.) stopped.

从上述代码中我们可以看到,我们已经将调试上下文从内核切换到了用户空间进程。程序也正常运行,但我们仍然在悄悄地调试它。现在,使用程序提供的调试信息,我们可以使用lldb打印用户空间NSString对象的内容:

2024-01-24 09:31:26.294 main-deny[745:40019] Flag value: k5mLCxkR 
2024-01-24 09:31:26.295 main-deny[745:40019] PID: 745 
2024-01-24 09:31:26.295 main-deny[745:40019] Base Address of Main: 0x10000423c 
2024-01-24 09:31:26.295 main-deny[745:40019] Address of NSString: 0x16fdff2f8 
2024-01-24 09:31:26.295 main-deny[745:40019] Address of actual NSString contents: 0x7c24043e0 
2024-01-24 09:31:26.296 main-deny[745:40019] Pausing for user input... 
(lldb) x 0x7c24043e0 
0x7c24043e0: 6b 35 6d 4c 43 78 6b 52 00 00 00 00 00 00 00 00  k5mLCxkR........ 
0x7c24043f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................ 
(lldb)  

后话

当然了,你还可以使用该技术来调试Corellium的非越狱模型。如果你想在未越狱VM中调试com.apple.WebKit.WebContent的话,可以直接绑定一个内核调试器并安装上述步骤操作即可。

参考资料

Technical Q&A QA1361: Detecting the Debugger

Mac OS X Manual Page For ptrace(2)

https://github.com/securing/IOSSecuritySuite/blob/2121b32eb967a2a27c5cf54a369a92c2e36546d3/IOSSecuritySuite/DebuggerChecker.swift

How to Debug the Kernel | Corellium Support Center

Debug Accelerator | Corellium Support Center

参考链接

Defeating debug protections with Corellium

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

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

相关文章

2024年腾讯云最新优惠活动整理汇总

随着云计算技术的不断发展&#xff0c;越来越多的企业和个人开始选择将业务迁移到云端。腾讯云作为国内领先的云计算服务提供商&#xff0c;不仅提供了稳定、安全的云服务&#xff0c;还通过一系列的优惠活动&#xff0c;为用户带来了实实在在的福利。2024年&#xff0c;腾讯云…

链表合集(easy难度)

合并两个有序链表 双指针法 由于list1和list2都是递增的&#xff0c;可以想到用双指针法。假如当前list1这个指针指向的节点被收入完成&#xff0c;那就list1&#xff1b;如果是list2被收入&#xff0c;那就list2。 具体是list1和节点被收入还是list2的节点被收入&#xff…

接口自动化框架搭建(八):pytest+allure+jenkins接入

1&#xff0c;安装allure插件 2&#xff0c;创建jenkins项目 怎么确定路径&#xff0c;可以查看工作空间&#xff0c;jenkins默认根目录就是工作空间 配置执行用例的命令&#xff0c;可以现在pycharm上试一下&#xff0c;然后在jenkins中配置&#xff1a; 把启动java服务的代…

Redis 和 Mysql 数据库数据如何保持一致性

一、操作 我们在实际项目中经常会使用到Redis缓存用来缓解数据库压力&#xff0c;但是当更新数据库时&#xff0c;如何保证缓存及数据库一致性&#xff0c;一般我们采用延时双删策略。 目前系统中常用的做法是一个查询接口&#xff0c;先查询Redis&#xff0c;如果不存在则查…

RockChip Android8.1 Settings

一:Settings一级菜单 1、AndroidManifest.xml 每个APP对应都有一个AndroidManifest.xml,从该文件入手分析最为合适。 packages/apps/Settings/AndroidManifest.xml 根据<category android:name="android.intent.category.LAUNCHER" />可找到当前当前APP a…

教程分享 | GitHub Copilot+ESP开发实战-SPI

准备工作 1. ESP32-C3-DevKitC-1 开发板一块 &#xff1b; 2.SPI转uart小板一块&#xff1b; 3.杜邦线4根、USB线 ; 教程分享 | GitHub CopilotESP开发实战-SPI 一、向Copilot提问 需要实现的功能&#xff1a; 1、ESP32-C3用C语言实现SPI初始化&#xff1b; 2、MOSI为7&a…

帆软报表踩坑日记

最近公司项目要是使用报表&#xff0c;公司使用的是帆软这个国产软件&#xff0c;自己也是学习使用&#xff0c;在使用的过程中记一下问题以及解决方式 公司使用的是帆软8这个版本&#xff0c;比较老了。 首先是表格中的扩展&#xff0c;就是当我们根据数据库查询数据然后放到表…

实时渲染是什么意思?实时渲染和离线渲染的区别

一、实时渲染是什么意思&#xff1f; 实时渲染是指在计算机程序运行时即时地生成图像和动画的过程&#xff0c;这种渲染技术通常用于网络游戏、虚拟现实和增强现实等需要实时交互的XR应用中。实时渲染需要在每秒内渲染数百万到数十亿个像素&#xff0c;以呈现出平滑的动画和交…

以XX医院为例的医疗建筑能效管理系统【建筑能耗 供电可靠 】

一、行业背景 二、行业特点 1.供电可靠性要求高&#xff1a;医院配电系统复杂&#xff0c;门诊、急救、手术室、ICU/CCU、血液透析等场合特一级和一级负荷比较多&#xff0c;一旦发生故障会造成严重影响&#xff0c;对配电可靠性要求极高。 2.能耗水平高&#xff1a;医院能耗…

vue3+threejs新手从零开发卡牌游戏(二十):添加卡牌被破坏进入墓地逻辑

在game目录下新建graveyard文件夹存放墓地相关代码&#xff1a; game/graveyard/p1.vue&#xff0c;这里主要设置了墓地group的位置&#xff1a; <template><div></div> </template><script setup lang"ts"> import { reactive, ref,…

UE5数字孪生系列笔记(三)

C创建Pawn类玩家 创建一个GameMode蓝图用来加载我们自定义的游戏Mode新建一个Pawn的C&#xff0c;MyCharacter类作为玩家&#xff0c;新建一个相机组件与相机臂组件&#xff0c;box组件作为根组件 // Fill out your copyright notice in the Description page of Project Set…

2.java openCV4.x 入门-hello OpenCV

专栏简介 &#x1f492;个人主页 &#x1f4f0;专栏目录 点击上方查看更多内容 &#x1f4d6;心灵鸡汤&#x1f4d6;我们唯一拥有的就是今天&#xff0c;唯一能把握的也是今天 &#x1f9ed;文章导航&#x1f9ed; ⬆️ 1.环境搭建 ⬇️ 3.Mat之构造函数与数据类型 hell…

关于深度学习的 PyTorch 项目如何上手分析?从什么地方切入?

文章目录 PyTorch 项目分析1.背景2.分析流程 PyTorch 项目分析 1.背景 当我们拿到一个 PyTorch 的深度学习项目时&#xff0c;应该怎么入手&#xff1f;怎么去查看代码&#xff1f; 2.分析流程 首先阅读对应项目的 README.md 文件。通过阅读 README.md &#xff0c;一般可以…

HarmonyOS 应用开发之创建PageAbility

开发者需要重写app.js/app.ets中的生命周期回调函数&#xff0c;开发者通过DevEco Studio开发平台创建PageAbility时&#xff0c;DevEco Studio会在app.js/app.ets中默认生成onCreate()和onDestroy()方法&#xff0c;其他方法需要开发者自行实现。接口说明参见前述章节&#xf…

UVA1388 - Graveyard (数学)

Graveyard 题面翻译 题目描述 在一个周长为 10000 10000 10000的圆上等距分别着 n n n个雕塑。现在又有 m m m个新雕塑加入(位置可以随意),希望所有 n m nm nm个雕塑在圆周上分布均匀。这就需要移动其中一些原有的雕塑。要求 n n n个雕塑移动的总距离尽量小。 输入格式 输…

前端-css-01

1.CSS 长度单位和颜色设置 1.1CSS 中的长度单位 px 像素 em 字体大小的倍数&#xff08;字体默认是16px&#xff09; % 百分比 1.2CSS 中的颜色设置方式 1.2.1使用颜色名表示颜色 red、orange、yellow、green、cyan、blue、purple、pink、deeppink、skyblue、greenyellow .…

国产暴雨AI服务器X3418开启多元自主可控新篇章

在当前数字化转型的大潮中&#xff0c;算力作为新质生产力的重要动力引擎&#xff0c;对推动经济社会发展起着关键作用。尤其在人工智能领域&#xff0c;随着高性能、安全可控的AI算力需求持续攀升&#xff0c;国产化服务器的研发与应用显得尤为迫切。 作为国内专业的算力基础…

aeon,一个好用的 Python 库!

更多Python学习内容&#xff1a;ipengtao.com 大家好&#xff0c;今天为大家分享一个好用的 Python 库 - aeon Github地址&#xff1a;https://github.com/aeon-toolkit/aeon 在现代计算机科学和人工智能领域&#xff0c;处理时间序列数据是一个重要而复杂的任务。Python aeon库…

【Roadmap to learn LLM】Large Language Models in Five Formulas

by Alexander Rush Our hope: reasoning about LLMs Our Issue 文章目录 Perpexity(Generation)Attention(Memory)GEMM(Efficiency)用矩阵乘法说明GPU的工作原理 Chinchilla(Scaling)RASP(Reasoning)结论参考资料 the five formulas perpexity —— generationattention —— m…

mysql 常见运算符

学习了mysql数据类型&#xff0c;接下来学习mysql常见运算符。 2&#xff0c;常见运算符介绍 运算符连接表达式中各个操作数&#xff0c;其作用是用来指明对操作数所进行的运算。运用运算符 可以更加灵活地使用表中的数据&#xff0c;常见的运算符类型有&#xff1a;算…