2020 看雪SDC议题回顾 | 高通移动基带系统内部揭密

发布者:Editor
发布于:2020-11-04 18:24

移动基带系统作为连接世界的桥梁,是万物互联的重要基础设施,其建设也日益成为5G时代各国竞相争取的科技高地。


而高通作为全球4G/5G端移动通信设备最大的芯片和方案供应商、行业标准制定者,一直是业界的重点研究对象,其安全性和可靠性也成为我们关注的重要问题。


在5G领跑新基建的当下,有必要深入了解基带系统的建设,挖掘其中潜藏的安全隐患。


下面就让我们来回顾看雪2020第四届安全开发者峰会上《高通移动基带系统内部揭密》的精彩内容。



演讲嘉宾





谢君 ,阿里安全IoT安全研究团队Leader,资深安全专家,15年安全领域工作经验。现专注于IoT安全研究与提供解决方案。 

2016年发现小米整个智能硬件生态高危远程漏洞,在XPwn2016展示其漏洞利用并协助修复。同年,发现美的智能生态远程高危漏洞,并协助修复;2015年发现Broadlink整个智能硬件生态高危远程利用漏洞,在GeekPwn2015展示其漏洞利用;2014年发现美国奔驰高危远程漏洞,并控制超过50辆奔驰汽车。此前并发现过惠普,富士施乐打印机远程漏洞和微软高危漏洞;2011年发现迅雷网络多个高危漏洞,并且验证利用迅雷网络发起大规模DDOS攻击。



演讲内容



以下为速记全文:

大家好,我是谢君,很高兴有这样一个机会和大家一起探讨一下关于移动基带安全相关的一些议题。自我介绍一下,我叫谢君,来自于阿里安全,一直在安全工业领域持续了15年的安全研究工作,现在主要专注于loT领域的安全以及基础设施相关的一些安全研究。


今天的议题主要是介绍高通移动基带的一些技术。我大概去年9月份的时候有写过一篇关于高通移动基带基于ARM架构的一篇分析文章,那篇文章是基于高通的MDM6200基带芯片实现的一个系统的技术,这个芯片2012年的时候在苹果iphone4上曾用于基带通讯。


那今天我讲的基带芯片主要是基于高通最新的hexagon硬件架构体系上面来做一些介绍。我会主要介绍一下高通硬件架构平台的一些信息以及它的基带操作系统,QuRTOS的一些特性以及它的一些实现过程,还有它系统内部一些比较有意思的东西。



一.基带背景介绍


什么是基带呢?它是属于我们移动应用的一个基础设施。基带通讯对于普通用户或者说大众来讲是接触不到的,没有交互的。它属于一个移动处理器的子系统,主要负责我们无线通讯的调试、解调以及不同移动通信技术的切换还有处理。


高通的SoC系统是在一个高通自己设计的统一的硬件架构平台上的,下面运行的子系统是用他们自己设计的叫QuRTOS的系统来运行的,它是有独立的一个内存和独立的固件来运行独立的系统的。子系统和主系统之间通讯是基于内存共享和主系统通讯的方式来完成数据交换过程的。



从现阶段我们市面上的基带芯片的份额分布和厂商的一些分布来看,整个市场上超过60%的份额都是被高通所占有的。其实,我们使用的手机里面很多基带芯片都是高通提供的,比如说苹果手机,6S使用的是高通基带MDM9635、苹果10使用的MDM9655系列,并且谷歌手机、小米、三星、OPPO、VIVO、华为、中兴都有使用高通的芯片。


在数字通信领域、数字模组领域,还有一些第三方的厂商用高通芯片来实现通信模组,主要应用于物联网领域和车联网领域。其他应用得比较多的就是华为的海思以及华为巴龙基带芯片。而英特尔也有自己的基带芯片,只不过现在已经卖给了苹果。三星的话也有自己设计的基带系统,是基于ARM架构的。


