Nintendo 3DS BootROM漏洞分析

gewenbin
gewenbin
gewenbin
188
文章
15
评论
2021年3月16日22:18:26 评论 1,328

1. 概述

本篇文档对任天堂的3DS BootROM漏洞做一个介绍,国外黑客derrek(这名字让我想起了神秘海域的主角==)通过dump并逆向芯片内的BootROM,发现了3DS在解密验证Firmware过程中的一个漏洞。通过该漏洞可以让用户自己签名的Firmware被BootROM认为是合法的,从而引导用户自己的镜像,达到破解运行自制系统和软件的目的。Derrek原始的演讲视频地址为https://www.bilibili.com/video/BV1Yt4y1v7p3/,视频中简单的介绍了dump芯片内BootROM的原理,并对BootROM漏洞做了一个大致的分析,除此之外并没有透露更多的信息。

Nintendo 3DS BootROM漏洞分析

图 1-1 Nintendo 3DS

国外另一组黑客基于derrek演讲分享的内容,通过另一种方法找到了利用漏洞的方法,并写了较为详细的文档,文档ppt形式地址是https://sciresm.github.io/33-and-a-half-c3/,pdf格式的论文地址为https://arxiv.org/pdf/1802.00359.pdf

Nintendo 3DS BootROM漏洞分析

图 1‑2  3DS漏洞攻击分析

2. 硬件架构

3DS的SOC是任天堂自己设计的,采用的是大小核的设计方式,包含1个ARM9核和2个ARM11核,后来发售的升级版New3DS采用了4核ARM11,如图 2‑1所示。关于3DS更详细的硬件信息请参见https://www.3dbrew.org/wiki/Main_Page

Nintendo 3DS BootROM漏洞分析

图 2‑1  3DS硬件架构

ARM9核主要用于访问Nandflash和SD卡存储设备,并对访问的镜像做加解密验证。ARM11核可以访问LCD、GPU等外设,执行一些复杂的功能,ARM9和ARM11通过PXI硬件机制实现核间数据传输。

ARM9、ARM11都分别有自己的BootROM,本篇文档分析的是ARM9的BootROM。

3. 加解密简介

由于发现的漏洞是3DS在解密验证Firmware过程中的一个漏洞,所以有必要提前对BootROM中使用到的加解密知识做一个基本的介绍。

3.1 SHA256哈希散列

SHA256是SHA2下细分出来的一种安全散列算法。SHA2(Secure Hash Algorithm 2)是一种密码散列函数算法标准,对于任意长度的数据,经过SHA2算法都会产生一个固定长度的哈希值,比如SHA256会产生256bit(32字节)的长度,SHA512会产生512Bit(64字节)的长度。

3DS中Firmware就是使用的SHA256进行哈希散列。

3.2 ASN.1编码

ASN.1标准用于对要传输的数据进行编码,并且规定了几种不同的编码规则用于不同场景下数据传输,这里我们只介绍基本编码规则BER(Basic Encoding Rules)。

BER编码格式是TLV三元组,即Type、Length、Value。Type用于描述编码数据的类型,Length表示数据的总长度,Value表示实际要传输的数据具体内容,如图 3‑1所示。

Nintendo 3DS BootROM漏洞分析

图 3‑1  BER编码格式

其中Value还可以是其他TLV或者TLV组合,如图 3‑2所示。

Nintendo 3DS BootROM漏洞分析

图 3‑2  TLV组合嵌套

Length字段根据数据的性质还分为定长和不定长,定长还分为短定长和长定长两种情况。我们这里只考虑短定长情况,也就是数据的长度在0和127之间,3DS的漏洞就是BootROM对于这个长度字段处理不严谨导致的

3.3 RSA2048加解密
3.3.1 公钥和私钥

RSA加密是一种非对称加密。可以在不直接传递密钥的情况下,完成解密。这能够确保信息的安全性,避免了直接传递密钥所造成的被破解的风险。是由一对密钥来进行加解密的过程,分别称为公钥和私钥。两者之间有数学相关,该加密算法的原理就是对一极大整数做因数分解的困难性来保证安全性。通常个人保存私钥,公钥是公开的(可能同时多人持有)。
根据密钥的长度RSA可以分为RSA1024、RSA2048等等,目前常用的RSA密钥都在1024bit以上以保证安全性。3DS中使用的是RSA2048进行加解密。

3.3.2 3DS中的加密和解密

3DS中ARM9的BootROM中含有RSA公钥,其对应的私钥只有任天堂才有。任天堂发布的Firmware都使用私钥进行签名加密,然后被ARM9用公钥进行解密校验,只有校验通过了,Firmware才会被进一步的处理。

3.3.3 PKCS#1标准

