Summary Description Successful exploitation result Fixed in system-module system-version Last system-module system-version this flaw was checked for Timeframe this was discovered Timeframe this was added to wiki Discovered by

CECD:ndm SetNZoneMacFilter (cmd8) stack smashing The length of the mac filter is not checked before being copied to a fixed-size buffer on stack. ROP under CECD sysmodule None 11.13.0-45 2020 July 20, 2020 MrNbaYoh

CECD message box access CECD allows any process to write to any message box, thus allowing to write Streetpass data to the message box of any title. Install exploit for any title having a vulnerability in Streetpass data parsers (see CTRSDK Streetpass parser vulnerability). None None ? June 1, 2020 Everyone?

CECD packet type 0x32/0x34 stack-smashing When parsing Streetpass packets of type 0x32 and 0x34, CECD copies a list without checking the number of entries. The packet length is limited to 0x400 bytes, which is not enough to reach the end of the stack frame and overwrite the return address. However, the buffer located just next to the packet buffer is actually filled with data sent just before, hence actually allowing to overwrite the whole stack frame with conrolled data. RCE under CECD 11.12.0-44 11.12.0-44 Summer 2019 June 1, 2020 MrNbaYoh

CECD TMP files parser multiple vulnerabilities When parsing "TMP_XXX" files, CECD does not check the number of messages contained in the file. This allows to overflow the array of message pointers and message sizes on the stack. Pointers aren't controlled and sizes are limited (one cannot send gigabytes of data...), yet the last message size can be an arbitrary value (the current message pointer goes outside the file buffer and the parsing loop is broken). This allows to overwrite a pointer to a lock object on the stack and decrement an arbitrary value in memory. One can change the TMP file parsing mode to have CECD trying to free all the message buffers after parsing the next TMP file. The parsing mode is usually restored when parsing a new TMP file, but an invalid TMP file allows to make a function returns an error before the mode is restored , the return value is not checked and the parser consider the file valid. The message pointers and sizes arrays are not updated though, this is not a problem since the previous TMP file buffer is reused for the new TMP file in memory. Thus the message pointers actually points to controlled data. This allows to get a bunch of fake heap chunk freed, thus a bunch of unsafe unlink arbitrary writes. RCE under CECD 11.12.0-44 11.12.0-44 Summer 2019 June 1, 2020 MrNbaYoh

CFG:CreateConfigInfoBlk integer underflow When creating a new block it checks the size of the block is <= 0x8000, but it doesn't check that the block size is less than the remaining space. This induces an integer underflow (remaining_space-block_size), the result is then used for another check (buf_start+current_offset+constant <= remaining_space-block_size) and then in a mempcy call (dest = buf_start+(u16)(remaining_space-block_size), size =block_size). This allow for writing past the buffer, however because of the u16 cast in the memcpy call memory has to be mapped from buf_start to buf_start+0x10000 (cannot write backward). Theoritically ROP under CFG services, but BSS section is to small (size <= 0x10000) so it only results in a crash. None 11.8.0-41 November, 2018 November 24, 2018 MrNbaYoh

MP:SendDataFrame missing input array index validation MP:SendDataFrame doesn't validate the input index at cmdreq[1], unless the function for flag=non-zero is executed. This is used to calculate the following, without validating the index at all: someptr = stateptr + (index*0x924) + somestateoffset. After validating some flags from someptr, when input_flag=0 the input buffer data is copied to someptr+someotheroffset+0x14 with the u16 size loaded from someptr+someotheroffset. With a large input index someptr could be setup to be at a <target address>, for overwriting memory. This is probably difficult to exploit. None 8.0.0-18(MP-sysmodule v2048) January 22, 2017 January 22, 2017 Yellows8

MP cmd1 out-of-bounds handle read MP-sysmodule handles the input parameter for cmd1 as a s32. It checks for >=16, but not <0. With <16 it basically does the following(array of entries 4-bytes each): *outhandle = ((Handle*)(stateptr+offsetinstate))[inputindex]. Hence, this can be used to load any handle in MP-sysmodule memory. MP doesn't really have any service handles of interest however(can be obtained from elsewhere too). Reading any handle in MP-sysmodule memory. None 8.0.0-18(MP-sysmodule v2048) January 21, 2017 January 22, 2017 Yellows8

AM stack/.bss infoleak via AM:ReadTwlBackupInfo(Ex) After writing the output-info structure to stack, it then copies that structure to the output buffer ptr using the size from the command. The size is not checked. This could be used to read data from the AM-service-thread stack handling the command + .bss. This was not tested on hardware. Stack/.bss reading None 10.0.0-27(AM v9217) Roughly October 17, 2016 October 25, 2016 Yellows8