这几个厂商当中我唯一没有分析过的是联发科。通过整个固件分析能判断这几家厂商当中架构做得最烂的应该是三星,做得最好的是高通。华为最新的基带固件暂时没法分析,因为太封闭了,固件都拿不到,可能需要一些特殊的手段才行。




二.高通移动基带内部架构


接下来我来讲一下高通基带的演进过程以及发展过程。高通的移动基带最早用的是ARM的架构,而且除了高通之外,其他的厂商都是用ARM架构。到后来由于高通的野心以及其战略目的,高通设计了属于自己的硬件架构的芯片,而且这是一种DSP的架构芯片,为什么会使用这种架构呢?后续我会介绍。


它的操作系统在演变进程中最早是叫REX,后来代号经过不断迭代,现在它的SoC有两种类型,主要是通过应用场景的不同来区分。


其中,应用最多的就是MSM,它主要是应用于手机的一个很大的SoC,里面包含了我们的手机、应用处理器,就相当于是我们在高通平台上运行的安卓系统,现在最新支持到64位的ARM。另外一个类型就是MDM,主要是用于数据通讯,比如说我们使用的一些4G、Wifi、车联网、物联网相关的一些模组,都是基于MDM的平台来设计的,也就是我之前一张功能图里面介绍的MDM9607就属于其中的一个产品。


那高通的hexagon DSP有什么特点呢?它是VLIW(非常长的指令流水),单指令多数据流。它的指令跟我们之前所遇到的ARM和x86指令不一样的地方在于,它有一个指令Packet的概念,一个指令Packet里面可以并行执行高达4条指令流的操作,就是每一调CPU的时钟,就可以允许你同时执行4条指令,这叫做一个指令Packet。


它拥有丰富的浮点计算单元和向量计算单元以及硬件多线程特性,因此其应用场景非常广泛,很适合用于神经网络计算,例如AI计算以及一些信号调制与解调的计算,IQ的样本处理,以及音频、图像处理、计算机视觉等其他相关的一些计算处理。


所以,可以预见到也许在不远的未来,高通的DSP平台就会把这些计算统一起来。


我们知道应用高通平台比较多的是小米手机,它支持人脸识别、指纹识别、语音识别、4G以及WIFI,这些功能都可以通过一个DSP平台去满足所有相关能力实现。


接下来就是关于DSP指令架构的信息。它跟我们常见的普通的ARM、X86指令一样,有一些寄存器信息,但它只提供一些应用处理的寄存信息,对于系统编程的寄存器的定义是没有的。所以他的手册上是没有这种公开的SDK信息的,这种系统编程信息只会给一些合作厂商和授权的厂商。



所以,它这块做得很封闭,我们没办法直接从它的系统手册去看有哪些系统寄存器的功能,比如说你这个DSP需要去开启MMU内存单元的功能的时候,哪个bit的设置有这个功能。


刚刚我们有说到它的指令Packet可以高达4条,但是这4条指令是分了四个不同的Slot。也就是说它所处的位置是有特定的指令类型的,不是你想放哪里就放哪里,还有因为这些指令操作有不同的Slot,所以也有一些约束条件。比如说这四条指令里面不能同时使用一个寄存器即做读又做写的操作,编译器是不允许的。



既然我们了解了指令架构,有没有什么好的办法去更好地研究、学习它呢?现在为止,基本上高通官方可供下载LLVM的一个供应SDK既可以编译你的应用程序,也可以去做反汇编的操作,开源的反汇编框架就是在github上面展示的。展示的这两个插件是有BUG的,有的时候解析不正确,对一些指令的解析是不完整的。



三.高通基带系统概要


接下来讲高通的基带系统它在整个应用的SoC当中所扮演的角色,以及它自己的一些特性。首先,基带系统它是底层的kernel,是用C和汇编来写的,上层的业务逻辑是通过C和C++来实现。它和主系统之中,比如说安卓系统进行信息交互是通过共享内存的方式,在AP端为了方便去调试或诊断你的基带系统,它会提供一个非常方便的诊断接口DIAG,基带应用系统可以通过QDI(高通设备接口)接口来进行系统调用管理设备驱动。


