年龄和季节的甲骨文 - 链接电缆漏洞

2021-04-28 11:15:41

我发现了多种漏洞,包括严重的远程CodeExecution(RCE)漏洞,在“塞尔达的”塞尔达:季节的甲骨文“的链接电缆通信模块中为游戏男孩颜色。该漏洞仅通过未能消毒在链路电缆上收到的输入。

年龄的甲骨文,姐妹游戏对季节的甲骨文,也受到了这一恒星的影响,并且据信是可能的远程代码执行。但是,鉴于该软件已经具有未涉及使用链路电缆的未携带的代码执行漏洞,尚未调查漏洞的影响的范围。相比之下,这是季节Oracle中的第一个众所周知的执行漏洞。

在本报告中,我将演示在Ages Oracle Oracle中的先前已知的代码executionexproit如何通过在链路电缆上发送损坏的文件数据来实现Oracleof Seasons中的远程代码执行。我将在第一次打开文件的几秒钟内直接扭曲到季节的季节扭曲验证概念剥削。“链接任何%”类别的eedredrunders发现这是一个令人震惊的开发或欢迎,将他们对季节甲骨文的态度。

塞尔达的传说:年龄和季节的甲骨文是一对视频游戏在2001年发布的游戏男孩颜色。因为它们同时发布,他们是一个独特的“链接”系统,必须用来解锁“真实”的终止。游戏。因为并非所有玩家都有一个GameBoy链接电缆,那么游戏可以通过一系列“密码”来互补。我以前在本普通系统中曾签署过非剥削性;但是,这是链接电缆功能首次审核。

虽然这两个游戏共享相同的代码基础,但令人惊讶的是,在与年龄的同学的同学中,在季节的甲骨文中发现了非常小的错误。 (在此上下文中,“可利用的错误”表示可以使用的错误更快地击败游戏)。唯一已知的可利用错误的票据是Theso称为“公鸡冒险”错误,甚至在欧洲更新中修补了这一点。

相比之下,年龄的甲骨文有许多经常利用的错误,包括铲复制,教学和臭名昭着的Veranwarp。最近,任意代码执行(ACE)已经很容易地通过SpeedRunnersto扭曲直接向信用术而定。

因为在季节中实现远程代码执行首先需要年龄的任意代码,我将首先描述这一点。

最近几个月,已经开发了新的ACE技术,允许一个到几乎任何内存地址的写字字节,这意味着一个人可以通过游戏实现“TotalControl”。鉴于我们唯一的输入设备是GameBoy本身上的按钮(链接电缆未用于此),这不是小小的壮举。概念验证视频如下所示,这种技术用于禁用游戏中的Allcollisions。请注意,日语版本几乎总是在执行ACE时使用,因为用于名称输入的较大字符集ISvery在被执行的代码时有用(但它仍然可能原则上的其他版本)。

使用这种ACE技术的略微修改的版本,以准备链接电缆漏洞利用。下面是它的工作原理:

首先,在创建文件时,播放器输入名称“ズモゲフフ”(zumogefufu)。还有一个可行的儿童NPC,谁给出了“ぇヌフコオ”(Enufukoo)。这将在稍后作为代码执行。然后,Plantermust在获得“谐腾”项目之前“通常”播放游戏。在该点,玩家将使在特定区域中执行“TextWarp”毛刺所需的设备,并达到界限地图瓦片。

此时,如果播放器打开该地图,他们会发现它们的光标isout-ed-edress。如果选择特定的界面磁贴,则程序计数器(PC寄存器)将尝试跳转到未定义的位置;这意味着它占据了一些价值,这不应该成为PCRegister的地址。最终,PC最终跳转到地址FAD5,这是在对象存储器的实质上。然后,通过在屏幕上操纵对象,我们可以进行“JP”指令,以便跳转到地址E602,存储链接的名称。 SBD的早期研究更详细地达到了达灵。

链接名称(ズモゲフフ)对应于操作码“XOR A,D2; LD(CBCB),a“。”.since'寄存器的值为d5,我们实际上将value“07”进入地址“CBCB”。 (我们无法使用名称输入0x00-0x5f之间的值,因此我们有时需要解决此问题)。

地址“CBCB”对应于变量跟踪打开的菜单类型。这通常是“02”的地图菜单,但通过将其更改为“07”,我们将菜单更改为Child NPC的名称输入屏幕。

