» 您尚未登录:请 登录 | 注册 | 标签 | 帮助 | 小黑屋 |


发新话题
打印

[新闻] PS Vita 首个原生系统破解 Rejuvenate 已经公开发布(含下载)

这是目前 PS Vita 惟一已知的原生系统漏洞,其实也就是三年前就已经传出过消息的那个漏洞。因为这个漏洞依赖 PSM 运行,而索尼现在已经完全停止了“PSM 开发助手”的下载,所以 Yifan Lu 决定公开发布这个漏洞。

Rejuvenate 0.2 官方下载:http://yifan.lu/p/rejuvenate/
国内镜像:http://pan.baidu.com/s/1eQniHqU

============================

http://yifan.lu/2015/06/21/hacking-the-ps-vita/

译者按:目前,与 3DS 相反的是,PS Vita 的破解工作一直强调重在参与、全民参与,而本文所述的很多重要概念之前在 wololo.net 上已经有专门的文章进行了解释。非常欢迎到 wololo.net/talk 论坛和 EFNet #vitadev IRC 频道参与讨论!

破解 PS Vita

下面的内容选自我(译注:Yifan Lu)在 2012 年 9 月(将近三年前)写的一系列没有发布的帖子。这些帖子不但详细解释了我发现的漏洞,而且阐释了我发现它的过程。我本想在索尼封堵这个漏洞或者其他人分析内存转储并发现另外的漏洞之后立即发布这篇文章。但是,直到今天,PSM 权限提升仍然是惟一已知的在 PS Vita 上执行原生 ARM 代码的方法。对于已经过时的引用表示抱歉。

寻找线索

在开始的时候,让我们先想想能够攻击这个黑箱式设备的办法。一般来说,一个新的设备解锁的过程包括这些步骤:1) 读取设备的内存、ROM 或闪存,2) 分析读取的数据以获取信息和缺陷,3) 利用缺陷创造一个工具使得其他人可以轻易地获取最高权限。

首先我们需要的是信息。我们的信息来源很少。首先是维基,我们可以从中获知硬件的信息。不幸的是,虽然这个系统使用 ARM 架构,但是 CPU 是索尼专用的芯片,我们没有任何了解。系统中许多组件的源代码也可以找到。我们可以利用这些源代码来寻找被调用的库(例如 libpng)当中的缺陷。但是,即使这样的缺陷存在,在没有内存转储的情况下,要利用这样的缺陷是极其困难的,因为我们并不知道在何处注入代码,或者注入什么样的代码,故收集信息的要点就在于取得一份内存转储。所以,在这个阶段就试图破解系统是没有意义的,几乎只能靠猜测。在一个像 PSP 这样的系统中,这个过程要稍微容易一些。1.00 版的固件直接允许未签名的代码运行,而且系统文件没有加密,可以任意分析。当封堵漏洞的固件发布时,信息已经泄漏出去,并且可以用来创建一个用于在 1.50 固件中获取更多信息的破解,然后是 2.00,等等。正如你所看到的,一切都取决于第一个破解,而这就是我们试图发现的。这一次,索尼没有让我们轻易成功。下一个显然易见的攻击方式是硬件破解。这是绝大多数的主机最开始被分析的方式,而且是 3DS 当前被分析的方式。但是,Vita 不允许我们轻易地找到嗅探内存的办法,因为内存与 CPU 是在同一个片上系统当中(嗅探内存的办法是在内存和 CPU 之间的路径上放置一个嗅探器,以此得知读取或写入的信息)。我并不否认 Vita 在硬件方面破解的可行性,但是我并不想拆开价值 300 美元的设备,仅仅为了微乎其微的获得一些信息的可能。并且,我对硬件一无所知,那就这样吧。