接下来我就介绍一下高通基带的微内核架构,跟我们正常大部分使用的Windows系统和Liunx系统有什么不一样的地方。


这种微内核架构,它是区分内核空间和应用空间的,但是内核空间是非常精简的功能应用,它负责做的事情只是一些任务调度、IPC通讯以及内存管理、虚拟内存和物理内存的映射关系,然而它跟硬件IO相关以及跟驱动相关的一些功能实现,都是在应用层以任务的形式来运行的。这里面跟我们的Liunx宏内核系统有很大的不同之处在于,如果你的驱动写出来有问题、有漏洞,内核可能就崩掉了,但如果是微内核的话,实现的驱动出现了故障内核也不会崩溃,只是你的任务崩溃。



在高通基带的用户态上面有一个抽象的设备管理层,主要是为了去管理你设备驱动,例如各种定时器中断以及文件系统,都是在应用层封装调用。用户态进入到内核态的方式,可以通过Trap这种指令进入到内核态。


为什么它会有两个Trap呢?这两个都可以进入内核,Trap0主要是进入到内核态处理原生操作系统的任务调度,IPC通信,虚拟内存与物理内存映射相关操作,而Trap1主要是为了实现QDI接口注册的相关的功能逻辑,这样做的好处在于提升了系统的移植性,比如更新操作系统的内核功能只需要关注Trap0对应的内核操作,而如果硬件外设有功能更新的话,那开发者就只需要更新Trap1对应的功能实现了。



四.高通基带存储器管理


现在高通的5G基带SDX55的模块中,对内存的管理和物理内存的分割更细腻了,可以定义不同的业务逻辑,让你的业务使用不同的堆。这个特性有点像我们现代经典操作系统里面隔离堆的技术,也就是说特定的业务只允许使用特定的堆来进行分配或者是回收。



在基带内存管理当中还有一个非常重要的特性就是MMU这种机制。高通基带系统和我们现在使用的大部分经典的现代操作系统不一样的是,在它慢慢演进过程中它开始大量使用TLB直接操作,因为Hexagon DSP支持TLB读写指令,直接通过TLB的方式Cache物理内存和虚拟内存的映射关系。也就是说CPU在执行过程中可以快速地去找到它的代码进行执行,大大节省时间。如果使用页表结构的话,因为你的粒度最大只有4KB,但是直接使用TLB设置支持到16MB大小的页面映射。



在早期的MDM的基带芯片中,支持传统的二级页表的翻译模式,也就是说CPU首先查TLB里面,如果没有缓存的话直接产生一个TLB missw/x/r的异常,然后去查页表,再做地址翻译。


到了最新的SDX55的5G基带中,直接引入了一个Virtual TLB的方式,来做一个虚拟内存和物理内存的翻译操作。这样做的好处主要是为了节省物理内存,因为用TLB的方式能快速、灵活地翻译内存的映射关系。


而在基带的业务逻辑层,它的做法跟我们传统的固件加载到内存当中执行不太一样的点在于,不是所有的业务逻辑都初始化,只有你需要使用某种业务逻辑的时候,才会把相应的代码铺设到内存里面进行执行。


比如说我们的手机还没有连入网络的时候,所有的业务逻辑比如说LTE都还没有准备好,还有3G、2G的网络协议也都没有准备好,但它有一部分的代码在内存当中是固定部署好的。当它要执行LTE相关业务,执行相关操作的时候,代码就会执行到一些虚拟地址,比如说要执行到0xD00xxxxx开始的地方。


但是,发现这块地址没有被映射的时候就会产生一个pagefault异常。内核异常处理中断会判断这个pagefault的地址是在哪儿,要找到pagefault地址相应的地址所对应的压缩代码块,解压出来后再铺设到物理内存当中进行映射,再去执行相应的代码。这是高通自己定义的一种名为Q6zip的压缩方式。