这方便,因为实际上,孩子的名称缓冲区直接存储在链接名称旁边。这意味着孩子的名称是下次执行的。更具体地说,由于周围的字节,它将执行Opcode“LD BC,XXXX”,其中“XXXX”是孩子名称的字符;接下来是3个更可控的字节,然后是TheOpcode“LD(BC),A”。

重新回顾:我们有一个任意代码执行设置,打开了子项菜单,也将孩子的名称作为代码执行;此含义可以继续更改我们要执行的代码。即使只有5个字节的工作,甚至在没有能够输入字节00-5F的情况下,这也足以将任何值写入许多内存地址(只要每个地址的每个字节为60-FF)。

只有一个剩下的问题:如果我们想在Thechild的名称中使用所有5个字节,我们需要某种“返回”操作码。在这种情况下,“RST 38”操作码有效地起作用。孩子的初始名称“ぇぇ”将此操作码(0xFF)写入地址C611(E611是C611的镜像)。

我们现在有能力将字节写入一个非常大量的MemoryAddresses。现在我已经展示了如何在Oracle上获得这种能力,我将展示它如何用于利用链路电缆的遗传般的遗漏。

在“文件选择”屏幕中,如果ITIS通过链路电缆连接,则可以选择“链接”。例如,在完成Oracle文件后,Oracle of Seasons可以链接到它以基于年龄文件初始化新文件。如果此过程成功,则会在链路电缆上运输0x16字节“文件标题”,此数据用于初始化文件。此数据包括但不限于:

动物伴侣(你可以选择3个“同伴”之一来帮助游戏)

为三个文件中的每一个(0x42字节总计)的0x16字节标题被存储为ATADDRESS 4:D98D。它们对应于来自Anormal GamePlay的地址C600-C615的字节。

文件头有两个布尔变量,它是thisvulnerability的关键,“链接游戏”和“英雄的游戏”变量。要理解的重要事项是这些应该是0或1,但我们将它们的ACE中的ACE授予它们以任何值。这是问题的问题,而在执行以下代码中运行(来自ThedisAssembly的代码片段):

;加载A:WfileShileGame(位1),; wfileislinkedgame(bit 0)ld hl,wfileSerogame LDD A,(HL)添加一个添加(HL); wfileislinkedgame推送af;根据是否;是不同的初始化数据;它' s一个链接或英雄游戏ld hl,initialfilevariablesable rst_addd doududindex; hl + = a * 2 ldi a,(hl)ld h,(hl)ld l,呼叫_initializefilevariables [...] initialfilevariablable:.dw _initialfilevariables_standardgame .dw _initialfilevariables_linkedgame .dw _initialfilevariables_herogame .dw _initialfilevariables_linkedgame

上面的代码假设变量“wfileislinkedgame”和“wfileSerogame”为0或1,但它们可以是任何东西。通过将它们设置为value4或更高,它将尝试从“initialfilevariablesable”中读取不存在的条目。结果:它使用完全垃圾数据致致拓展文件。

这只能用于损坏256字节范围内的值(地址C6xxW调节正常游戏模式),但这是保存数据的高度关键区域。 itholds前面描述的0x16-byte文件标题,当前的房间链接是,他的库存项目,许多游戏进展标志......有很多工作要做。

将“wfileislinkedgame”变量(C612)设置为Oracle ofages中的无效值将在链接时触发季节的oracle中的损坏。在最重要的情况下,结果很有意思,但不是很控制。然而,有特定注意的aretwo值。

第一个值是0x2b,导致游戏读取初始文件DataFrom地址2312.这一点到ROM,因此结果是100%一致;它是一个奇怪的文件,其中链接在一个完全不同的房间开始,链接似乎有一个腐败/不存在的项目,并试图谈论附近的NPC崩溃游戏。这本身并不完全有用,而是一些属性,使其在与2ndlink电缆漏洞结合使用时使其有用,但稍后描述。

第二个值是0x4f,它从地址4:f9c9读取初始文件数据。这是地址4:d9c9的镜像,它是链接电缆上的“文件头”数据传输的一部分;特别是,这一点到了最后6个字节文件3的标题。当然,这是从古代的oracle完全控制的.Having 6字节足以让我们覆盖任何我们想要的值的C6xx范围中的任何3个地址。

这似乎应该是非常强大的,但有局限性。首先,如果我们想改变房间链接产卵,我们还需要覆盖将在游戏开始时禁用切割的事件标志,其他温度将无法移动。我们可能还想覆盖另一个事件标志,可打开库存或地图菜单;并且已经使用了全部使用了全部3地址写入。仍然,这种精确的控件确实允许一些非常有趣的设置,例如此文件,其中链接生成到最终Dungeonequippippipped附带0剑。 (可悲的是,这是真正的设备才能真正终止最终的老板。)