最“常见”的漏洞(看看 PSP 被破解的频率)是缓冲区溢出和堆溢出。但是,寻找这两者都需要与系统有关的知识。例如,缓冲区溢出使你可以将代码的执行重定向到内存中的任意位置。但是,我们并不知道内存的布局。我们不知道栈所处的位置,也不知道标准调用的位置。当然,猜测的可能性总是有的(基于对其他 ARM 平台或者 PSP 的了解),但是根本就没有办法确认你所找到的漏洞的确是缓冲区溢出。你所能知道的仅仅是游戏或者系统发生了崩溃,而且你可以试着“注入”内存地址,但是内存地址也只能靠猜测。许许多多的未知使得依靠猜测不那么现实。通常,在这时,像我一样的人(软件人员)会退到一旁,让专业的硬件逆向工程师上阵,揭开 CPU 中的电路,施展黑魔法,但是现在仍然有希望…

索尼最近(译注:2012 年)公布了 PlayStation Mobile,这是允许独立游戏开发者给 Vita 和(某些)Android 手机开发在沙箱中运行的软件的一种方式。这是进入系统当中的一个非常有潜力的办法,因为我们只需要找到一个可以提升权限从而绕开沙箱的漏洞,而不再需要寻找一个可以执行代码的漏洞。一般地说,这个任务更加容易。PSM 使用一个名叫 Mono(基于 Windows 上的 .NET Framework)的运行时库,这个库可以读入“字节码”(将一种编程语言编译成另一种更简单的语言的代码),通过安全检查(即所谓沙箱)之后,在设备上将其编译为原生 ARM 代码。使用这样的安全机制会使得性能变得低下,但是我们在此不讨论为什么 PSM 的性能低于原生的自制代码。好消息是,因为 PSM 是基于 Mono 的,而 Mono 是开源的,我们可以拿到几乎整个安全系统的源代码。坏消息是,因为 Mono 是一个非常安全的平台(开源项目通常更加安全,因为有更多的人在查找漏洞),最近的一个主要缺陷在 2010 年就已经修复了。但是,在 Mono 中寻找漏洞,仍然比盲目猜测要好得多。至少我们现在已经有一个目标了。

攻击方案

我们现在有一个比“破解 Vita”更加具体的目标了。这个目标是“在 Mono 或者 PSM 对 Mono 的实现当中找到一个漏洞”。这是整个过程当中最乏味的部分。在接下来的三个星期里,每天大约有三到四个小时的时间,我做的惟一事情就是阅读 Mono 的源代码,同时反编译和阅读 Windows 上的 PSM 应用,以及 Android 的 PSM 应用。这是破解的乏味之处,很多人都会掩饰过去。慢慢地,随着我对 Mono 虚拟机了解的深入,我开始制造一些可能的攻击向量。虽然 Mono 中的绝大多数执行原生代码的功能都被删除(Pinvoke,加载动态链接库,以及用来运行程序的 System.Diagnostics.Process),System.Marshal 和 System.IO 都被 PSM 实现了(因为像文件输入输出这样的功能必须使用原生代码)。PSM 所使用的 Mono(和 .NET)的安全系统被称为 Moonlight(或称 Silverlight)安全系统。这个安全系统(名为 CoreCLR)的工作机理是,所有托管的代码都被认为是“安全透明(security transparent)”(不安全)的,除非它是系统运行时库(mscorlib.dll)。在运行时库中,一些代码被标注为“安全关键(security critical)”,这样的代码不允许被不安全代码调用。这些“安全关键”方法通常是对例如线程、内存分配、文件输入输出等等任务的原生调用。如果能够随意调用“安全关键”的方法,就意味着能够绕过沙箱,因为在 System.Marshal 当中有一些安全关键的方法,可以直接存取内存或者跳转到内存中的任意代码。因此,对“安全关键”的方法的访问,只能由“安全关键”的方法执行,而这些被运行时库导出为一个访问“安全关键”的方法的代理。这些代理方法会执行一切必要的检查,以确保“透明”的代码没有恶意行为(而我们想做的所有事情都被视为恶意的)。

