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

在这篇文章中,我们将跟大家介绍和分析一种针对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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于龙芯2k1000 mips架构ddr调试心得(二)

1、内存控制器概述 龙芯处理器内部集成的内存控制器的设计遵守 DDR2/3 SDRAM 的行业标准&#xff08;JESD79-2 和 JESD79-3&#xff09;。在龙芯处理器中&#xff0c;所实现的所有内存读/写操作都遵守 JESD79-2B 及 JESD79-3 的规定。龙芯处理器支持最大 4 个 CS&#xff08;由…

【JVM】JVM类加载过程

文章目录 &#x1f334;类加载过程&#x1f338;加载&#x1f338;加载&#x1f338;验证&#x1f338;准备&#x1f338;解析&#x1f338;初始化 &#x1f332;双亲委派模型&#x1f338;什么是双亲委派模型&#xff1f;&#x1f338;双亲委派模型的优点 ⭕总结 &#x1f334…

【2】单链表

【2】单链表 1、单链表2、单链表的设计3、接口设计4、SingleLinkedList5、node(int index) 返回索引位置的节点6、clear()7、添加8、删除9、indexOf(E element) 1、单链表 &#x1f4d5;动态数组有个明显的缺点 &#x1f58a; 可能会造成内存空间的大量浪费 &#x1f4d5; 能否…

云原生架构(微服务、容器云、DevOps、不可变基础设施、声明式API、Serverless、Service Mesh)

前言 读完本文&#xff0c;你将对云原生下的核心概念微服务、容器云、DevOps、Immutable Infrastructure、Declarative-API、Serverless、Service Mesh 等有一个相对详细的了解&#xff0c;帮助你快速掌握云原生的核心和要点。 因题主资源有限, 这里会选用部分云服务商的组件进…

算法沉淀——拓扑排序

前言&#xff1a; 首先我们需要知道什么是拓扑排序&#xff1f; 在正式讲解拓扑排序这个算法之前&#xff0c;我们需要了解一些前置知识&#xff08;和离散数学相关&#xff09; 1、有向无环图&#xff1a; 指的是一个无回路的有向图。 入度&#xff1a;有向图中某点作为图…

数字图像处理——直方图的均衡化

1.方法简介&#xff1a; 直方图均衡化通常用来增加许多图像的全局对比度&#xff0c;尤其是当图像的有用数据的对比度相当接近的时候。通过这种方法&#xff0c;亮度可以更好地在直方图上分布。这样就可以用于增强局部的对比度而不影响整体的对比度&#xff0c;直方图均衡化通…

01---java面试八股文——mybatis-------10题

1、什么是MyBatis Mybatis是一个半ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;它内部封装了JDBC&#xff0c;开发时只需要关注SQL语句本身&#xff0c;不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。程序员直接编写原生态sql&#xff0c…

基于51单片机和MAX1898的智能手机充电器设计

**单片机设计介绍&#xff0c;基于51单片机和MAX1898的智能手机充电器设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于51单片机和MAX1898的智能手机充电器设计概要 一、引言 随着智能手机的普及&#xff0c;其电池续航…

图像分类实战:深度学习在CIFAR-10数据集上的应用

1.前言 图像分类是计算机视觉领域的一个核心任务&#xff0c;算法能够自动识别图像中的物体或场景&#xff0c;并将其归类到预定义的类别中。近年来&#xff0c;深度学习技术的发展极大地推动了图像分类领域的进步。CIFAR-10数据集作为计算机视觉领域的一个经典小型数据集&…

NumPy介绍及其应用领域

1.NumPy介绍 ​NumPy&#xff08;Numerical Python&#xff09;是 Python 的一个开源的扩展程序库&#xff0c;支持大量的维度数组与矩阵运算&#xff0c;此外也针对数组运算提供大量的数学函数库。NumPy的前身为Numeric&#xff0c;起初由Jim Hugunin与其他协作者共同开发&…

机器学习和深度学习的简单对比

如图1-2所示&#xff0c;深度学习&#xff08;DeepLearning&#xff0c;DL&#xff09;属于机器学习的子类。它的灵感来源于人类大脑的工作方式&#xff0c;这是利用深度神经网络来解决特征表达的一种学习过程。深度神经网络本身并非是一个全新的概念&#xff0c;可理解为包含多…

Python基础入门 --- 9.异常、模块

文章目录 第九章&#xff1a;9.异常9.1 异常的捕获9.1.1 捕获指定异常9.1.2 捕获多个异常9.1.3 捕获全部异常9.1.4 异常else9.1.5 异常的finally 9.2 异常的传递性9.3 Python模块9.3.1 模块的导入import模块名from 模块名 import 功能名from 模块名 import *as定义别名 9.3.2 自…

2024年水电站大坝安全监测工作提升要点

根据《水电站大坝运行安全监督管理规定》&#xff08;国家发改委令第23号&#xff09;和《水电站大坝运行安全信息报送办法》&#xff08;国能安全〔2016〕261号&#xff09;的相关规定、要求&#xff0c;电力企业应当在汛期向我中心报送每日大坝汛情。近期&#xff0c;全国各地…

帆软报表踩坑日记

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

谷粒商城实战(007 压力测试)

Java项目《谷粒商城》架构师级Java项目实战&#xff0c;对标阿里P6-P7&#xff0c;全网最强 总时长 104:45:00 共408P 此文章包含第141p-第p150的内容 简介 安装jmeter 安装jmeter 使用中文 这样写就是200个线程循环100次 一共是2万个请求 介绍线程组 添加请求 可以是htt…

供应链销售数据分析丨跟张良均老师学大数据人工智能(第二期)

师傅带练 项目背景 通过大数据分析怡亚通供应链商品的销售数据&#xff0c;分析不同店铺地址、不同销售季节和不同产品的销售数据&#xff0c;可以给于客户铺货支持以及经营策略建议&#xff0c;帮助怡亚通更好地优化库存管理、供货策略和市场营销活动&#xff0c;从而提升销…

计算机视觉的应用25-关于Deeplab系列语义分割模型的应用场景,以及空洞卷积的介绍

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下计算机视觉的应用25-关于Deeplab系列语义分割模型的应用场景&#xff0c;以及空洞卷积的介绍。Deeplab是Google研发的一系列深度学习模型&#xff0c;主要用于图像语义分割任务&#xff0c;其在众多应用场景中展现出…

56、FreeRTOS/GPIO与定时器相关学习20240329

一、代码实现控制开发板上的指示灯闪烁。 /* USER CODE BEGIN 0 */ //利用定时器机制 定时器溢出时对应的回调函数实现如下 //本次实现控制PB0&#xff0c;PB1两个灯 int flag1 0,flag2 0;//使用一个标记执行以下代码 会造成一个灯常亮 另一个常灭 void HAL_TIM_PeriodElaps…

JavaSE day15 笔记

第十五天课堂笔记 数组 可变长参数★★★ 方法 : 返回值类型 方法名(参数类型 参数名 , 参数类型 … 可变长参数名){}方法体 : 变长参数 相当于一个数组一个数组最多只能有一个可变长参数, 并放到列表的最后parameter : 方法参数 数组相关算法★★ 冒泡排序 由小到大: 从前…

【threejs】较大物体或shape的贴图较小问题处理方法

问题 有的场景内相对体型差距过大的物体&#xff08;如山地 海洋等&#xff09;由于尺寸问题&#xff0c;加载贴图过于小&#xff0c;同时shader也无法完全展示&#xff0c;如图 我们可以获取物体的uv&#xff0c;进行缩放使得贴图可以完全展开 如果uv是乱的 可以用xyz坐标最…