PKCS(Public Key Cryptography Standards) 公钥加密标准定义了RSA公开密钥算法加密和签名机制。其中有个规定就是对于明文位数不足RSA密钥长度的需要进行数据填充以方便RSA运算,比如RSA2048要求EB(Encryption Block)的长度为2048bit,也就是256字节,当要加密的明文长度比这小时,就需要在明文前按一定的规则填充数据以达到256字节要求,具体的规则下面简单介绍下。
PKCS#1 v1.5标准中,数据块表示为EB=0x00+BT+PS+0x00+D:

  • EB:填充数据后的数据块,对于RSA2048而言长度为256字节。
  • 0x00:第一个字节固定为0x00。
  • BT:有三个值,分别是0、1、2,占一个字节长度。用来标明EB数据块填充的类型。
  • PS:填充的数据,如果BT为0,这些填充字节全部为0;如果BT为1,这些填充字节全部为0xff;如果BT为2,这些填充字节随机产生,但是不能为0。
  • 0x00:用来表示填充数据结束标志。
  • D:实际要加密的明文数据。

3DS的BootROM支持解析填充类型为1和2这两种情况下的数据,且漏洞利用的就是当填充类型为2时填充数据是随机生成的这一特性。配合ASN.1数据解码时长度字段处理的漏洞,就可以伪造一个EB数据块,经过BootROM的解密处理后可以通过校验,从而认为Firmware是合法签名的,从而被BootROM进行处理。具体的原理请见下一章节。

4. BootROM漏洞

4.1 Nintendo 3DS操作系统源码泄露

在2020年5月底,3DS操作系统的源码被黑客泄露到了互联网上,当时国内外的媒体都对这一事件进行了报道,如图 4-1所示。

Nintendo 3DS BootROM漏洞分析

图 4‑1  3DS操作系统源码泄露事件

通过科学上网的方式,我也在外网的某个角落里找到了这份泄露的源码,如图 4-2所示。

Nintendo 3DS BootROM漏洞分析

图 4-2 3DS操作系统泄露的源码

泄露的源码包含的东西还是比较全的,包含了ARM9和ARM11各自BootROM的源码、3DS操作系统Horizon内核源码和系统相关组件等源码。本次的漏洞我们就按照这份泄露的源码来进行分析。

4.2 BootROM处理Firmware数据
4.2.1 Firmware数据

Firmware数据主要有两部分组成,数据头部和数据本身。3DS进行加解密的是数据头部和数据整体,如果通过了解密校验才会对数据部分进行处理。

4.2.2 Firmware数据结构定义

我们来看看3DS对Firmware数据结构的定义,如图 4-3所示。

Nintendo 3DS BootROM漏洞分析

图 4-3 Firmware数据头部

  • MediaSign:Firmware加密后的数据,因为用的RSA2048加密,所以共256字节。
  • MediaHeaderCore:这个就是Firmware头部数据结构。
  • NandData和CardData:这个就是Firmware真正的数据部分。BootROM会对头部加数据本身重新进行SHA256计算,以和解密后得到的SHA256哈希值进行校验。
4.2.3 Firmware加密流程
  • 首先对Firmware使用SHA256计算得到32字节的哈希值。
  • 对SHA256哈希值使用1进行编码,这个也可以在源码里找到对应的函数,如图 4‑4所示。其中RSA_SHA256_SIGN_LENGTH为51,也就是经过ASN.1编码后的总数据长度为51字节。从源码中还可以看出编码后的数据共有3个大的TLV,第二个TLV又由2个TLV组合而成。最后一个TLV就是对SHA256哈希值的编码,类型为ASN1_TAG_OCTET_STREAM,长度为SHA256_LEN(32)。

Nintendo 3DS BootROM漏洞分析

图 4‑4  进行ASN.1编码

  • 对1编码后的51字节数据按照PKCS#1 v1.5标准扩充为256字节EB数据块,然后使用RSA2048算法进行加密得到同样256字节的加密数据。
4.2.4 Firmware解密流程

解密由mediaCheckHeader这个函数完成,首先进行了图 4‑5所示的操作。

Nintendo 3DS BootROM漏洞分析

图 4‑5  解密过程1

  • 分别定义两个缓冲区md[32]和buffer[256]用来存放重新计算的SHA256哈希值和解密后的PKCS#1数据。注意这里的缓冲区是在栈上分配的,由于ARM架构栈是递减形式的,所以md的地址比buffer地址值要大,如图 4‑6所示。

Nintendo 3DS BootROM漏洞分析

图 4‑6  栈中数据分布

  • 接着对头部中的魔数进行检查,以确保这是3DS可以处理的Firmware。
  • 接着设置硬件准备进行RSA2048解密,3DS中的加解密是通过硬件加速完成的。
  • 然后对Firmware重新进行SHA256计算得到哈希值。

然后接下来就是具体的解密过程了,如图 4‑7所示。

Nintendo 3DS BootROM漏洞分析