考虑到以这种方式损坏的许多文件具有崩溃游戏的趋势,因此可能很可能通过该漏洞实现远程执行情况;但是,由于下面描述的脆弱性,因此不必要地且可靠地达到了。

如前所述,“动物伴侣”是一种帮助球员游戏的动物。此变量的预期值为0x0B(Ricky TheKangaroo),0x0c(Dimitri Dodongo)和0x0d(Moosh飞行熊)。

当然,这可以在链接之前在年龄文件的Oracle中损坏。 Inmy以前的搜索在密码系统中的onvul​​nerability,我描述了如何在0x00-0x0f之间的任何值丢失。但是,当使用链路电缆时,Wecan将其设置为0x00-0xff之间的任何值。

在季节和季节的甲骨文中,这可以触发地图屏幕的漏洞。由于地图的布局实际上基于选择了哪个伴侣的更改,因此运行了一些代码,其覆盖了基于动物伴侣的不同瓷砖的地图上的矩形敏感。 SASIT结果,将动物伴侣设置为高值,而是导致IT覆盖内存不相关的内存。发生这种情况是因为,再次,GameatTemps要从表中读取未定义的值,如下面代码所示:

;如果伴侣不是瑞奇,请执行;适当的最小图块替换。 LD A,(WaniMalcompanion)Sub $ 0C; DIMITRI CALL NC,MAPMENU_PERFORMTILESUBSTITUSTURES [...] MAPMENU_PERFORMTIREUBSTITIONS:LD HL,MAPMENU_TILESUBSTURITTABLE RST_ADDATOHL LD A,(HL)RST_ADDATOHL @ NEXTSUBSTURIT:LDI A,(HL)或RET Z LD B,A; DE =目的地LDI A,(HL)LD E,LDI A,(HL)LD D,A; HL = SRC LDI A,(HL)LD C,LDI A,(HL)推高H,LD L,C; B =高度,C =宽度LD A,B和$ 0F LD C,LD A,B和$ F0交换LD B,A;代码复制矩形区域;来自" HL&#34的数据; " de"。[...];这是一个瓷砖替换表的表现; overworld映射在各种情况下.mapmenu_tilesubstutchtable:.db @ subst0 - caddr。ductr。dual1 - caddr .db @ subst2 - caddr .db @ subst3 - caddr .db @ subst4 - caddr .db @ subst5 - caddr .db @ subst5 - caddr。 Caddr .db @ subst7 - caddr;阅读价值过去的读数将导致;不相关的内存被损坏!

对于季节探索的Oracle,我们将使用动物伴侣值0x44(有几个其他值表现类似的值)。这将导致Theanimal伴侣写入0x2000-0x2FFF范围内的地址,即它是可切换的ROM BankRegister。由于代码从可切换的ROM BANK执行代码时,因此在其鼻子下突然发生变化。

这很容易导致游戏崩溃,通常会。但是,首先是幸运的是,一致;程序计数器最终跳跃地址F81A,这是D81A的镜像。在这种情况下,SwitchaBleram Bank 4已加载,这意味着这实际上是解决方案4:F81A - 这是靠近存储在4:D98D(或4:F98D)的文件标题缓冲器,这是一种从链路电缆完全控制的缓冲器转移!

那么,遗留的问题是,程序化是否有可能在F98D达到我们的有效载荷。挺直有两个令人讨厌的障碍。第一个是4:F900的缓冲区,它在打开菜单时存储链路'的临时拷贝。经过一些实验后,我发现了持有物品的链接的精灵是我们可以使用的简单普遍存在的一个,这不会导致崩溃或其他不良影响,因为它包含了一个有用的“JR”操作码(相对跳跃),可以跳过最多的结果代码。

第二个障碍是可变的4:F98C,在我们有效载荷之前的一个字节。宾列及是一个未使用和未初始化的字节,这意味着它的价值依赖于硬件电源时它发生的情况。基于BGB仿真器的测试,该值通常为0xFF,或“RST 38”操作码,我们在剥削中尝试;但它有时可能是别的东西,我们需要依靠这个剥削来工作。但是,它不清楚真正的硬件与BGB模拟器的行为相同,否则即使在这方面存在AllhardWare也是一致的。

这是我们将漏洞2与漏洞1组合到Bypassthis问题。对于“linkedgame”标志,使用值0x2b初始化的损坏文件设置了两个关键标志,分别绕过链接'中的“无意识”状态,并启用要打开的地图菜单;这种介绍了2分钟的介绍。此外,由于不清楚的原因,链接最初出现,好像他拿着盾牌一样,即使他不是。

