Vulnerabilities: Difference between revisions
CelesteBlue (talk | contribs) (Replaced content with "See [https://wiki.henkaku.xyz/vita/Vulnerabilities].") Tag: Replaced |
No edit summary |
||
(5 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
== Userland == | |||
=== WebKit 531 (Vita FW BEFORE 2.00) === | |||
There are two exploits used for WebKit prior to 2.00. One is a data leakage exploit CVE-2010-4577 <ref>https://code.google.com/p/chromium/issues/detail?id=63866</ref> using type confusion to treat a double as a string memory address and length. The other is a type confusion exploit CVE-2010-1807 on the parseFloat() function using a Nan as the arg. | |||
<ref>http://imthezuk.blogspot.com/2010/11/float-parsing-use-after-free.html</ref> | |||
=== WebKit 536 (Vita FW 2.00 thru 3.18) (CVE-2012-3748) (2013-09-03-1)=== | |||
The heap memory buffer overflow vulnerability exists within the WebKit's JavaScriptCore JSArray::sort(...) method. This method accepts the user-defined JavaScript function and calls it from the native code to compare array items. If this compare function reduces array length, then the trailing array items will be written outside the "m_storage->m_vector[]" buffer, which leads to the heap memory corruption.<ref>http://packetstormsecurity.com/files/123088/</ref> | |||
=== WebKit 537.73 (as used in Vita FW 3.30-3.36) (CVE-2014-1303) === | |||
The CSSSelectorList can be mutated after it's allocated. If the mutated list contains less entries than the original one, a restrictive 1-bit OOB write can be achieved. | |||
<ref>https://www.blackhat.com/docs/eu-14/materials/eu-14-Chen-WebKit-Everywhere-Secure-Or-Not.PDF</ref> | |||
<ref>https://www.blackhat.com/docs/eu-14/materials/eu-14-Chen-WebKit-Everywhere-Secure-Or-Not-WP.pdf</ref> | |||
<ref>https://cansecwest.com/slides/2015/Liang_CanSecWest2015.pdf</ref> | |||
=== WebKit 537.73 (as used in Vita FW 3.50-3.60) (unknown or no CVE) === | |||
The JSArray::sort method has a heap use-after-free vulnerability. If an array containing an object with a custom toString method is sorted, and the toString method causes the array to be reallocated, then the sorted elements will be written to the old freed address. | |||
https://blog.xyz.is/2016/webkit-360.html | |||
=== PSM Mono privilege escalation === | |||
https://yifan.lu/2015/06/21/hacking-the-ps-vita/ | |||
=== PSM Unity privilege escalation === | |||
UnityEngine.dll is a trusted assembly (SecurityCritical) and is not signed (can be modified). However, the actual file at <code>ux0:app/PCSI00009/managed/UnityEngine.dll</code> is [[PFS]] signed and encrypted, making this (and any) resource based hacks just as difficult as unsigned code execution hacks (which is the original goal). | |||
=== PSM NetworkRequest privilege escalation === | |||
NetworkRequest.BeginGetResponse(AsyncCallback callback) invokes callback with <code>SecurityCritical</code> allowing for a privilege escalation. Unfortunately, Sony closed down the scoreboards feature <ref>http://community.eu.playstation.com/t5/Announcements-Events/PSM-scoreboard-service-is-closing/td-p/21263959</ref> which means that Network.AuthGetTicket() fails and Network.CreateRequest() cannot be invoked. There is no other way of creating a NetworkRequest object. | |||
<source lang="csharp"> | |||
using System; | |||
using System.Security; | |||
using System.Runtime.InteropServices; | |||
using Sce.PlayStation.Core.Services; | |||
namespace NetHax | |||
{ | |||
public class AppMain | |||
{ | |||
[SecurityCritical] | |||
public static void Escalate (IAsyncResult result) | |||
{ | |||
Console.WriteLine("Should be SecurityCritical"); | |||
IntPtr ptr = Marshal.AllocHGlobal(1000); | |||
Console.WriteLine("Look at me allocating memory: 0x{0:X}", ptr); | |||
} | |||
public static void Main (string[] args) | |||
{ | |||
Network.Initialize("af1c0a1b-a7b8-4597-a022-eee91e6735d1"); | |||
Network.AuthGetTicket(); | |||
NetworkRequest req = Network.CreateRequest(NetworkRequestType.Get, "", ""); | |||
IAsyncResult result = req.BeginGetResponse(new AsyncCallback(Escalate)); | |||
while (!result.IsCompleted) | |||
{ | |||
Console.WriteLine("waiting..."); | |||
} | |||
Console.WriteLine("Completed!"); | |||
} | |||
} | |||
} | |||
</source> | |||
== System == | |||
== Kernel == | |||
=== Stack buffer overflow in sceSblDmac5EncDec === | |||
(16/09/2014) | |||
<pre> | |||
might have found one | |||
SceSblDmac5Mgr_sceSblDmac5EncDec | |||
reads in 0x18 bytes from first arg | |||
processes a little | |||
then | |||
ROM:005F711A MOV R1, R11 | |||
ROM:005F711C ADD R0, SP, #0x88+var_70 | |||
ROM:005F711E MOV.W R2, R10,LSR#3 | |||
ROM:005F7122 BLX _import_SceSblSsMgr_SceSysmemForDriver_sceKernelMemcpyUserToKernel | |||
R10 comes from orginal read in buffer+0x10 | |||
bad news is it got patched in 1.80 | |||
they also added a isShell check | |||
</pre> | |||
'''Consensus''': Confirmed exploitable before 1.80. YEAH! | |||
=== GcAuthMgr checks only KeyID > 0x8001 not >= 0x8001 !! === | |||
allows for a prototype keyset to be used, which is derived from bbmac 0x345 | |||
and skips the last step to derive using 0x348. thus instead the master key | |||
gc auth keys are derived using a constant that is obtainable.. | |||
<source> | |||
ret = bigmac_aes256_cmac_to_keyring(key_1,0x21,0x345); | |||
if (ret == 0) { | |||
memcpy(&enc_dec_buf,input,0x20); | |||
ret = bigmac_encrypt_aes128_using_keyslot(bigmac_temp,&enc_dec_buf,0x20,0x21); | |||
if (ret == 0) { | |||
memcpy(out,bigmac_temp,0x10); | |||
if (key_id == 1) { | |||
memcpy(&enc_dec_buf,out,0x10); | |||
ret = bigmac_aes128cbc_decrypt_to_keyslot(&enc_dec_buf,iv,0x24,0x348); | |||
if (ret == 0) { | |||
*key_id_to_use = 2; | |||
} | |||
} | |||
else { | |||
*key_id_to_use = 1; | |||
} | |||
} | |||
} | |||
return ret; | |||
</source> | |||
=== sceIoDevctl does not clear stack buffer === | |||
(24/11/2014) | |||
Call some interesting functions that interest you in a kernel context (call some damn syscalls) | |||
Then call devctl and get upto 0x3FF bytes of that stack! | |||
<source lang="c"> | |||
sceIoDevctl("sdstor0:", 5, "xmc-lp-ign-userext", 0x14, WINDOW_BASE+0x10, 0x3FF); | |||
store(RET, WINDOW_BASE+0x4); | |||
</source> | |||
Fixed in 3.61. | |||
=== Syscall handler doesn't check syscall number === | |||
(03/07/2015) A large syscall number passed in R12 can overflow syscall table and cause an arbitrary function pointer to be dereferenced and executed. | |||
This was patched in 1.61. | |||
=== Heap use-after-free in sceNetSyscallIoctl === | |||
(5/04/2016) sceNetSyscallIoctl is declared as <code>int sceNetSyscallIoctl(int s, unsigned flags, void *umem)</code>. When <code>memsz = (flags_ >> 16) & 0x1FFF</code> is in range (0x80; 0x1000], it will use SceNetPs custom malloc to allocate a buffer of that size on the heap. However, the second argument to malloc is 0, meaning that when not enough memory is available instead of returning NULL, it unlocks the global SceNetPs mutex and waits on a semaphore. Then, while malloc is waiting, another thread can free the socket sceNetSyscallIoctl is operating on, causing a use-after-free condition. | |||
When passed proper arguments, sceNetSyscallIoctl will execute a function from the socket's vtable at the end: | |||
<source> | |||
v13 = (*(int (__fastcall **)(int, signed int, unsigned int, char *))(*(_DWORD *)(socket + 24) + 28))( | |||
socket, | |||
11, | |||
flags_, | |||
mem_); | |||
</source> | |||
Fixed in 3.63. | |||
== Non-secure Kernel Loader == | |||
== Secure Kernel == | |||
=== SMC 0x12F does not validate arguments === | |||
(01/01/2017) SMC 0x12F (sceSblSmSchedGetStatusMonitorCall) takes two unchecked arguments: <code>sm_handle</code> and <code>shared_mem_index</code>. | |||
<code>sm_handle</code> is a pointer to TrustZone memory in the form of <code>(tz_addr >> 0x01)</code> and <code>shared_mem_index</code> is an integer value calculated as <code>((shared_mem_blk_addr - shared_mem_base_addr) / 0x80)</code>. | |||
By passing the right value as <code>sm_handle</code>, SMC 0x12F will read 0x08 bytes from <code>(tz_addr + 0x28)</code> and return them at <code>(shared_mem_base_addr + index * 0x80)</code> which translates to a TrustZone arbitrary memory leak (0x08 bytes only). | |||
By passing the right value as <code>shared_mem_index</code> it is also possible to write the leaked data into an arbitrary TrustZone memory region. | |||
The Non-secure Kernel sees the shared memory region at <code>0x00400000</code> (size is 0x5000 bytes) and the Secure Kernel sees the exact same memory region at <code>0x00560000</code>, thus making it possible to plant data inside the Non-secure Kernel's region and having the SMC copy this data somewhere into TrustZone memory (e.g.: SMC table). | |||
This results in TrustZone level arbitrary code execution. | |||
This was patched somewhere around 1.80. | |||
== Hardware == | |||
== F00D Processor == | |||
=== To be disclosed === | |||
(18/02/2017) To be disclosed. | |||
https://twitter.com/pomfpomfpomf3/status/832806488221446145 | |||
<pre> | |||
octopus exploit | |||
.---. ,, | |||
,, / \ ;,,' | |||
;, ; ( o o ) ; ; | |||
;,';,,, \ \/ / ,; ; | |||
,,, ;,,,,;;,` '-,;'''',,,' | |||
;,, ;,, ,,,, ,; ,,,'';;,,;'''; | |||
;,,,; ~~' '';,,''',,;'''' | |||
</pre> | |||
(I copied the octopus from an ASCII art page: http://ascii.co.uk/art/octopus) | |||
=== Disclosed by Yifan Lu === | |||
Yifan Lu has written an article on how to exploit the F00D processor on their personal blog (11/01/2019). | |||
https://yifan.lu/2019/01/11/the-first-f00d-exploit/ | |||
== References == |
Latest revision as of 01:42, 7 November 2024
Userland[edit | edit source]
WebKit 531 (Vita FW BEFORE 2.00)[edit | edit source]
There are two exploits used for WebKit prior to 2.00. One is a data leakage exploit CVE-2010-4577 [1] using type confusion to treat a double as a string memory address and length. The other is a type confusion exploit CVE-2010-1807 on the parseFloat() function using a Nan as the arg. [2]
WebKit 536 (Vita FW 2.00 thru 3.18) (CVE-2012-3748) (2013-09-03-1)[edit | edit source]
The heap memory buffer overflow vulnerability exists within the WebKit's JavaScriptCore JSArray::sort(...) method. This method accepts the user-defined JavaScript function and calls it from the native code to compare array items. If this compare function reduces array length, then the trailing array items will be written outside the "m_storage->m_vector[]" buffer, which leads to the heap memory corruption.[3]
WebKit 537.73 (as used in Vita FW 3.30-3.36) (CVE-2014-1303)[edit | edit source]
The CSSSelectorList can be mutated after it's allocated. If the mutated list contains less entries than the original one, a restrictive 1-bit OOB write can be achieved. [4] [5] [6]
WebKit 537.73 (as used in Vita FW 3.50-3.60) (unknown or no CVE)[edit | edit source]
The JSArray::sort method has a heap use-after-free vulnerability. If an array containing an object with a custom toString method is sorted, and the toString method causes the array to be reallocated, then the sorted elements will be written to the old freed address.
https://blog.xyz.is/2016/webkit-360.html
PSM Mono privilege escalation[edit | edit source]
https://yifan.lu/2015/06/21/hacking-the-ps-vita/
PSM Unity privilege escalation[edit | edit source]
UnityEngine.dll is a trusted assembly (SecurityCritical) and is not signed (can be modified). However, the actual file at ux0:app/PCSI00009/managed/UnityEngine.dll
is PFS signed and encrypted, making this (and any) resource based hacks just as difficult as unsigned code execution hacks (which is the original goal).
PSM NetworkRequest privilege escalation[edit | edit source]
NetworkRequest.BeginGetResponse(AsyncCallback callback) invokes callback with SecurityCritical
allowing for a privilege escalation. Unfortunately, Sony closed down the scoreboards feature [7] which means that Network.AuthGetTicket() fails and Network.CreateRequest() cannot be invoked. There is no other way of creating a NetworkRequest object.
using System;
using System.Security;
using System.Runtime.InteropServices;
using Sce.PlayStation.Core.Services;
namespace NetHax
{
public class AppMain
{
[SecurityCritical]
public static void Escalate (IAsyncResult result)
{
Console.WriteLine("Should be SecurityCritical");
IntPtr ptr = Marshal.AllocHGlobal(1000);
Console.WriteLine("Look at me allocating memory: 0x{0:X}", ptr);
}
public static void Main (string[] args)
{
Network.Initialize("af1c0a1b-a7b8-4597-a022-eee91e6735d1");
Network.AuthGetTicket();
NetworkRequest req = Network.CreateRequest(NetworkRequestType.Get, "", "");
IAsyncResult result = req.BeginGetResponse(new AsyncCallback(Escalate));
while (!result.IsCompleted)
{
Console.WriteLine("waiting...");
}
Console.WriteLine("Completed!");
}
}
}
System[edit | edit source]
Kernel[edit | edit source]
Stack buffer overflow in sceSblDmac5EncDec[edit | edit source]
(16/09/2014)
might have found one SceSblDmac5Mgr_sceSblDmac5EncDec reads in 0x18 bytes from first arg processes a little then ROM:005F711A MOV R1, R11 ROM:005F711C ADD R0, SP, #0x88+var_70 ROM:005F711E MOV.W R2, R10,LSR#3 ROM:005F7122 BLX _import_SceSblSsMgr_SceSysmemForDriver_sceKernelMemcpyUserToKernel R10 comes from orginal read in buffer+0x10 bad news is it got patched in 1.80 they also added a isShell check
Consensus: Confirmed exploitable before 1.80. YEAH!
GcAuthMgr checks only KeyID > 0x8001 not >= 0x8001 !![edit | edit source]
allows for a prototype keyset to be used, which is derived from bbmac 0x345 and skips the last step to derive using 0x348. thus instead the master key gc auth keys are derived using a constant that is obtainable..
ret = bigmac_aes256_cmac_to_keyring(key_1,0x21,0x345);
if (ret == 0) {
memcpy(&enc_dec_buf,input,0x20);
ret = bigmac_encrypt_aes128_using_keyslot(bigmac_temp,&enc_dec_buf,0x20,0x21);
if (ret == 0) {
memcpy(out,bigmac_temp,0x10);
if (key_id == 1) {
memcpy(&enc_dec_buf,out,0x10);
ret = bigmac_aes128cbc_decrypt_to_keyslot(&enc_dec_buf,iv,0x24,0x348);
if (ret == 0) {
*key_id_to_use = 2;
}
}
else {
*key_id_to_use = 1;
}
}
}
return ret;
sceIoDevctl does not clear stack buffer[edit | edit source]
(24/11/2014) Call some interesting functions that interest you in a kernel context (call some damn syscalls) Then call devctl and get upto 0x3FF bytes of that stack!
sceIoDevctl("sdstor0:", 5, "xmc-lp-ign-userext", 0x14, WINDOW_BASE+0x10, 0x3FF);
store(RET, WINDOW_BASE+0x4);
Fixed in 3.61.
Syscall handler doesn't check syscall number[edit | edit source]
(03/07/2015) A large syscall number passed in R12 can overflow syscall table and cause an arbitrary function pointer to be dereferenced and executed.
This was patched in 1.61.
Heap use-after-free in sceNetSyscallIoctl[edit | edit source]
(5/04/2016) sceNetSyscallIoctl is declared as int sceNetSyscallIoctl(int s, unsigned flags, void *umem)
. When memsz = (flags_ >> 16) & 0x1FFF
is in range (0x80; 0x1000], it will use SceNetPs custom malloc to allocate a buffer of that size on the heap. However, the second argument to malloc is 0, meaning that when not enough memory is available instead of returning NULL, it unlocks the global SceNetPs mutex and waits on a semaphore. Then, while malloc is waiting, another thread can free the socket sceNetSyscallIoctl is operating on, causing a use-after-free condition.
When passed proper arguments, sceNetSyscallIoctl will execute a function from the socket's vtable at the end:
v13 = (*(int (__fastcall **)(int, signed int, unsigned int, char *))(*(_DWORD *)(socket + 24) + 28))(
socket,
11,
flags_,
mem_);
Fixed in 3.63.
Non-secure Kernel Loader[edit | edit source]
Secure Kernel[edit | edit source]
SMC 0x12F does not validate arguments[edit | edit source]
(01/01/2017) SMC 0x12F (sceSblSmSchedGetStatusMonitorCall) takes two unchecked arguments: sm_handle
and shared_mem_index
.
sm_handle
is a pointer to TrustZone memory in the form of (tz_addr >> 0x01)
and shared_mem_index
is an integer value calculated as ((shared_mem_blk_addr - shared_mem_base_addr) / 0x80)
.
By passing the right value as sm_handle
, SMC 0x12F will read 0x08 bytes from (tz_addr + 0x28)
and return them at (shared_mem_base_addr + index * 0x80)
which translates to a TrustZone arbitrary memory leak (0x08 bytes only).
By passing the right value as shared_mem_index
it is also possible to write the leaked data into an arbitrary TrustZone memory region.
The Non-secure Kernel sees the shared memory region at 0x00400000
(size is 0x5000 bytes) and the Secure Kernel sees the exact same memory region at 0x00560000
, thus making it possible to plant data inside the Non-secure Kernel's region and having the SMC copy this data somewhere into TrustZone memory (e.g.: SMC table).
This results in TrustZone level arbitrary code execution.
This was patched somewhere around 1.80.
Hardware[edit | edit source]
F00D Processor[edit | edit source]
To be disclosed[edit | edit source]
(18/02/2017) To be disclosed.
https://twitter.com/pomfpomfpomf3/status/832806488221446145
octopus exploit .---. ,, ,, / \ ;,,' ;, ; ( o o ) ; ; ;,';,,, \ \/ / ,; ; ,,, ;,,,,;;,` '-,;'''',,,' ;,, ;,, ,,,, ,; ,,,'';;,,;'''; ;,,,; ~~' '';,,''',,;''''
(I copied the octopus from an ASCII art page: http://ascii.co.uk/art/octopus)
Disclosed by Yifan Lu[edit | edit source]
Yifan Lu has written an article on how to exploit the F00D processor on their personal blog (11/01/2019). https://yifan.lu/2019/01/11/the-first-f00d-exploit/
References[edit | edit source]
- ↑ https://code.google.com/p/chromium/issues/detail?id=63866
- ↑ http://imthezuk.blogspot.com/2010/11/float-parsing-use-after-free.html
- ↑ http://packetstormsecurity.com/files/123088/
- ↑ https://www.blackhat.com/docs/eu-14/materials/eu-14-Chen-WebKit-Everywhere-Secure-Or-Not.PDF
- ↑ https://www.blackhat.com/docs/eu-14/materials/eu-14-Chen-WebKit-Everywhere-Secure-Or-Not-WP.pdf
- ↑ https://cansecwest.com/slides/2015/Liang_CanSecWest2015.pdf
- ↑ http://community.eu.playstation.com/t5/Announcements-Events/PSM-scoreboard-service-is-closing/td-p/21263959