它主要的目的,第一是为了节省物理内存,第二是降低功耗。这个压缩算法是一种非常高效的解压算法,因为编译器生成的指令是有一些固定的特征和特性的,所以它会自己建立一套字典,通过查字典的方式快速做数据的解压,之后再去执行相应的代码逻辑。



这个就是CPU在执行过程中一个处理的流程。可以看到,静态映射的一些代码在执行过程中,执行到了一些未被映射到的代码地址空间里的时候,会进行TLB查表,发现TLB里面没有查到以后,会产生一个TLB Miss的Exception,TLB就会解压相应代码,然后映射到内存再去执行。



五.高通基带设备管理机制


接下来我们就讲一下高通设备管理的架构体系。刚才我也有提到高通有一个设备虚拟层的机制,它专门是管理和描述所有高通和高通基带设备相关的一些信息的,比如说它的IO映射信息以及它的寄存器信息和初始化信息,有两种方式。



一种就是字符设备,通过字符串的方式来描述你这个设备是属于什么样的设备。另外一种就是通过ID的方式来标识。它属于某种特定的物理设备的话,我们物理外设常用的串口、中断控制器以及处理器之间通讯的一些控制器,都是属于在这个DAL中进行描述的。


里面还有一些通用属性就是刚才提到的设备ID还有一些映射信息、设备名称以及这个设备的中断注册等等,以及如何初始化。它的一些设备驱动会有一些相应的API对你这个设备的初始化、管理、开关、设备信息之类的做一些读取。


另外,在API层,就是说在使用这些设备的时候,有一些API专门负责解析你这个设备抽象层的设备信息。而高通的这套设备管理机制其实适用于所有的高通子系统以及其他的层面。


这里我写了一个脚本,提取了MDM9607里面的一些外设信息和设备ID的对应关系。




六. 高通基带任务管理机制


说完设备管理,接下来我们来了解一下高通的任务管理机制。其实高通没有太多进程的概念,大部分都是一个任务的概念或者可以理解为一个线程的概念。


高通定义线程的任务定义了不同的类型以及一些不同的优先级,它会把这些任务分为不同的组,比如说第一种任务只运行一次就结束了。第二种就是这个任务会动态分配内存去作为你的一个函数运行的堆栈空间。第四种就是一个系统管理的任务,比如说你要初始化你的外设驱动的时候,是通过这个任务来进行管理和初始化的。第六种就是一种共享设备、共享驱动信息的任务类型,比如说两个不同的处理器在通讯的时候,双方都需要初始化相应的中断管理例程以及共享内存相关的描述信息,我们如何去进行数据交换的操作逻辑。第七种也是一种静态定义的栈地址和栈空间的普通的任务,而且还支持Posix线程的定义方式。


最后还有一种任务的依赖性。比如说这次任务运行的是A,你要运行这个任务A之前你必须得先运行任务B,这叫做任务依赖。这个任务管理在内核态是怎么存储任务信息呢?内核会分配内存来保存每个任务的执行上下文信息,每创建一个任务的时候,都会把上下文信息存在这个数据结构里面,用于调度不同的任务的时候保留你任务的一些现场信息,并且在内核态中也会保存着你这个任务所能访问的一些资源的权限。


至于任务调度过程,刚才我们有提到高通基带运行的一些任务。任务初始化完后大部分是处于阻塞的状态,也就是等待消息的一个状态,用不同的消息来处理不同的业务逻辑。还有一个特性就是说,为了保证你这个任务它不是一个僵尸的进程,不是一个僵尸的任务,或者说长时间没有响应就可能就会认为你是个僵尸任务,里面会有一个看门狗喂狗的机制专门来保证你的任务一段时间之后是否存活,通过这种机制来判断任务运行的健康状态。


任务的类型分为正常的业务处理逻辑,另外一种就是中断服务接管的任务,传统情况下我们使用单片机。如果大家对嵌入式系统了解的话,单片机里面使用的中断是通过直接硬件Dispatch到中断向量表中,然后直接进行处理,处理完了再返回。


