OTP相关信息

OTP是一个在0x10012000位置长度为0x100字节的区域,其内容似乎是一些随机数。据推测,设备唯一号(console unique keys)源自于这片区域,虽然到目前为止我们还不确切的知道它是如何计算出来的。这片区域有可能是被启动rom加密的设备唯一数据(console unique data)的存储地,但是我们并不知道它是如何完成的,除非有人导出了整个受保护的启动rom。在有人成功导出了受保护的启动rom之前,一切都是未知的。

在3.0.0-X版本之前,0x10012000-区域(OTP)是不被保护的,可以通过一些有了必要权限(arm9代码执行权限)的攻击程序导出。

在3.0.0-X之后,任天堂使用CFG_SYSPROT9寄存器对这片区域加锁,同时也锁住了启动引导器(bootloader),并且在我们通过漏洞获得代码执行权限之前就被设置好了。这个寄存器只能被设置一次,并且在关机之前不能被关掉,因此不使用3.0.0-X以下版本,是不可能导出整个OTP数据的。

但是,还是有一个办法可以在9.6.0-X版本上导出OTP的哈希值(Hash)。因为Kernel9Loader在使用SHA_HASH寄存器后并不会清除该数据,导出的SHA_HASH可以提供从Kernel9Loader递交给Kernel9的OTP哈希数据。此外有一个由来已久的漏洞——由i2c引发的MCU重启不会清除RAM数据,就像我们期望的那样。

这使得一种基于硬件的攻击成为可能。把一些数据写入备份的SysNAND的nand_sector96+0x10的位置并刷入设备。然后用我们的命令让MCU重启,写一个payload(把0x1000A040 - 0x1000A060数据写到sd卡)放在arm9内存的某个地方,将内存填满NOP指令紧接着写一个跳转(JMP)指令指向payload所在位置。然后我们不停地让MCU重启(每次让nand_sector96+0x10的数值加1)直到Kernel9Loader跳转到我们写的payload。

考虑到上述方法的复杂性和需要额外的硬件,我(原作者)决定限制本教程的范围,只针对降级到3.0.0-X以下版本的方法。选择2.1.0-X的原因是因为它是唯一的在3.0.0-X版本以下并且完全支持浏览器漏洞的版本(2.0.0-X也有部分可利用漏洞的浏览器,但是由于其他的原因,并不能完成OTP提取)

这个过程包括将你的CTRNAND刷到2.1.0-4版本。这样的操作由安装一个预处理过的包含2.1.0版本的镜像,拷贝你的机器特有的文件(像是moveable.sedSecureInfo_A),然后修复title数据库的CMACs这几个步骤组成。对于新3DS,CTRNAND的加密方式会被替换并加上老3DS的NCSD文件头,让新3DS可以使用只有老3DS才能用的2.1.0固件。

如需获取教程帮助,请参见常见问题
觉得本教程很有帮助?请支持我的劳动成果,给我打赏