MVD: Stack buffer overflow with MVDSTD:SetupOutputBuffers. The input total_entries is not validated when initially processing the input entry-list. This fixed-size input entry-list is copied to stack from the command request. The loop for processing this initializes a global table, the converted linearmem->physaddrs used there are also copied to stack(0x8-bytes of physaddrs per entry). If total_entries is too large, MVD-sysmodule will crash due to reading unmapped memory following the stack(0x10000000). Afterwards if the out-of-bounds total_entries is smaller than that, it will crash due accessing address 0x0, hence this useless. MVD-sysmodule crash. None 9.0.0-20 April 22, 2016 (Tested on the 25th) April 25, 2016 Yellows8

NWM: Using CTRSDK heap with UDS sharedmem from the user-process. See the HTTP-sysmodule section below. CTRSDK heap is used with the sharedmem from NWMUDS:InitializeWithVersion. Buffers are allocated/freed under this heap using NWMUDS:Bind and NWMUDS:Unbind. Hence, overwriting sharedmem with gspwn then using NWMUDS:Unbind results in the usual controlled CTRSDK memchunk-header write, similar to HTTP-sysmodule. This could be done by creating an UDS network, without any other nodes on the network. Besides CTRSDK memchunk-headers, there are no addresses stored under this sharedmem. ROP under NWM-module. None (need to check, but CTRSDK heap code is vulnerable) 9.0.0-X April 10, 2016 April 16, 2016 Yellows8