因为高通是多任务的嵌入式系统,当中断过来的时候,此时运行的任务可能并不是中断接管任务,内核会保存当前任务的执行上下文和寄存信息,硬件会dispatch到相应的中断向量表的处理例程中去,该例程会判断中断号信息以及该中断号对应的中断接管服务的任务信息,然后把这个任务加入到任务调度池中去,最后执行这个中断接管服务任务,完成中断响应。


另外,IPC在高通基带处理当中是一种非常重要的通讯机制。因为,3GPP定义的协议栈里面,会有很多不同层次以及不同原语的交互以及请求之类的,高通就自己定义了一套管理不同层次、不同对象的标识技术,通过UMID的方式去标识。这个UMID是有一些对应关系的,比如说它定义的UMID是32位,第一个最高的一个字节定义的是你使用这个消息使用的一个网络技术的逻辑。比如说LTE,4节LTE它的头部就是4,4来定义LTE这个技术,其他的用来定义WCDMA、GSM、TDSCDMA、CDMA2000等等网络接入技术。


那中间的实体是来定义你这个协议栈当中所处的哪个层次和操作呢?比如说你这是一个配置信息或者是一个取消等等的操作。


最后就是一个原语操作,这种原语操作是3GPP当中定义好的不同层次间的进行通讯的几种方式。我这里提取出来在4G LTE协议栈里面不同的消息实体,3GPP协议栈是定义了三层,对于L1、L2、L3,高通在实现过程中会有更丰富细腻度的消息通讯机制,来管理不同层次的一些操作逻辑。




七.高通基带数据分组和网络模型


接下来我会简单介绍一下关于高通基带的数据分组聚合和网络模型。我们刚刚有提到高通的3GPP里面定义的不同层次的一些模型,在高通定义的3GPP的PDCP上层,它会自己去定义不同的逻辑层,来做一些网络数据的传输和通道的选择。


再往上就是封装的IPV4和IPV6的一些协议栈,再顶层就是一些抽象封装,再往上就是一些业务逻辑了。比如说我们常用的VOLTE,这种IMS的业务逻辑都是在顶层的业务逻辑上进行封装,往下一直到物理层传输出去。




八.高通基带系统攻击面


我们了解了高通基带的一些基本信息之后,再来看一下它有哪些攻击路径。因为,基带它不是一个独立存在的系统,它是跟AP一起存在的,所以它的攻击路径可以从本地的AP打到基带里面去,比如说安卓系统当中可以打到基带当中,AP系统也可以通过基带打到核心网,从核心网到远端的基带。然后也可以从OTA层进行攻击,比如说OTA就是伪基站,从伪基站信令层打到基带,从信令层到基带然后再到AP系统。以上都是一些可能的攻击路径。



那它的攻击接口有哪些呢?本地有一些诊断接口,以及QMI高通的消息接口,又比如和AP之间的通讯,远端的语音通信和数据,还有就是和基带和基站之间的OTA的信令交互,还有内置的一些GPS和定位系统的解码相关的一些攻击面,另外就是其他的一些边缘计算相关的东西。




九.基带模糊测试工具包


那我们对高通基带有一些了解之后,是否可以打造一个通过高通基带来fuzzing测试挖掘对端基站以及核心网的测试工具呢?


比如说可以在信令层要达到一个fuzzing测试操作,在信令承载层SRB可以满足RRC层次信令漏洞挖掘,在应用层、数据承载层可以在NAS、VoLTE、语音通话和边缘计算相关,做到这些相关的漏洞挖掘,还需要它的成本足够低并且合法。所以我们不建议使用SDR软件去做这种测试。


最后就是它的尺寸要足够小。这里我通过改造高通的基带系统的方式,实现了一个基于基带的fuzzing工具,能够满足网络探测的一些功能,比如说能够探测核心网,能够和对端通讯,以及在协议层次,3GPP定义的IP网络协议层次的fuzzing,能够直接fuzzing基站信令交互。


