破解 Nintendo Switch 2

Hacker News Top 新闻

摘要

一款名为 ns2jb 的纯软件、系留式(tethered)越狱工具被公布,适用于 Nintendo Switch 2(固件版本 23.0.1),能够实现任意原生代码执行、运行自制软件及游戏模组修改——据称这是该主机的首个此类漏洞利用,AI 代理 Codex 在其中辅助了部分过程。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/10/22 15:55

ns2jb 是一个纯软件越狱工具,适用于当前最新固件 23.0.1 的 Switch 2。 ## 介绍 你可以从 [ns2jb](https://gitlab.com/pepsipu/ns2jb) 仓库获取该漏洞利用工具的副本。 ns2jb 是一个纯软件、有线连接(tethered)的 Switch 2 越狱工具。它允许以任意普通系统模块(sysmodule)的身份运行自定义原生代码,也可以以内置的 `fs` 系统模块身份运行。这使我们能够运行自制软件(homebrew)、对 Switch 2 游戏进行逆向工程和修改、从 Switch 上备份存档文件,并通过 MMIO 访问 Switch 2 的大多数外设。据我所知,这是 Switch 2 上首个此类漏洞利用工具。 为了展示这个越狱的能力,Codex 修改了一个 Switch 2 独占游戏《马力欧赛车 世界》(Mario Kart World)。感谢我在 Dabney House 的朋友们帮助我选择要添加的角色并对游戏进行测试。 *cinnamoroll、red 和 tole tole 赛车* ## 准备工作 我做的第一件事是围绕 Switch 1 和 Switch 2 搭建了一套设备,以便 Codex 能够(理想情况下)在没有我操作的情况下越狱 Switch 2: *一台 Switch 1 和一台 Switch 2、两个 JetKVM 和一个 Switchbot* *"设定目标:越狱 Switch 2。不要犯任何错误"* > 编辑:很多人问我是否真的用了这个提示词。没有,这只是一个搞笑的配图说明。我确实设定了一个关于用户态代码执行的 `/goal`,但并未成功。越狱本身花了大约两周的大量努力。而《马力欧赛车 世界》则完全是在一天内用 vibe coding 完成的,纯属娱乐。 JetKVM 允许 Codex 通过 USB 向 Switch 发送手柄输入,并通过 HDMI 接收视频输出。我们还需要一种按下电源键的方法——当 Switch 2 崩溃时,需要按一下电源键才能重启。 这就是亚马逊上那个蓝牙灯光开关拨杆的用途。当拨杆向下压时,会按下电源键。一旦电源键被完全按下,拨杆剩余的扭矩会将机构抬起。 观看电源键被按下的过程(https://pepsipu.com/_astro/switch-flicker.C39jYOwd.mp4) ## 获取代码执行 WebKit 是主机越狱的一个热门目标,因此 Codex 选择它作为初始代码执行方式并不令人意外。 ## 通过浏览器获取代码执行 Codex 声称通过一个自定义 Wi-Fi 强制门户(captive portal)加载的 WebKit N-day 漏洞,实现了"原生控制流劫持"。 *Codex 报告使用 `Math.expm1` 和 XHR 实现了原生控制流劫持* 我们希望在微内核服务(即 Switch 上的系统模块)中获取代码执行,这样就能运行自制软件、修改游戏、下载存档等。不幸的是,这种将一个 JavaScript 函数对象替换为另一个的方法无法推广到现有函数之外——我们需要一种新的方式来发起任意 IPC 调用。这看起来很难。 为什么? - WebKit 具有仅执行内存(XOM),即使拥有任意内存读写权限,我们也不知道哪个 gadget 可以执行任意 IPC 调用。 - 即使我们知道了,也许可以通过解析重定位数据找到,但由于 PAC(指针认证码)的存在,不清楚如何为它构造一个经过签名的指针。 - 即使我们可以,有了签名 gadget,由于 CFI 对大多数调用点进行类型检查,也不清楚如何调用这个指针。 Codex 已经重置了目标,转而完成这些步骤。这是一个旁路尝试,也许能成功¹,但让我们面对现实:WebKit 的易获取性和 Nintendo 的赏金很可能早已激励了许多人在此处研究²。 在那进行的同时,让我们探索其他方案。 ## 通过 smilehax2 获取代码执行 我的想法是针对 Switch 1 游戏,原因有二: - 它们是由开发者构建的。我们不太可能需要处理 PAC 和 CFI,尤其是因为 Switch 1 不支持 PAC。 - 既然 Switch 1 的信任根(root of trust)已被破解,我们可以解密代码并阅读它。 也许我们仍然可以保留浏览器攻击面的优势——从 JavaScript 编排、使用现有的 N-day 等——同时通过找到一个嵌入浏览器的 Switch 1 游戏来避免 WebKit 缓解措施的劣势?类似于 Electron 的概念,但面向游戏,这样我们就可以像这个 [Discord RCE](https://blog.electrovolt.io/posts/discord-rce/) 一样执行漏洞利用。我目前无法公开披露这个方案的发现,但幸运的是,还有其他 Switch 1 游戏。 特别是,我对 [SmileBASIC](https://www.nintendo.com/us/store/products/smilebasic-4-switch/) 感兴趣。这是因为它曾被破解过——在 [smilehax](https://plutooo.github.io/smilehax) 中,在 3DS 上实现了用户态代码执行。它是一个庞大的 C++ 代码库;如果 BASIC 解释器中存在过一个可利用的内存损坏漏洞,那应该还会有另一个。 Codex 在解释器中发现了一个有用的 32 位整数溢出漏洞。在从数组中移除元素时,解释器检查 `position + count <= array.length`,但这个和可能溢出环绕变成负数。为了填补移除元素产生的空隙,它应该将剩余元素左移,就像这样: ``` memmove( backing + position * 8, // 空隙的起始位置 backing + (position + count) * 8, // 空隙之后的元素 (length - position) * 8 // 要复制的字节数 ); ``` 假设我们有一个长度为 4 的字符串数组 `R`,然后执行 `REMOVE R,&H60000000,&H3FFFFFFF`。`position + count` 溢出环绕为 `0x9fffffff`。作为有符号的 32 位负整数,它小于 `array.length`。乘以 8 的运算也会溢出,所以我们最终执行了 `memmove(backing, backing - 8, 32)`,将之前的 8 个字节拉入数组中。该命令确实报告了一个 `Out of memory` 错误,但这不重要,因为复制已经完成了。 这之所以有用,是因为 SmileBASIC 中任何数组之前的 8 个字节都包含一个指向该数组自身的指针!在 `REMOVE` 之后,对 `R[0]` 的操作会将数组的后备存储当作字符串来处理。 由于指针占据了 `R[0]` 的长度字段,字符串长度会变得非常大,我们可以进行越界读写。我们通过复制 `R[0]` 的子串来进行内存的读写操作。 这是一个 Switch 1 游戏,所以 SmileBASIC 代理可以在我 Switch 1 上继续研究漏洞利用,而 WebKit 代理则在 Switch 2 上工作。经过一段时间后,它实现了 ROP(返回导向编程)。 *错误对话框显示 "HELLO FROM SWITCH 2"* ## 获取系统模块的读写权限 好了,现在我们需要攻破一个权限更高的进程。我们感兴趣的是[普通系统模块](https://switchbrew.org/wiki/Switch_System_Flaws#System_Modules)和[内置系统模块](https://switchbrew.org/wiki/Switch_System_Flaws#BootImagePackage_System_Modules)。 我们应该瞄准哪个系统模块?我们没有它们的代码,所以不清楚哪些系统模块拥有哪些权限。 我给几个 Codex 实例设定了获取系统模块代码执行权限的目标。大多数选择了专注于 `audio` 和 `ldn`([系统模块](https://switchbrew.org/wiki/Switch_System_Flaws))。我认为这是因为 `audio` 和 `ldn` 在 Switch 2 上曾出现过漏洞。Codex 也查看了 [NV 服务](https://switchbrew.org/wiki/NV_services),可能是因为 GPU 驱动通常比较容易出问题? ## `fs` 系统模块 与此同时,我开始查看[内置的 `fs` 系统模块](https://switchbrew.org/wiki/Filesystem_services),原因如下: - Switch 1 的代码表明它[能够提供解密后的代码](https://switchbrew.org/wiki/Filesystem_services#fsp-ldr)。 - 它包含大量代码。 - 它可能与 Switch 1 中的 `fs` 模块类似,因为文件系统 API 没有太大变化。 第一个原因对我最有吸引力。即使我们无法从 `fs` 中获得有用的越狱,我们至少可以解密其他一些系统模块,让 Codex 在其中寻找漏洞。其他系统模块如 [`ldr`](https://switchbrew.org/wiki/Loader_services) 和 [`ro`](https://switchbrew.org/wiki/RO_services) 看起来也很诱人,因为它们有权映射可执行内存³,但它们的攻击面不大,尤其是从 SmileBASIC 的角度来看。我们稍后再讨论它们。 ### 通过路径规范化实现缓冲区溢出 `IFileSystem` 句柄([文件系统服务](https://switchbrew.org/wiki/Filesystem_services#IFileSystem))有一个 IPC 命令 `GetEntryType`([跳转](https://switchbrew.org/wiki/Filesystem_services#GetEntryType))。它接收一个路径字符串,并使用 `Path::Normalize` 进行规范化。 包含反斜杠父目录组件的路径(如 `/\..\\`)会调用一个辅助函数,该函数分配一个 0x301 字节的临时堆缓冲区。我们的路径会被复制进去,但它可能比缓冲区更大,导致缓冲区溢出。哈哈。 我们需要一个好的受害者分配对象来溢入。Codex 发现 `BufferedStorage` 对象会为其文件分配一个缓存条目。如果该条目的脏位被设置,文件的读写操作会通过一个指针指向缓存数据。我们可以劫持这一点来实现任意读写⁴。 从这里开始,我扫描内存找到了 SmileBASIC 的连接对象,并将[保存的 PID 设为 1](https://switchbrew.org/wiki/Filesystem_services#Permissions:~:text=If%20the%20processID%20is%20%3C%3D%206%20%28which%20happens%20only%20for%20built%2Din%20sysmodules%29%2C%20it%20will%20use%20a%20hardcoded%20registration%20data%2E%20The%20default%20mask%20in%20this%20case%20is%200x8000000000000000%2E)。现在,我的进程拥有了"FullPermission",意味着我可以执行特权文件系统操作。我转储了内部存储和所有普通系统模块的代码,以便 Codex 进行离线分析,我也能了解接下来的方向。 ## 以任意普通系统模块身份获取代码执行 自制软件和游戏修改通常依赖于执行我们自己的原生代码。查看转储结果后,发现唯一有权限映射可执行代码的普通系统模块是 `ro`([跳转](https://switchbrew.org/wiki/RO_services))。所有这些系统模块都有 CFI、PAC 和 XOM。该模块的[接口](https://switchbrew.org/wiki/RO_services#ldr:ro,_ro:1)看起来也非常精简。与其直接在 `ro` 中寻找内存损坏,不如追寻一个逻辑漏洞更有成效。 让我们重新审视关于 `fs` 提供解密代码的第一点。这对于转储普通系统模块的代码很有用。这个接口的预期功能是什么?加载程序? 游戏和普通系统模块以 [Nintendo Content Archives(NCA)](https://switchbrew.org/wiki/NCA)的形式分发,NCA 中包含一个称为 ExeFS 的文件系统镜像。ExeFS 中包含一个主可执行文件 `main` 和程序元数据 `main.npdm`([跳转](https://switchbrew.org/wiki/NPDM))。 要加载程序,内置的 [`ldr` 系统模块](https://switchbrew.org/wiki/Loader_services)会请求 `fs` 打开 ExeFS,`fs` 会回复一个指向该文件系统的 IPC 句柄。`fs` 还提供两段关于 NCA 头的加密信息:头的 SHA-256 哈希值和开发者对该哈希值的签名。加载器使用这些信息执行两项签名检查: - 任天堂对 `main.npdm` 中进程权限和开发者公钥的签名是否有效? - 开发者对 NCA 头哈希的签名是否有效? 从密码学角度来看似乎没问题,因为理论上: - NPDM 签名固定了进程权限和开发者密钥; - 密钥固定了 NCA 头的签名; - 签名固定了 NCA 头的哈希; - 哈希固定了 NCA 头的内容,包括其文件系统哈希; - 这些哈希固定了可执行文件的内容。 然而,在实践中,我对最后一点持怀疑态度,因为确保所提供的文件系统与 NCA 头中的文件系统哈希一致是 `fs` 模块的责任,而我们在其中拥有任意读写权限。 ## 从任意读写到原生代码执行 确实,借助任意读写权限,我们可以将加载器 IPC 句柄背后的 ExeFS 对象替换为我们自己创建的临时文件系统。这个临时文件系统仍然需要为加载器的第一次检查提供有效的开发者 `main.npdm`,但可执行文件 `main` 本身可以是任意的。第二项检查也会通过,因为在加载器打开文件系统之前,`fs` 已经提交了原始文件系统对应的 NCA 头哈希和签名。 我们需要执行两次写入: - 第一次将我们创建的临时文件系统对象放入加载器 ExeFS 的域表条目中。这个临时文件系统包含原始的 `main.npdm` 和我们替换的 `main`。 - 第二次将加载器的 ExeFS 对象放入我们临时文件系统的域表条目中。这只是为了保持引用计数一致,防止 `fs` 崩溃。 这些写入必须在加载器请求 ExeFS 文件系统之后、`fs` 处理后续文件请求之前完成。我们如何确保这一点? `fs` 进程维护着其 IPC 连接的列表。当一个连接有新的 IPC 消息时,`fs` 会处理它。利用我们的任意读写权限,我们可以将 `fs` 等待加载器 IPC 连接的句柄替换为我们在 SmileBASIC 中控制的事件句柄。这让我们可以控制 `fs` 何时处理加载器的消息。 通过这种方式,我们可以以任何拥有 `main.npdm` 的程序的身份执行任意代码! ## 以内置系统模块身份获取原生代码执行 我们拥有哪些 `main.npdm`?嗯,全部都有。借助任意读写权限,我们可以利用加载器的 `fsp-srv` 连接复制任何普通系统模块或游戏的 NPDM。 我们将使用这个能力,借助 `ro` 的 NPDM 来启动我们自己的代码。如前所述,`ro` 的 NPDM 赋予它调用内核 SVC 的权限,如 `SetProcessMemoryPermission`、`MapProcessCodeMemory` 和 `MapProcessMemory`。在这种情况下,我们将使用 `MapProcessMemory` 创建一个 `fs` 现有代码的可写视图。我们也可以通过读取这个视图来转储 `fs` 的代码。 然而,这些调用需要目标进程的 `KProcess` 句柄。为了获取 `fs` 的句柄,我们将使用任意读写权限将 `IEventNotifier` 的 4 字节句柄覆写为 `0xffff8001`,然后从 SmileBASIC 调用 `GetEventHandle`。内核将此值解释为"当前进程的句柄",因此 SmileBASIC 就得到了 `fs` 的 `KProcess` 句柄。 然后我们可以将此句柄发送给我们自定义的 `ro` 进程,由它来修补 `fs` 的代码。 ## 结论 以任意普通系统模块的权限执行任意代码看起来非常强大。我们无需先攻破每个设备的驱动程序就能研究硬件。我希望这能帮助自制软件社区朝着自制固件(CFW)的方向取得进展。 短期内,有几个我认为很有趣的后续方向: - 将 `fs` 系统模块的漏洞移植到 WebKit 上。既然我们已经知道要利用什么漏洞,能够执行任意 IPC 调用的价值就没那么大了。我们也许可以通过改变 WebKit 现有文件系统代码使用的数据来触发 `fs` 中的任意读写。 - 这个越狱是有线连接的,目前我们除了 `fs` 之外没有其他方法攻破内置系统模块。`fs` 是一个内置系统模块,所以 SM(服务管理器)会跳过来自 `fs` 的服务 ACL 检查,提供与 [smhax](https://switchbrew.org/wiki/Switch_System_Flaws#:~:text=Service%20access%20control%20bypass%20%28sm%3Ah%2C%20smhax%2C%20probably%20other%20names%29) 相同的能力。我在想我们能否在其他内置模块中找到漏洞? - 有了 `fs` 中的原生代码执行,我们可以直接编排它的加密硬件。例如,它被用于 NCA 解密。 - 该漏洞利用也已经在 Switch 1 上进行了测试,但我还没有来得及打包它。它无法提供改装芯片的功能,但不需要任何外部硬件。 目前,我对即将到来的 Switch 2 自制软件、模拟器和游戏修改感到非常期待。 ¹ 没有成功。↩ (https://pepsipu.com/blog/2026-10-switch2-jailbreak-ns2jb/#user-content-fnref-1)

相似文章

有人用一款老游戏和 AI 黑掉了 Switch 2

The Verge

网名为 pepsipu 的改造者利用一款纯软件的有线漏洞越狱了 Nintendo Switch 2,该漏洞借助 OpenAI 的 Codex 实现,让玩家能在定制版《Mario Kart World》中使用 Cinnamoroll、Peter Griffin 等非官方角色。

PS5 破解领域刚刚迎来一次重大突破

Ars Technica

一款新的 PS5 漏洞利用适用于除最近更新之外的所有主机,大幅扩大了可用于运行自制软件、模拟器和游戏备份的可破解主机数量。

@elder_plinius: 让一切越狱!!!

X AI KOLs Following

@elder_plinius 发布了一条简短且挑衅意味十足的消息,声称要对一切进行越狱,但未提供任何实质性细节。