现在,我们了解了安全系统,接下来就是要找到一个瑕疵。我的第一次尝试是寻找某些“安全关键”的方法中的漏洞。只需要一个代理方法遗漏某些安全检查,我们就能取得无限制的权限。再一次,在很多个星期的时间里,我做的一切事情就是阅读代码、寻找特定的代码调用、查看在什么地方传递什么样的参数等等。在这段时间里,我检查了几百个(不是夸张)可能的攻击向量(例如,试图欺骗 PSM 使其认为我们的库是系统库,或者传递非法路径给输入输出函数,等等)。但是,正如我之前所说,因为 Mono 是开源的,许许多多安全研究人员审计了代码,尤其是因为 Moonlight 组件在浏览器当中像 Flash 一样运行(如果它的安全性甚至不如 Flash,那会是非常尴尬的)。我并不是说 Mono 是绝对安全的,而且我非常肯定其他更有才华的人会发现漏洞,但是我能找到某些并没有被那些专家发现的东西的概率很小。但是,如果我们换一个思路呢?看看如果我们去寻找那些专家没有看过,因为他们不必去看的地方会怎么样。

破解 PSM

如果 Moonlight(及其安全系统)是为浏览器设计的,那么将其用于全方面的安全工具就会产生问题。Moonlight 防御的威胁模型并不与针对 PSM 的威胁模型一致。Moonlight 是用于将用户与恶意开发者区隔开来。PSM 是用来将索尼和(我猜是他们所认为的“恶意”)开发者区隔开来。这两者能够如何比较呢?至少,两个威胁模型都需要防止对系统原生函数的访问,以及将托管的代码完全限制于沙箱当中。但是,Moonlight 并没有理由对调试器具备安全性,不是吗?调试器的目的就是“监督”应用程序,这就隐含着调用它必须具备特权。在 Moonlight 的威胁模型当中,如果攻击者可以调用调试器,这就意味着他们已经获取了执行非托管的原生代码的权限。但是在 PSM 的威胁模型当中,调试器并不能被特权保护,因为开发人员必须调用它。这看起来是个很有希望的发现,但是我们应该如何充分利用调试器呢?让我们看看 Mono 调试器能做些什么。INVOKE_METHOD 看起来非常有意思。它的描述是,它能在调试器中运行一个方法。它能调用“安全关键”的方法吗?MonoDevelop 没有任何 GUI 工具能使用这个功能,所以我很快就自己实现了一个 Mono 调试客户端。惊喜的是,我可以用它调用任何方法,包括非托管的内存读取和写入函数。我用它读取了 PSM 有权读取的所有内存区域。我把这个历史性的时刻飞快地录制了下来。但是,视频所录制不了的,是我在很多个月的辛勤劳动之后成功的感觉。

执行代码

一些人可能会因为这并不是一个聪明的软件漏洞而感到失望,但是我认为实现中犯的一个错误和任何的缓冲区溢出一样坏(如果不是更坏)。现在我们取得了内存转储,就可以运行一些代码了。这是另一个障碍。ARM 有一个被称为 XN(永不执行;execute never)的内置功能,使得内核可以决定内存中的数据可以被执行与否,一般非常严格。这就意味着我们不能简单地向栈或堆当中写入数据,并期望它能运行。即使我们现在能控制代码执行,我们并没有办法使自定义的代码运行起来。所有的可执行内存区域(例如 PSM 本身)都被标记为只读的,所以我们也不能简单地覆盖已有的代码。而且,我们没有存取内核的权限(我们跳出了 PSM 沙箱,但是又进入了上一层的由内核管理的 PS Vita 系统沙箱) 。要绕过这个限制,一个可能的办法是针对返回的编程(return orientated programming),这是现在绝大多数破解(比如 iPhone)绕过 XN 的办法。现在我们有了内存转储,这就是可能的了。在这个时候,我联系了其他(即:更聪明的)对 Vita 有兴趣的而且正在研究的人。但是,这就是我们的幸运之处了。(我必须感谢在 IRC 房间或者论坛上问过相关事宜的人,但是我现在暂时想不起他们的名字了。)PSM(Mono)在一些时刻必须产生可执行代码。回想一下 C# 编译器产生的字节码,它们通过安全检查后,必须在设备上被即时编译为原生 ARM 代码。这就意味着 PSM 有一些特殊的操作权限(得到内核的支持),可以分配并且写入可执行内存。我们有了提升权限的漏洞,就能使用这些调用,将我们自己的 ARM 代码写入内存并执行。在这个时候,我把很多很多汇编代码块注入到了系统当中。我试着读取系统文件(不行),应用程序文件(加了密),并且测试了不同的系统调用和 API,看它们能做些什么。这是我或者其他任何人第一次能在 Vita 上运行原生代码,感觉就像圣诞节的早晨。

更多细节

提升权限的办法是,找到载入的 CLR 映像的 hashmap,然后遍历 hashmap,将所有载入的映像都标记为“运行时库”,以使它们有权限执行“安全关键”调用。这是由调试器的漏洞执行的。然后,我们使用在 System.Marshal 当中找到的方法来读取和写入内存,并且从 C# 代码中直接调用原生函数。

编写加载器

即使这意味着我们能“运行原生代码”,但是要求自制软件的开发者学习 ARM 汇编,以及完全用 ARM 汇编来写他们的游戏,简直就是疯狂的举动。另外,自制软件还需要调用系统 API 函数。还有就是,自制软件必须打包成一个能在系统固件发生变化时不需要改动的格式。所以我们需要一个加载器,来把自制软件的 ELF 加载到内存(使用我们新发现的 PSM 可执行内存分配系统调用),并且在内存中将其链接到系统 API 函数。

在 PSP 上,这个问题是由 Half Byte Loader 解决的,它会释放用户空间的内存,然后把自制软件的 ELF 加载到空白的内存区域,最后动态查找并链接 API 导入。这也是 UVLoader 在 Vita 上要实现的。你,开发人员,编写 C 或者 C++ 代码,使用和真正的注册在案的 Vita 开发人员相同的 API。然后,使用一个开源的 SDK,将代码编译为与官方 SDK 相同的可执行文件格式(理论上,SDK 编译产生的文件【不是发行的游戏】,如果没有加密,也能在 UVLoader 上运行,因为格式是相同的,但是我们显然没有办法获得它,而且就算我们能获得它,也是违法的)。UVLoader 读取这个文件,解析 ELF 格式,将自制软件加载到内存,寻找内存中的 API 和系统调用,并且把它们“附加”到你的自制软件。现在,对于官方的开发人员,这些都是由系统的加载器完成的。我们没有办法访问它,因为加载器处于内核当中。UVLoader 是通过对已经加载到内存当中的 PSM 可执行文件的格式进行分析而开发出来的。PSM ELF 文件自身是加密的,所以 ELF 的残留痕迹可以在内存中找到。因为我们并不是要试图仿真系统加载器,我们可以阅读内存转储,看看东西是怎么捆绑到一起的,偏移量的含义是什么,等等。

附录:PSM 破解后记

好了,让我们回到 2015 年 6 月。自从 2012 年 9 月以来,发生了很多事情;它们大都是索尼对 Vita 的安全性的加强。当我第一次发布 UVLoader 的源代码的时候,我以为这会带来 Vita 破解的复兴,开发人员会制作开源的 SDK 和自制软件,而破解人员会继续寻找越来越多的漏洞用来加载 UVLoader(就像 PSP 一样)。不幸的是,这一切并没有发生。整个社区几乎都处于寂静当中,偶然上演一些某人发现了某些漏洞的哑剧。没有人能在 PSM 破解以外找到执行代码的办法,也没有人在开源 SDK 方面开展工作,直到上个月我发布了一份 SCE ELF 文件格式规格。但是,索尼在分析了 UVLoader 的代码之后,一直忙于加强 Vita 的安全性。惟一的可喜之处是,即使他们发布了许多安全补丁,也从来没有发现这个“漏洞”(如果你能这么称呼的话)(LGPL 协议规定索尼必须在更新“PSM 开发助手”之后公开源代码)。

反制 1:更严格的对使用可执行内存的系统调用

在 PSM 破解当中,执行代码的关键是通过特殊的系统调用,而这只有 PSM 有权限执行。这些系统调用允许 PSM 分配可执行内存并且写入。这些系统调用工作的方式是,你必须在写入内存域之前“解锁”它,完成之后“锁定”它。在 2.00 固件当中,一些特定的系统函数会检查并确保可执行内存域处于锁定状态,否则就强制结束应用。这就意味着如果你一直让域处于解锁状态(就像第一版 UVLoader 所做的),它就会强制结束 PSM。我的猜想是,索尼最开始认为这个漏洞是某些函数忘了锁定内存域,使得我们可以覆盖即时编译的代码。通过加入相应的锁定代码,UVLoader 很容易就绕过了这一点。我猜,我的偷懒反倒被索尼认为是智慧的体现。