DLP: Out-of-bounds memory access during spectator data-frame checksum calculation DLP doesn't validate the frame_size when receiving spectator data-frames at all, unlike non-spectator data-frames. The actual spectator data-frame parsing code doesn't use that field either. However, the data-frame checksum calculation code called during checksum verification does use the frame_size for loading the size of the framebuf. Hence, using a large frame_size like 0xFFFF will result in the checksum calculation code reading data out-of-bounds. This isn't really useful, you could trigger a remote local-WLAN DLP-sysmodule crash while a 3DS system is scanning for DLP networks(due to accessing unmapped memory), but that's about all(trying to infoleak with this likely isn't useful either). DLP-sysmodule crash, handled by dlplay system-application by a "connection interrupted" error eventually then a fatal-error via ErrDisp. None 10.0.0-X April 8, 2016 (Tested on the 10th) April 10, 2016 Yellows8

DLP: Out-of-bounds output data writing during spectator sysupdate titlelist data-frame handling The total_entries and out_entryindex fields for the titlelist DLP spectator data-frames are not validated. This is parsed during DLP network scanning. Hence, the specified titlelist data can be written out-of-bounds using the specified out_entryindex and total_entries. A crash will occur while reading the input data-frame titlelist if total_entries is larger than 0x27A, due to accessing unmapped memory. There's not much non-zero data to overwrite following the output buffer(located in sharedmem), any ptrs are located in sharedmem. Overwriting certain ptr(s) are only known to cause a crash when attempting to use the DLP-client shutdown service-command. There's no known way to exploit the above crash, since the linked-list code involves writes zeros(with a controlled start ptr). None 10.0.0-X April 8-9, 2016 April 10, 2016 Yellows8

IR: Stack buffer overflow with custom hardware Originally IR sysmodule used the read value from the I2C-IR registers TXLVL and RXLVL without validating them at all. See here for the fix. This is the size used for reading the data-recv FIFO, etc. The output buffer for reading is located on the stack. This should be exploitable if one could successfully setup the custom hardware for this and if the entire intended sizes actually get read from I2C. ROP under IR sysmodule. 10.6.0-31 February 23, 2016 (Unknown if it was noticed before then) February 23, 2016 Yellows8

HTTP: Using CTRSDK heap with sharedmem from the user-process. The data from httpcAddPostDataAscii and other commands is stored under a CTRSDK heap. That heap is the sharedmem specified by the user-process via the HTTPC Initialize command. Normally this sharedmem isn't accessible to the user-process once the sysmodule maps it, hence using it is supposed to be "safe". This isn't the case due to gspwn however. Since CTRSDK heap code is so insecure in general, one can use gspwn to locate the HTTPC sharedmem + read/write it, then trigger a mem-write under the sysmodule. This can then be used to get ROP going under HTTP-sysmodule. This is exploited by ctr-httpwn. ROP under HTTP sysmdule. None 11.13.0-X Late 2015 March 22, 2016 Yellows8

NIM: Downloading old title-versions from eShop Multiple NIM service commands(such as NIMS:StartDownload) use a title-version value specified by the user-process, NIM does not validate that this input version matches the latest version available via SOAP. Therefore, when combined with AM(PXI) title-downgrading via deleting the target eShop title with System Settings Data Management(if the title was already installed), this allows downloading+installing any title-version from eShop if it's still available from CDN. The easiest way to exploit this is to just patch the eShop system-application code using these NIM commands(ideally the code which loads the title-version). Originally this was tested with a debugging-system via modded-FIRM, eventually smea implemented it in HANS for the 32c3 release. Downloading old title-versions from eShop None 10.0.0-X October 24, 2015 (Unknown when exactly the first eShop title downgrade was actually tested, maybe November) January 7, 2016 (Same day Ironfall v1.0 was removed from CDN via the main-CXI files) Yellows8

SPI service out-of-bounds write cmd1 has out-of-bounds write allowing overwrite of some static variables in .data. None 9.5.0-22 March 2015 plutoo

NFC module service command buf-overflows NFC module copies data with certain commands, from command input buffers to stack without checking the size. These commands include the following, it's unknown if there's more commands with similar issues: "nfc:dev" <0x000C....> and "nfc:s" <0x0037....>. Since both of these commands are stubbed in the Old3DS NFC module from the very first version(those just return an error), these issues only affect the New3DS NFC module. There's no known retail titles which have access to either of these services. ROP under NFC module. New3DS: None New3DS: 9.5.0-22 December 2014? Yellows8

NEWSS service command notificationID validation failure This module does not validate the input notificationID for "news:s" service commands. This is an out-of-bounds array index bug. For example, NEWSS:SetNotificationHeader could be used to exploit news module: this copies the input data(size is properly checked) to: out = newsdb_savedata+0x10 + (someu32array[notificationID]*0x70). ROP under news module. None 9.7.0-X December 2014 Yellows8

NWMUDS:DecryptBeaconData heap buffer overflow input_size = 0x1E * <value the u8 from input_networkstruct+0x1D>. Then input_tag0 is copied to a heap buffer. When input_size is larger than 0xFA-bytes, it will then copy input_tag1 to <end_address_of_previous_outbuf>, with size=input_size-0xFA. This can be triggered by either using this command directly, or by boadcasting a wifi beacon which triggers it while a 3DS system running the target process is in range, when the process is scanning for hosts to connect to. Processes will only pass tag data to this command when the wlancommID and other thing(s) match the values for the process. There's no known way to actually exploit this for getting ROP under NWM-module, at the time of originally adding this to the wiki. This is because the data which gets copied out-of-bounds *and* actually causes crash(es), can't be controlled it seems(with just broadcasting a beacon at least). It's unknown whether this could be exploited from just using NWMUDS service-cmd(s) directly. Without any actual way to exploit this: NWM-module DoS, resulting in process termination(process crash). This breaks *everything* involving wifi comms, a reboot is required to recover from this. None 9.0.0-20 ~September 23, 2014(see the NWMUDS:DecryptBeaconData page history) August 3, 2015 Yellows8

HID module shared-mem HID module does not validate the index values in sharedmem(just changes index to 0 when index == maxval when updating), therefore large values will result in HID module writing HID data to arbitrary addresses. ROP under HID module, but this is *very* unlikely to be exploitable since the data written is HID data. None 9.3.0-21 2014? Yellows8

gspwn GSP module does not validate addresses given to the GPU. This allows a user-mode application/applet to read/write to a large part of physical FCRAM using GPU DMA. From this, you can overwrite the .text segment of the application you're running under, and gain real code-execution from a ROP-chain. Normally applets' .text(Home Menu, Internet Browser, etc) is located beyond the area accessible by the GPU, except for CROs used by applets(Internet Browser for example). FCRAM is gpu-accessible up to physaddr 0x26800000 on Old3DS, and 0x2D800000 on New3DS. This is BASE_memregion_start(aka SYSTEM_memregion_end)-0x400000 (0x800000 with New3DS) with the default memory-layout on Old3DS/New3DS. With 11.3.0-X the cutoff now varies due to the new SVC 0x59. The New3DS "normal"(non-APPLICATION) cutoff was changed to 0x2D000000 due to the new SVC 0x59. User-mode code execution. None 9.6.0-X Early 2014 smea, Yellows8/others before then

rohax Using gspwn, it is possible to overwrite a loaded CRO0/CRR0 after its RSA-signature has been validated. Badly validated CRO0 header leads to arbitrary read/write of memory in the ro-process. This gives code-execution in the ro module, who has access to syscalls 0x70-0x72, 0x7D. This was fixed after ninjhax release by adding checks on CRO0-based pointers before writing to them. Memory-mapping syscalls. 9.3.0-21 9.4.0-21 smea, plutoo joint effort

Region free Only Home Menu itself checks gamecards' region when launching them. Therefore, any application launch that is done directly with NS without signaling Home Menu to launch the app, will result in region checks being bypassed. This essentially means launching the gamecard with the "ns:s" service. The main way to exploit this is to trigger a FIRM launch with an application specified, either with a normal FIRM launch or a hardware reboot. Launching gamecards from any region + bypassing Home Menu gamecard-sysupdate installation None Last tested with 10.1.0-X. June(?) 2014 Yellows8