基于这个模块,最终我发现了几个与运营商服务相关的漏洞:第一,只需要知道对方的手机号,我就可以知道你这个手机使用的什么样的版本、版本信息以及你使用的什么样的手机;第二,可以绕过运营商进行免费的点对点通讯,也可以绕过运营商进行加密通讯。第三,4g信息泄露,可以把发给别人的手机认证信息以及短信发到我的手机上。


接下来我要介绍一个基带系统,从基带系统打到AP系统的一个非常有意思的漏洞,它是属于一个共享系统里面的内存任意地址读写的漏洞类型。它的攻击链路就是从基带打到你的AP里面,可以做到任意地址的读写,它的原理是什么样的呢?


我们看一下,普通的在SoC的共享系统当中,不同的系统之间,子系统和主系统之间的通讯,是通过内存共享的方式来进行数据交互的。而且,这个也是在大家一开始都已经协定好的,因为大家属于不同的系统,所以有不同的MMU体系,不同的MMU体系就有不同的内存翻译机制。


如果说我在基带里面能够篡改MMU的映射关系的话,那我有没有可能直接通过构造恶意的MMU映射关系,直接把别的系统当中的物理内存,映射到我的基带空间当中进行读写呢?这个时候其他主系统是没办法干预的。我在高通的MDM9607模组里面成功实现,可能在手机里面不一定能够成功,可能跟实现有关系。后来结合研究发现,高通有非常强悍的三个访问控制的硬件机制VMIDMT,XPU以及SMMU机制。


第一个VMIDMT是属于系统来定义你的子系统所使用的一个资源信息的一个初始器。


第二个XPU机制是在运行过程中,你要访问相应资源的时候,高通的XPU外部的保护单元会去检查你这个子系统当中使用的这些资源是否是合法且合理的,会做一个资源访问的隔离。


第三个保护机制就是SMMU,如果是研究ARM最新Cortex-A系列的小伙伴应该都清楚,SMMU是一个IOMMU用于去做物理内存的边界隔离的机制,通过hypervisor的方式限定你这个系统的物理内存地址的访问空间。


类似这种共享内存系统间攻击的手段,之前我看到360的研究人员龚广实现了类似的方式,实现了AP系统的地址空间可写。他通过修改GPU的页表里面MMU的物理内存映射,构造一个恶意的GPU的物理访问空间,把AP系统中的地址映射到GPU的地址空间里面,对AP系统的物理内存的读写操作,从而完成对它的利用。


我觉得这应该是作为一个共享内存机制当中的,不同系统之间通讯的一个通病,如果系统间内存隔离做得不妥当就可能造成这种跨系统物理内存读写的安全问题。我觉得这块的研究在未来在漏洞利用对抗上面应该会有一个非常大的启发。




本届峰会议题回顾


2020看雪SDC议题回顾 | 逃逸IE浏览器沙箱:在野0Day漏洞利用复现

2020 看雪SDC议题回顾 | LightSpy:Mobile间谍软件的狩猎和剖析

2020 看雪SDC议题回顾 | DexVmp最新进化:流式编码

2020 看雪SDC议题回顾 | Android WebView安全攻防指南2020

2020 看雪SDC议题回顾 | 生物探针技术研究与应用

2020 看雪SDC议题回顾 | 世界知名工控厂商密码保护机制突破之旅

2020 看雪SDC议题回顾 | 敲开芯片内存保护的最后一扇“门”

2020 看雪SDC议题回顾 | 基于量子逻辑门的代码虚拟(vmp)保护方案

2020 看雪SDC议题回顾 | 麒麟框架:现代化的逆向分析体验

……



注意:关注看雪学院公众号(ikanxue)回复“SDC”,即可获得本次峰会演讲ppt!

其他议题演讲PPT,经讲师同意后会陆续放出,请大家持续关注看雪论坛及看雪学院公众号!



- End -




声明:该文观点仅代表作者本人,转载请注明来自看雪