图 4‑7  解密过程2

  • 首先将RSA解密后的数据保存在buffer缓冲区里。
  • 然后对解密后的数据进行PKCS#1解析,以找到1编码数据在buffer中的位置。
  • 找到编码数据后,再对其进行1解析,以找到最终的SHA256哈希值所在的位置。
  • 最后md中保存的是重新计算的SHA256哈希值,hash指针指向的是解密后SHA256哈希值所在位置,将这两个哈希值比较,如果完全一致则表示校验成功。

以上就是Firmware解密校验的大致流程。

4.2.5 PKCS1数据解析

我们首先来分析下解密后的数据进行PKCS#1解析的大致流程,如图 4‑8所示。

Nintendo 3DS BootROM漏洞分析

图 4‑8  PKCS#1解析

  • 首先检查第一个字节是否为0,因为PKCS#1中规定第一个字节必须是0。
  • 接着检查填充类型是否为1或者2,3DS只支持处理这两种类型的填充情况。
  • 随后循环跳过填充的数据,以找到填充结束标志0x0。从中我们还可以看出如果填充类型为1还会检查每个填充的数据是否是规定中的0xff,如果填充类型为2则直接跳过填充数据。
  • 最后跳过结束标志0x0,然后返回的地址就是1编码后的数据所在的位置了。
4.2.6 ASN.1 BER数据解析

我们接着分析下ASN.1数据的解析过程,如图 4‑9所示。

Nintendo 3DS BootROM漏洞分析

图 4‑9  ASN.1数据解析

  • 解析1每一个TLV数据都是通过rsaAnalyzeBER这个函数来实现的,这个函数实现稍后会作分析。
  • 首先解析第一个TLV数据并检查编码类型。
  • 然后解析第二个TLV数据并检查数据类型。
  • 通过加密章节的描述我们知道第二个TLV中还包含了2个子TLV数据,但是这里我们不关心,直接简单的加上数据长度跳过这段数据区,这就是个隐患
  • 最后解析第三个TLV并检查编码类型。
  • 三个TLV都解析完毕后,我们也就得到了最后一个TLV中数据内容的地址,也就是解密后的SHA256哈希值所在的位置。

每一个TLV数据都是通过rsaAnalyzeBER这个函数来解析的,我们来简单的分析下这个函数,如图 4‑10所示。

Nintendo 3DS BootROM漏洞分析

图 4‑10  TLV解析

  • 首先获取TLV数据编码类型和数据的长度。
  • 然后根据数据长度再分别处理长定长数据和短定长数据。
  • 随后返回编码类型和数据长度值。
  • 最后返回TLV数据中数据内容所在的位置以进一步处理。
4.2.7 漏洞

从图 4‑6中我们可以知道计算出的SHA256哈希值在栈中的地址是在buffer之后的,从4.2.6章节我们又知道在解析ASN.1第二个TLV数据时,没有对数据长度做检查,而是直接用当前指针加上这个长度值以直接跳到第三个TLV数据进行解析,而第三次TLV数据解析后指针其实就是加上2而已,随后新指针值就被认为是解密后的SHA256哈希值所在的地址,同样没有对指针所指向的地址值做检查

那么我们就可以构造一个特殊的256字节的PKCS数据,让其经过ASN.1解析后,指针正好越出buffer缓冲区指向md缓冲区,如图 4‑11所示。

Nintendo 3DS BootROM漏洞分析

图 4‑11  构造特殊的虚假的PKCS#1数据

这样的话,在mediaCheckHeader函数最后会将md和md自身做比较,当然永远都会成立,通过校验啦!

4.2.8 寻找特殊的PKCS数据

现在我们知道了漏洞的原理,那么现在的问题是如何去寻找这样一个满足要求的特殊的PKCS数据。之前研究漏洞的黑客们给出来的解决方法就是利用Brute Force算法进行暴力破解。。。。。。Brute Force算法其实就是通过穷举法来寻找满足要求的数据,根据https://sciresm.github.io/33-and-a-half-c3/math.html黑客们优化后算法,使用几块GTX1080显卡加上Amazon AWS云平台硬件花了大概9天时间终于找到了这样的PKCS数据,如图 4‑12所示。

Nintendo 3DS BootROM漏洞分析

图 4‑12  特殊的PKCS数据

5. 总结

通过前面的分析可知3DS这个漏洞是比较严重的,之前分析过的Switch和iPhone的漏洞都没有攻破镜像签名这一环节,而3DS的这个漏洞则可以让用户任意镜像只要使用图 4‑12中的签名都会被设备认为是合法的镜像,直接被设备引导使用,从根源上达到了完美破解的目的,这也是目前3DS中主流的B9破解所使用的漏洞原理。

gewenbin
  • 本文由 发表于 2021年3月16日22:18:26
  • 转载请务必保留本文链接:http://www.databusworld.cn/9963.html
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: