Editing Vulnerabilities
Jump to navigation
Jump to search
The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.
Latest revision | Your text | ||
Line 173: | Line 173: | ||
* JIT enabled allowing to write a kernel exploit in C versus writing in assembly and JavaScript since around FW 2.00 | * JIT enabled allowing to write a kernel exploit in C versus writing in assembly and JavaScript since around FW 2.00 | ||
=== FW <= 10.71 - BD-JB2 - Path traversal sandbox escape by TheFloW === | === FW <=10.71 - BD-JB2 - Path traversal sandbox escape by TheFloW === | ||
==== Credits ==== | ==== Credits ==== | ||
Line 191: | Line 191: | ||
'''No''' as of PS4 FW 10.71 (maybe patched on PS4 FW 11.00). '''Yes''' on PS5 FW 8.00. | '''No''' as of PS4 FW 10.71 (maybe patched on PS4 FW 11.00). '''Yes''' on PS5 FW 8.00. | ||
=== FW <= 9.00 - BD-JB - Five vulnerabilities chained by TheFloW === | === FW <=9.00 - BD-JB - Five vulnerabilities chained by TheFloW === | ||
==== Credits ==== | ==== Credits ==== | ||
Line 230: | Line 230: | ||
== Usermode Exploits (WebKit) == | == Usermode Exploits (WebKit) == | ||
=== FW 6.00-9.60 - FrameLoader::loadInSameDocument UaF (CVE-2022-22620) leading to arbitrary RW === | |||
=== FW 6.00-9.60 - FrameLoader::loadInSameDocument | |||
==== Credits ==== | ==== Credits ==== | ||
* Sergei Glazunov, Google Project Zero, for reporting the bug in 2013-01 and answering Maddie Stone's questions in 2022 (2013) | * Sergei Glazunov, Google Project Zero, for reporting the bug in 2013-01 and answering Maddie Stone's questions in 2022 (2013) | ||
* Maddie Stone, Google Project Zero, for sharing a write-up describing this vulnerability (2022-06-14) | * Maddie Stone, Google Project Zero, for sharing a write-up describing this vulnerability (2022-06-14) | ||
* Anonymous for making an OOM PoC for webkit-gtk, PS4 and PS5 (2023-10-03) then making an arbitrary RW PoC | * Anonymous for making an OOM PoC for webkit-gtk, PS4 and PS5 (2023-10-03) then making an arbitrary RW PoC for webkit-gtk, PS4 7.00-9.60 and PS5 1.00-5.10 (2023-10-24) | ||
* CelesteBlue for testing and porting anonymous' | * CelesteBlue for testing and porting anonymous' PoC to firmwares 6.00-9.60. | ||
==== Analysis ==== | ==== Analysis ==== | ||
Line 269: | Line 246: | ||
==== Bug Description ==== | ==== Bug Description ==== | ||
The History API allows access to (and modification of) a stack of the pages visited in the current frame, and these page states are stored as a | The History API allows access to (and modification of) a stack of the pages visited in the current frame, and these page states are stored as a SerializedScriptValue. The History API exposes a getter for state, and a method replaceState which allows overwriting the "most recent" history entry. | ||
The bug is that | The bug is that FrameLoader::loadInSameDocument takes the state as an argument (stateObject), but does not increase its reference count. Only a HistoryItem object holds a reference to the stateObject. loadInSameDocument can trigger a callback into user JavaScript through the onblur event. The user's callback can call replaceState to replace the HistoryItem's state with a new object, therefore dropping the only reference to the stateObject. When the callback returns, loadInSameDocument will still use this free'd object in its call to statePopped, leading to the use-after-free. | ||
When | When loadInSameDocument is called it changes the focus to the element its scrolling to. If we set the focus on a different element prior to loadInSameDocument running, the blur event will be fired on that element. Then we can free the stateObject by calling replaceState in the onblur event handler. | ||
The bug is triggered by <code>history.back()</code> with the target state whose URL contains a hash | The bug is related to the web browser History API and is triggered by <code>history.back()</code> with the target state whose URL contains a hash: | ||
<source lang="js"> | <source lang="js"> | ||
history.pushState("state1", "", location + "#foo"); // URL with a hash | |||
// ... | |||
history.back(); // triggers loadInSameDocument() | |||
</source> | |||
The user may then trigger a double free and escalate it into an arbitrary read primitive. The exploit proceeds similarly to the buildBubbleTree() UaF exploit except the arbitrary decrement primitive is achieved from manipulating ~SerializedScriptValue(). | |||
A way to know if the system is vulnerable is the appearance of the input HTML element in the PoC page. If the HTML input field stays focused (blue outline) after the second timeout, then the vulnerability is not present. Note that Maddie Stone's PoC will never trigger any sort of crash on release builds as it was meant for builds with memory sanitation that can detect UaFs. | |||
By default, arguments to functions should be reference-counted. Raw pointers should only be used in rare exceptions. | |||
The bug was killed in 2013 and re-introduced in 2016. It seems that this likely occured due to the large issues affecting most software dev teams: legacy code, short reviewer turn-around expectations, refactoring and security efforts are generally under-appreciated and under-rewarded, and lack of memory safety mitigations. Steps towards any of these would likely make a difference. | |||
The | |||
The | The two commits that reverted the 2013 fix were very, very large commits: 40 and 94 files changed. While some large commits may include exclusively no-ops, these commits included many changes affecting lifetime semantics. This seems like it would make it very difficult for any developer or reviewer to be able to truly audit and understand the security impacts of all the changes being made. | ||
This bug was actually reported and initially fixed in 2013. In 2016 the fix was regressed during (it seems) refactoring. It seems reasonable that the vulnerability could have been found through watching the commits and seeing the initial fix from 2013 reverted in 2016, code auditing, or fuzzing. Fuzzing seems slightly less likely due to needing to support "navigation" which many fuzzers explicitly try to exclude. | |||
==== Exploit Implementation ==== | ==== Exploit Implementation ==== | ||
Line 314: | Line 274: | ||
* [https://github.com/springsec/CVE-2022-22620/blob/main/CVE-2022-22620_infoleak_exploit.html Information leak PoC for webkit-gtk by springsec] | * [https://github.com/springsec/CVE-2022-22620/blob/main/CVE-2022-22620_infoleak_exploit.html Information leak PoC for webkit-gtk by springsec] | ||
* [https://discord.com OOM PoC for PS4 and PS5 by anonymous on ps4-dev discord (to mirror)] | * [https://discord.com OOM PoC for PS4 and PS5 by anonymous on ps4-dev discord (to mirror)] | ||
* [https://discord.com Arbitrary RW PoC | * [https://discord.com Arbitrary RW PoC for PS4 7.00-9.60 and PS5 1.00-5.10 by anonymous on ps4-dev discord (to mirror)] | ||
==== Patched ==== | ==== Patched ==== | ||
'''Yes''' on PS4 FW 10.00 and PS5 FW 6.00. | '''Yes''' on PS4 FW 10.00 and '''Probably''' on PS5 FW 6.00. | ||
The patch changes the stateObject argument to loadInSameDocument from a raw pointer, SerializedScriptValue*, to a reference-counted pointer, RefPtr<SerializedScriptValue>, so that loadInSameDocument now increments the reference count on the object. | The patch changes the stateObject argument to loadInSameDocument from a raw pointer, SerializedScriptValue*, to a reference-counted pointer, RefPtr<SerializedScriptValue>, so that loadInSameDocument now increments the reference count on the object. | ||
Tested working on PS4 FWs 6.00-9.60 and PS5 FWs 1.00-5. | Tested working on PS4 FWs 6.00-9.60 and PS5 FWs 1.00-5.10. PS4 FWs <=5.56 seems invulnerable as the HTML input field stays focused (blue outline) after second timeout whilst it should not if the console were exploitable. PS4 FWs 6.00-6.72 pass the OOM PoC but "fail string leak" in the arbitrary RW PoC. | ||
=== FW 9.00-9.04 - WebCore::CSSFontFaceSet vulnerabilities leading to arbitrary RW === | === FW 9.00-9.04 - WebCore::CSSFontFaceSet vulnerabilities leading to arbitrary RW === | ||
Line 604: | Line 564: | ||
==== Tested ==== | ==== Tested ==== | ||
Works on 3.15-4.07. Not working on <= 3.11. | Works on 3.15-4.07. Not working on <=3.11. | ||
---- | ---- | ||
Line 768: | Line 728: | ||
* Between 1.76 and 4.05, Sony did that to prevent webkit exploiters from defeating usermode ASLR easily. | * Between 1.76 and 4.05, Sony did that to prevent webkit exploiters from defeating usermode ASLR easily. | ||
* Now we have to dump entire usermode sandboxed memory, and by studying it we can defeat ASLR: | * Now we have to dump entire usermode sandboxed memory, and by studying it we can defeat ASLR: | ||
1. Chose a function (ex: __stack_chk_fail) imported from | 1. Chose a function (ex: __stack_chk_fail) imported from LibKernel by SceWebkit2 | ||
2. Read pointer contained at the address where the call is done | 2. Read pointer contained at the address where the call is done | ||
3. Substract to this pointer the offset of the function (ex: __stack_chk_fail) in LibKernel module | 3. Substract to this pointer the offset of the function (ex: __stack_chk_fail) in LibKernel module | ||
4. This result is LibKernel base address. This method works for any imported module. | 4. This result is LibKernel base address. This method works for any imported module. | ||
=== DEP / NX === | === DEP / NX === | ||
Line 784: | Line 739: | ||
=== JiT removed from webbrowser === | === JiT removed from webbrowser === | ||
* On FW <= 1.76, you could map RWX memory from ROP by abusing the JiT functionality and the sys_jitshm_create and sys_jitshm_alias system calls. This however was fixed after 1.76, as WebKit has been split into two processes. One handles javascript compilation and the other handles other web page elements like image rendering and DOM. The second process will request JiT memory upon hitting JavaScript via IPC (Inter-Process Communication). Since we no longer have access to the process responsible for JiT, we can no longer (at least currently), map RWX memory for proper code execution unless the kernel is patched. | * On FW <= 1.76, you could map RWX memory from ROP by abusing the JiT functionality and the sys_jitshm_create and sys_jitshm_alias system calls. This however was fixed after 1.76, as WebKit has been split into two processes. One handles javascript compilation and the other handles other web page elements like image rendering and DOM. The second process will request JiT memory upon hitting JavaScript via IPC (Inter-Process Communication). Since we no longer have access to the process responsible for JiT, we can no longer (at least currently), map RWX memory for proper code execution unless the kernel is patched. | ||
* Workaround is to use ROP. | * Workaround is to use ROP. | ||
Line 808: | Line 762: | ||
* Around 6.50-6.70, device access got blocked or removed. Now you can no longer access devices from webbrowser | * Around 6.50-6.70, device access got blocked or removed. Now you can no longer access devices from webbrowser | ||
== Kernel Exploits == | == Kernel Exploits == | ||
=== FW <= 9.00 - PPPoE driver remote buffer overflow (CVE-2022-29867) === | === FW <= 9.00 - PPPoE driver remote buffer overflow (CVE-2022-29867) === | ||
Line 957: | Line 879: | ||
==== Patched ==== | ==== Patched ==== | ||
'''Yes''' in PS4 9.03 FW and PS5 4.50 FW | '''Yes''' in PS4 9.03 FW and PS5 4.50 FW. | ||
---- | ---- | ||
Line 1,123: | Line 1,045: | ||
==== Tested ==== | ==== Tested ==== | ||
Works on FWs 4.00-4.05. On <= 3.70 FW we have not found a way to leak the target object, but it might be doable as Fail0verflow did it on 1.01. | Works on FWs 4.00-4.05. On <=3.70 FW we have not found a way to leak the target object, but it might be doable as Fail0verflow did it on 1.01. | ||
---- | ---- | ||