反制 2:从 Mono 的 Marshal 中删除“危险的”方法

索尼似乎对 Mono 进行了一次(或者多次?)内部安全审计,因为每次的发布,更多安全“修复”都被添加了进来(几乎都是潜在的释放后引用或者解除空引用)。在 0.99.20(开发助手 1.03)当中,索尼删除了一个 VitaInjector 必需的函数。Marshal.GetDelegateForFunctionPointer 接受任意内存地址,并且允许托管的 C# 代码跳转至此。当然,这个方法是安全关键的,必须由我们的漏洞所调用,但是这是我们的调用任意原生代码的途径。在这个时候,通过对 Mono 几个月的学习,我已经相当熟悉 CIL(C# 的字节码格式)。有一个字节码指令“calli”可以提供 Marshal.GetDelegateForFunctionPointer 的功能。据我所知,这个指令并没有在 Mono 的运行时库当中的其他任何地方用到,所以看来被索尼的审计人员忽略了。“calli”只能被 CoreCLR 安全模型中的安全关键函数使用,所以我们将其嵌入了自己的动态链接库当中,并且通过 PSM 漏洞来调用它。

反制 3:地址空间布局随机化(译注:ASLR)

因为 VitaInjector 和 UVLoader 依赖于内存中的函数(包括分配可执行内存的系统调用),索尼决定在“PSM 开发助手”1.08 当中将内存布局随机化。这一点,与以下的反制措施一起,使得 VitaInjection 的开发中断了一年(在它以 VitaDefiler 的名字复活之前)。解决它的办法理论上很简单,但是在实践中需要大量辛勤的工作。要应对 ASLR,我们首先用 C# 托管的代码在内存中找到一个已知函数的地址(例如 Environment.Exit),因为 Mono 知道内部调用的内存地址,并且我们可以通过 PSM 漏洞取得它。然后,使用之前的内存转储中找到的偏移量,我们可以定位加载器运行所需全部的函数。这个工作量非常大,因为一切都必须用 Mono 调试器命令来编写,而这完全没有参考文档。

反制 4:NID 投毒

UVLoader 链接自制软件的 API 调用的办法是,在内存中找到已经加载的库的相同的 API 调用,并使用该信息定位正确的系统调用和函数地址。在 Vita 上,在传统的 ELF 里是找不到字符串“symbols(调试符号)“的。事实上,它用 4 字节整数作为导入的函数名称的散列值。在 Vita 2.06 固件中,索尼将全部的已经加载的库的系统调用 NID 导入表替换成了随机整数(并且在 3.x 固件中,扩展到了函数调用的导入表)。我将其称为“NID 投毒”,因为这使得导入表不再有用,而且我们无法再定位系统调用。一个解决办法是,在 UVLoader 内部“缓存”这些 NID。但是,因为库随着固件版本而变化,NID 顺序也随之改变,而且因为需要加载的库的数量很多,这使得 UVLoader 变得过于臃肿。UVLoader 1.0 现在改进了这一策略。它只缓存一个库的导入,SceLibKernel,这个库用来运行加载器本身。然后,当链接自制软件 ELF 的时候,UVLoader 使用一项由 Proxima 和我开发的技术,我将其称为“NID 解毒”(原因很明显)。库可以懒惰加载,意味着库会被载入内存但是不链接(因此 NID 导入表此时不会被投毒)。然后,当应用程序决定它需要使用这个共享库时,它将会使用另外一个系统调用来“开始”这个库,这就会执行链接和 NID 投毒。每个库都可以被加载多次,所以我们就可以查找已经开始的库,并且再次将其加载(但是不开始)。新加载的库的 API 调用没有被解析,但是 NID 也没有被投毒。这样,我们就可以将两个表合并,以取得 UVLoader 所需全部信息。

参考文献

