Line 1:
Line 1:
This page lists publicly known vulnerabilities on the Wii U system.
This page lists publicly known vulnerabilities on the Wii U system.
+
+
==Hardware==
+
{| class="wikitable" border="1"
+
! Summary
+
! Description
+
! Successful exploitation result
+
! Fixed in hardware version
+
! Discovered by
+
|-
+
| HW_SPARE1 is not clear-only, even in [[WiiMode]]
+
| Much like on the Wii, the Wii U includes a register that can be cleared to unmap [[boot0]]. However, Nintendo forgot once again to make this register clear-only, which allows boot0 to be dumped, including in WiiMode.
+
| Dumping of boot0
+
| None
+
| [[User:marcan|marcan]]
+
|-
+
| eFuse readout counter is not reset with NRST (de_Fuse)
+
| In order to accommodate eFuse-based JTAG lockout (and due to other considerations), eFuse bits must be buffered into a register file immediately following NRST, before the internal reset can be released. The eFuse sense state machine latches at a rate of 4 bits per cycle, directly off the 27MHz XTALCLK. Every other rising edge, a byte is written into the register file, starting from the least significant byte of the current u32.
+
+
An internal counter is used to keep track of the remaining bytes to be read into the register file. While the eFuse register file is reset to zero with NRST, the internal counter is not: By asserting NRST after N bytes have been read, only 0x400-N bytes will be read on the subsequent boot.
+
+
By asserting NRST just before the final byte has been read (1830 cycles), all eFuses will read entirely zero, including the JTAG lockout fuse. This allows trivial, unsigned and unencrypted boot1 execution, with no SEEPROM anti-rollback.
+
+
Additionally, because SRAM is not cleared on reboot, and because boot1 verifies over the encrypted payload, the boot1 key can be extracted. By asserting NRST after 176 cycles and walking the delay width down cycle-by-cycle, code execution can be used to gather 16 failed decryptions of boot1: A zerokey-decrypted boot1, and 15 others with one more byte present in its boot1 key than the last. This allows a straightforward bruteforce of the boot1 key.
+
| Trivial arbitrary code execution as boot1;
+
boot1 AES key extraction;
+
Recovery of SEEPROM-bricked Wii Us
+
| None
+
| [[User:shinyquagsire23|shinyquagsire23]]
+
|}
==boot0==
==boot0==
Line 27:
Line 56:
==boot1==
==boot1==
+
{| class="wikitable" border="1"
+
! Summary
+
! Description
+
! Successful exploitation result
+
! Fixed in system version
+
! Discovered by
+
|-
+
| boot1hax (unsafe "boot_info" pointer)
+
| boot1 communicates with IOS-MCP using the "boot_info" structure. A pointer to this structure is stored in the PRSH/PRST section in MEM2 which is given back to boot1 on a warmboot.
+
Due to this pointer not being validated by boot1, an attacker can craft a malicious PRSH/PRST section where the "boot_info" pointer will point to anywhere inside boot1's memory region and thus achieving a semi-arbitrary write.
+
| warmboot boot1 code execution
+
| None
+
| derrek, [[User:Plutoo|plutoo]], [[User:Naehrwert|naehrwert]], [[User:Yellows8|yellows8]], [[User:Shuffle2|shuffle2]] and [[User:Hexkyz|hexkyz]]
+
|-
+
| isfshax (stack overflow while processing ISFS superblock directory entries)
+
| Upon startup, boot1 loads and processes the latest SLC ISFS superblock. Directory entries are parsed using a recursive function without any limitation on recursion depth. A carefully crafted superblock with a sufficient directory depth can be used to overwrite memory preceding the boot1 stack and eventually gain arbitrary code execution. For example, it is possible to redirect FLA's FS device structure pointer to the superblock area, allowing an attacker to point structure's functions to a controlled memory location.
+
| coldboot boot1 code execution
+
| None
+
| [[User:Rw-r-r_0644|rw-r-r-0644]]
+
|}
==ARM software (IOSU)==
==ARM software (IOSU)==
Line 37:
Line 86:
! Fixed in system version
! Fixed in system version
! Discovered by
! Discovered by
+
|-
+
| ioctlvhax (ioctlv TOCTOU)
+
| This flaw technically is in the kernel, but it can be used to exploit a userland module.
+
It allows changing an ioctlv vector buffer address entry after it has been validated by the kernel. Any module not checking the number of ioctlv vectors is vulnerable. More information [https://nwert.wordpress.com/2016/05/03/ioctlvhax/ here].
+
| ROP under several IOSU modules
+
| 5.2.0
+
| [[User:Naehrwert|naehrwert]] and [[User:Plutoo|plutoo]]
|-
|-
| Bad memset in IOS_CreateThread syscall
| Bad memset in IOS_CreateThread syscall
Line 58:
Line 114:
| [[User:Plutoo|plutoo]] (on September 11th, 2015);
| [[User:Plutoo|plutoo]] (on September 11th, 2015);
Mrrraou (independently, on October 31th, 2016)
Mrrraou (independently, on October 31th, 2016)
+
|-
+
| IOS_CreateMessageQueue poor address range validation
+
| IOS_CreateMessageQueue() syscall does not check the number of entries, allowing for an integer overflow that will bypass the address range validation. Using IOS_SendMessage(), one can overwrite IOSU kernel and achieve code execution. see [https://www.youtube.com/watch?v=8C5cn_Qj0G8 here] and [https://github.com/Rambo6Glaz/iosu_mq_exploit/blob/master/source/main.c here] for impl.
+
| ARM kernel code execution
+
| None
+
| [[User:derrek|derrek]], [[User:nedwill|nedwill]] and [[User:naehrwert|naehrwert]] ?
|}
|}
Line 67:
Line 129:
! Fixed in system version
! Fixed in system version
! Discovered by
! Discovered by
−
|-
−
| ioctlvhax (ioctlv TOCTOU)
−
| This flaw technically is in the kernel, but it can be used to exploit a userland module.
−
It allows changing an ioctlv vector buffer address entry after it has been validated by the kernel. Any module not checking the number of ioctlv vectors is vulnerable. More information [https://nwert.wordpress.com/2016/05/03/ioctlvhax/ here].
−
| ROP under several IOSU modules
−
| 5.2.0
−
| [[User:Naehrwert|naehrwert]] and [[User:Plutoo|plutoo]]
|-
|-
| uhshax (/dev/uhs/0 bad array index check)
| uhshax (/dev/uhs/0 bad array index check)
Line 91:
Line 146:
| None
| None
| [[User:Hykem|Hykem]]
| [[User:Hykem|Hykem]]
+
|-
+
| Stack buffer overflow for received HID reports (BluuBomb)
+
| The Wii U doesn't check the size of received HID reports in IOS-PAD. By emulating a Wii Remote an attacker can send reports larger than 58 bytes and overflow a buffer on the stack.
+
More information [https://github.com/GaryOderNichts/bluubomb/blob/master/WRITEUP.md here].
+
| ROP under IOS-PAD
+
| None
+
| [[User:GaryOderNichts|GaryOderNichts]], [[User:Yellows8|yellows8]] (independently: January 2021)
+
|-
+
| Double fetch during USB configuration parsing causing out of bounds byteswap
+
| The Wii U doesn't verify that the total length of the USB configuration descriptor matches the total length used to determine the buffer size. This allows placing endpoint descriptors outside of the allocated buffer which will be swapped.
+
| Out of bounds byteswap in IOS-USB heap. Can lead to ROP, see [https://garyodernichts.blogspot.com/2022/06/exploiting-wii-us-usb-descriptor-parsing.html this post].
+
| None
+
| [[User:GaryOderNichts|GaryOderNichts]]
+
|-
+
| Heap buffer overflow in DNS response processing
+
| IOS-NET uses a modified version of NicheStack which is affected by [https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-25928 CVE-2020-25928]. Unlike described by the CVE, the IOS-NET implementation has an additional check for DNS PTR answers, which ensures the data isn't copied past the end of the buffer.
+
For additional PTR records pointing at the first answer name <code>dnc_set_answer</code> is still called without checking the response data length field though.
+
| Out-of-bounds heap write. Can lead to ROP, see [https://garyodernichts.blogspot.com/2023/10/exploiting-dns-response-parsing-on-wii-u.html this post].
+
| None
+
| [[User:GaryOderNichts|GaryOderNichts]]
+
|}
+
+
== Espresso Boot ROM ==
+
{| class="wikitable" border="1"
+
! Summary
+
! Description
+
! Successful exploitation result
+
! Fixed in system version
+
! Discovered by
+
|-
+
| Binary is not reverified before launching
+
| The [[Espresso boot ROM]] does not check for modifications to the binary in main memory before launching it. By changing the first instruction from the [[Hardware/Starbuck|Starbuck]], the [[Espresso]] can be sent anywhere.
+
| Arbitrary Espresso code booting
+
| Unknown
+
| marcan
+
|-
+
| Reset vector is not always locked in L2 cache
+
| The Espresso Boot ROM keeps an infinite loop at the reset vector to prevent unexpected code from executing. Most of the time, this is in the L2 cache, which prevents the Starbuck from overwriting it. Toward the end, it is no longer in the cache, so a custom jump can be done, before ROM access is disabled.
+
| Espresso Boot ROM can be dumped
+
| Unknown
+
| marcan
+
|-
+
| [[WiiMode]] flag is not set here
+
| In WiiMode, the [[ancast image|ancast images]] themselves are responsible for lowering the clock speed. If one of the above hacks is used to take control, it becomes possible to execute code in full [[Espresso]] mode.
+
| WiiUMode privileges within the Espresso
+
| Unknown
+
| marcan
|}
|}
Line 146:
Line 248:
| [[5.5.2]]
| [[5.5.2]]
| [[User:Yellows8|yellows8]]
| [[User:Yellows8|yellows8]]
+
|-
+
| Image input use-after-free
+
| Use-after-free in <input type="image"> tags, see [https://bugs.chromium.org/p/chromium/issues/detail?id=240124 here]
+
| ROP under the Internet Browser application
+
| None
+
| [https://github.com/JumpCallPop JumpCallPop]
|-
|-
| contenthax
| contenthax
Line 155:
Line 263:
| [[User:Yellows8|yellows8]], [[User:Smea|smea]] (Early 2016);
| [[User:Yellows8|yellows8]], [[User:Smea|smea]] (Early 2016);
[[User:WulfyStylez |WulfyStylez]] (Early 2016)
[[User:WulfyStylez |WulfyStylez]] (Early 2016)
+
|-
+
+
| contenthax2 (FailST)
+
| Each title has a File System Table (FST) that describes the filesystem. However, its integrity is not checked at runtime by the Wii U. Once the title is installed and has at least one section with hash mode 2 (no runtime checks) all file entries can modified to point to this section and thus bypass runtime file integrity checks of this title. This can be easily used as a secondary entrypoint by replacing the titles binary, leading to arbitrary code execution. By modifying the cos.xml the application can also run with full permissions, allowing for example JIT or SD Card access. A detailed write up can be found [https://maschell.github.io/homebrew/2020/12/02/failst.html here]
+
| Arbitrary title content modification
+
| None
+
| [[User:Maschell|Maschell]] (April 2020)
|-
|-
| haxchi (variation of contenthax)
| haxchi (variation of contenthax)
Line 171:
Line 286:
The .ini loading occurs much earlier during title boot than the font loading. These vulnerabilities (or at least the .ini one) trigger while the system is still displaying the application splash-screen(from the title's meta/ directory).
The .ini loading occurs much earlier during title boot than the font loading. These vulnerabilities (or at least the .ini one) trigger while the system is still displaying the application splash-screen(from the title's meta/ directory).
−
* Stack buffer overflow when handling BMFont "pages". The entire block is copied to stack using just the size, without checking the size. The loaded data is not checked either, other than converting uppercase to lowercase('A'..'Z' to 'a'..'z'). This string is used with sprintf + PNG texture loading afterwards.
+
* Stack buffer overflow when handling BMFont "pages". The entire block is copied to stack using just the size, without checking the size. The loaded data is not checked either, other than converting uppercase to lowercase('A'..'Z' to 'a'..'z'). This string is used with sprintf + PNG texture loading afterwards. see [https://github.com/Rambo6Glaz/vesselhax here]
* Heap buffer overflow during .ini parsing with field-data string starting with '"'. The allocated heap buffer is 0x100-bytes, but the size is not checked when copying the value string into this buffer. During copying/etc this string content is not checked/modified, besides checking for the end of the string with '"'. For example: HAX = "LONGSTRINGHERE"
* Heap buffer overflow during .ini parsing with field-data string starting with '"'. The allocated heap buffer is 0x100-bytes, but the size is not checked when copying the value string into this buffer. During copying/etc this string content is not checked/modified, besides checking for the end of the string with '"'. For example: HAX = "LONGSTRINGHERE"
| ROP under the Wii U N64 virtual console emulator title
| ROP under the Wii U N64 virtual console emulator title
| None
| None
| [[User:Yellows8|yellows8]] (Early 2016)
| [[User:Yellows8|yellows8]] (Early 2016)
+
|-
+
| ROBChain (variation of contenthax)
+
| Super Smash Brothers for Wii U is vulnerable to contenthax attacks via a crafted moveset file that causes a buffer overflow from the moveset's stack buffer into the stored write index of said stack allowing for a contiguous relative read/write which can be used for an address leak to translate it into an arbitrary read/write. A proof of concept and write up can be found [https://github.com/jam1garner/ROBChain here].
+
| ROP under Super Smash Brothers for Wii U
+
| None
+
| [[User:Jam1garner|jam1garner]]
+
|-
+
| DKCTF-Save-Exploit
+
| Donkey Kong Country Tropical Freeze is vulnerable to a save exploit based around a crafted game save. The vulnerability is located in how achievemets are stored. The save contains a count for the number of items to read into a set length buffer located on the stack. Increasing this count past the length of this buffer writes directly to stack which can be used to immediately gain ROP. Proof of concept can be found [https://github.com/Kinnay/DKCTF-Save-Exploit Here]
+
| ROP under Donkey Kong Country Tropical Freeze
+
| None
+
| [[User:Kinnay|Kinnay]]
|}
|}