当作为代码 - ithappens执行时,这种特殊的精灵非常方便,以包含指令“JR NZ,F98E”,该指令“JR NZ,F98E”,它通过直接跳转到我们的有效载荷来绕过4:F98C的uniNitialized字节。这款Makesthe利用100%一致。

既然我们有一种方法来执行可通过可链接控制的内存区域,我们需要决定有效载荷。为了安全地恢复游戏的执行,我们必须先做两件事:

重新打开屏幕(打开菜单时会短暂关闭)。出众,如果没有完成,游戏软锁。

此外,我们将写入0x0a来解决C2EF;这将触发序列。因此,有效载荷将如下所示:

现在,我将解释如何在与季节Oracle联系的Ages of Ages文件Priorto中的exproit。

首先,我们将通过将链接的名称设置为“ズモゲフフ”(zumogefufu)和孩子的名称,在“ぇ”(enufukoo)中,以“ぇぇ”(enufukoo),在早期的部分中的Asextoplate中设置Ace。这使我们能够通过重复修改孩子的名称来写入多种媒体地址。

然后,该策略将通过直接写入保存RAM中的Datafor文件插槽1来损坏我们的文件。通常,通过写入存储在C6xx内存范围内的副本,然后通常保存ANGAME来更容易损坏我们的文件,但我们不能这样做有两个原因:

我们无法可靠地写入C610等地址,因为“10”不是valueStat对应于可进入的字符。

我们想要损坏季节有效载荷的数据也是佩戴在年龄段的ace设置的数据。如果我们覆盖它,我们将失去追踪任意记忆写作,我们将无法完成处理。

将直接写入保存文件绕过这些问题,但引入了一个新的问题:文件校验和。游戏将自动修复文件checksumif,我们修改了C6xx内存范围,但如果我们向保存数据编写而不是这种情况。因此,我们必须确保校验和不会改变,以防止游戏将文件考虑为“损坏”并还原返回文件。

幸运的是,校验和算法很简单:它是所有16位字的总和。只要字节和那个值的初始值之间的差值始终相同,校验和的差异将永远是唯一的;因此,我们可以通过对抗该差异在另一个变化中来解决校验和。我们做出以下假设,以确保变量的数值是一致的:

链接名称是“ズモゲフフ”,孩子的名字是“ぇヌフコオ”。

如果孩子的名称已更改,则此后的游戏尚未保存。

为了写入保存RAM,我们必须做的第一件事是在0x0000-0x1FFF范围内写入值0x0ATO。这将解锁SavErambetween Addrandes A000-BFFF并允许我们写信给它。这可以通过将孩子的名称设置为“ろろフケの”(Rorofukeno)来实现这一目标:

然后,除了损坏的“动物伴侣”(A070)和“链接游戏”(A072)(A072)所需的价值观,我们将开始将有效载荷写入文件1,如上述部分中所描述的那样损坏季节文件的Oracle所需的值。我们必须向“已完成的文件”(A074)变量提供非零值,以便全部执行链接;此变量将作为其中一个二手修订器之一。下表显示了必须输入的所有名称,TheadDress修改,以及更改的值。请注意,“SRAM”地址是实际写入的“SRAM”地址,但“WRAM”副本是Alsonoted以供参考。

要加快输入名称的过程,它们可以重新排列到文件中,以利用重复的字符:

おぞララおぞララかぞラゼくぞラハけぞラプけぞラプちぞラトてなぞラナェぞラヂきぞヌシきぞヌシこぞヌッそぞヌッさぞヌギ

在此表中输入并执行此表中的所有名称后,PlayerMust重置或关闭游戏而不保存它(否则他们会撤消他们刚刚做过)。如果它已正确完成,文件的名称应该havechanganged(现在它现在包含通常无法进入正确箭头标志的字符)。如果要错误地完成,校验和将终于正确,并且由于恢复备份,该文件将显示不变。

通过链接到该文件初始化的季节文件的Oracle可以只要在装入文件后立即打开地图; 此WillTrigger触发动物伴侣错误并从链接电缆发送AGESTHAT的Oracle中的文件标题。 Ages文件的Oracle应该在FileSlot 1中,以便此项工作。 此漏洞可以在此处看到。 首先,软件开发人员对从外部来看的投入消毒,以避免如本报告中讨论的安全缺陷.Nintendo可能认为没有人会想到 ......