如果你渴望了解这个漏洞工作的更多细节,我推荐你去看一看 VitaDefiler 的 USB.cs 源代码。我必须为糟糕的代码质量道歉,因为绝大多数都是在熬夜的时候写下的,而且我保留了诸如“Thread.Sleep(1500)”这样的代码,如果它能使某些功能运行起来。StartDump 是使用 PSM 漏洞转储内存的办法。DefeatASLR 展示了如何击败 ASLR 并获得重要函数的指针。EscalatePrivilege 是对 Mono 的补丁,使得所有已加载的映像都具备运行时库的权限。

============================

之前 Yifan Lu 已经放出风声,PS Vita 第一个原生系统的破解将需要 PlayStation Mobile 开发者证书才能安装到主机上。这条消息发布以后,PSM 开发者项目新增注册用户出现了上百倍的增长。

但是,作为一项即将在 5 月 31 日关闭注册的服务,索尼明显察觉到了其中的异常。由于 PSM 开发者证书是由人工审核的,在注册量爆发式增长之后,索尼实质上停止了新的开发者证书的发放。

现在事情出现了转机,Yifan Lu 宣布,PS Vita 原生系统破解不再需要 PSM 开发者证书,而只需要主机上安装有“PSM 开发助手(PlayStation Mobile Development Assistant)”软件即可。

要安装这个软件,只需要在 https://psm.playstation.net/portal/index.html,登录自己的 PSN 账号并自助注册,注册成功后“PSM 开发助手”就会出现在 PSN 下载列表当中,然后在主机上下载安装即可。

再次强调,PSM 开发者注册将于 2015 年 5 月 31 日关闭,请尽快下载安装“PSM 开发助手”软件。PS Vita 原生系统破解细节将在此后公布。

[ 本帖最后由 Boomer 于 2015-6-21 20:11 编辑 ]


本帖最近评分记录
  • jingly0 激骚 +6 好闪! 2015-5-28 23:35
  • riven 激骚 +1 恭喜发财 2015-5-26 20:00
  • pikachu 激骚 +5 感谢分享 2015-5-26 18:07

TOP

posted by wap, platform: 小米
3.51版泪奔,肯定破解不了了……



TOP

posted by wap, platform: Chrome
我也是3.51,不知道能不能破解。


TOP

posted by wap, platform: ZTE
PSV要诈尸了么? -_-||

TOP

posted by wap, platform: Chrome
三年之内没戏。

TOP

posted by wap, platform: SONY Xperia Z2
马克回家看看两年没充电了

TOP

posted by wap, platform: Firefox
算了,大法也挺可怜的,这次就饶了它吧。

TOP

mark下,回家试试

TOP

引用:
原帖由 darkccc 于 2015-5-26 11:47 发表
posted by wap, platform: 小米
3.51版泪奔,肯定破解不了了……
引用:
原帖由 田中健一 于 2015-5-26 11:49 发表
posted by wap, platform: Chrome
我也是3.51,不知道能不能破解。
破解的就是最新的 3.51 系统,马上抓紧时间下载安装

顺便说一下,为了这次的破解,我又买了台新的 PS Vita 主机,因为之前的主机得保住低版本固件用来玩 PSP 破解,而这次的漏洞是适用于最新固件的…

[ 本帖最后由 Boomer 于 2015-5-26 12:00 编辑 ]

TOP

posted by wap, platform: Galaxy Note III
我是3.5,为了玩天域篇升级的。

TOP

posted by wap, platform: iPhone
我感觉怎么可能会ban ID呢

TOP

马克

TOP

posted by wap, platform: 小米
引用:
原帖由 @Boomer  于 2015-5-26 11:57 发表
破解的就是最新的 3.51 系统,马上抓紧时间下载安装

顺便说一下,为了这次的破解,我又买了台新的 PS Vita 主机,因为之前的主机得保住低版本固件用来玩 PSP 破解,而这次的漏洞是适用于最新固件的…
多谢,哪个服也没啥关系的吧?

TOP

问题是 就算破了 还是没游戏...

TOP

引用:
原帖由 我是我的马甲 于 2015-5-26 11:58 发表
posted by wap, platform: Galaxy Note III
我是3.5,为了玩天域篇升级的。
现在最新固件 / 本次破解固件是 3.51,请尽快下载安装主帖提到的软件

TOP

发新话题
     
官方公众号及微博