Skip to content

PabloMK7/ENLBufferPwn

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 

Repository files navigation

ENLBufferPwn (CVE-2022-47949)

CVE: CVE-2022-47949
CVSS v3.1: 9.8/10 (Critical)
Authors: PabloMK7, Rambo6Glaz, Fishguy6564
Reported: August 8th, 2021 (Mario Kart 7)
April 14th, 2022 (for the impacted WiiU and Switch games)
Disclosed: December 22nd, 2022

Table of contents

Description

ENLBufferPwn is a vulnerability in the common network code of several first party Nintendo games since the Nintendo 3DS that allows an attacker to execute code remotely in the victim's console by just having an online game with them (remote code execution). It was dicovered by multiple people independently during 2021 and reported to Nintendo during 2021 and 2022. Since the initial report, Nintendo has patched the vulnerability in many vulnerable games. The information in this repository has been safely disclosed after getting permission from Nintendo.

The vulnerability has scored a 9.8/10 (Critical) in the CVSS 3.1 calculator.

Here is a list of games that are known to have had the vulnerability at some point (all the Switch and 3DS games listed have received updates that patch the vulnerability, so they are no longer affected):

  • Mario Kart 7 (fixed in v1.2)
  • Mario Kart 8 (fixed in v4.2.0)
  • Mario Kart 8 Deluxe (fixed in v2.1.0)
  • Animal Crossing: New Horizons (fixed in v2.0.6)
  • ARMS (fixed in v5.4.1)
  • Splatoon (fixed in v2.12.1)
  • Splatoon 2 (fixed in v5.5.1)
  • Splatoon 3 (fixed in late 2022, exact version unknown)
  • Super Mario Maker 2 (fixed in v3.0.2)
  • Nintendo Switch Sports (fixed in late 2022, exact version unknown)
  • Probably more...

Vulnerability details

The ENLBufferPwn vulnerability exploits a buffer overflow in the C++ class NetworkBuffer present in the network library enl (Net in Mario Kart 7) used by many first party Nintendo games. This class contains two methods Add and Set which fill a network buffer with data coming from other players. However, none of those methods check that the input data actually fits in the network buffer. Since the input data is controllable, a buffer overflow can be triggered on a remote console by just having an online game session with the attacker. If done properly, the victim user may not even notice a vulnerability was triggered in their console. The consequences of this buffer overflow vary on the game, from simple inoffensive modifications to the game's memory (like repeatedly opening and closing the home menu on the 3DS) to more severe actions like taking full control of the console, as shown below.

The rest of the report will focus on Mario Kart 7, as due to the lack of security measures (ASLR, for example) of the 3DS, it is the most severe case of the vulnerability. However, it may be possible to bypass ASLR on Switch games by hijacking the NetworkBuffer used to send data back to the attacker (and making it leak pointers to the heap and code).

ENLBufferPwn in Mario Kart 7 (3DS)

The following video showcases a severe case of the vulnerability in Mario Kart 7, where a console controlled by an attacker (left side) fully takes over an unmodified console (right side). The only interaction done by the user is joining an online game session with the attacker, in this case, using the "communities" feature (note that a "community" was used to safely test the vulnerability in an isolated manner and not affect any other users playing in public lobbies). The takeover is done by copying a ROP payload to the remote console and then executing it. This ROP payload then uses other vulnerabilities in the OS to escalate privileges and get total control. In the video, the remote console is forced to run a CFW installer (SafeB9SInstaller). Using the same techniques, it would be theoretically possible to steal account/credit card information or take unauthorized audio/video recordings using the console built-in mic/cameras.

ENLBufferPwn - Mario Kart 7 Demonstration - Youtube

Technical details

As previously stated, the vulnerability comes from an oversight in two methods of the class NetworkBuffer. Here is an implementation of the class and methods in C++:

class NetworkBuffer
{
public:
    u8	bufferType;
    u8* dataPtr;
    u32 dataSize;
    u32 currentSize;

    void Set(u8* newData, u32 newDataSize);
    void Add(u8* newData, u32 newDataSize);
}

void NetworkBuffer::Set(u8* newData, u32 newDataSize)
{
    memcpy(this->dataPtr, newData, newDataSize);
    this->currentSize = newDataSize;
}

void NetworkBuffer::Add(u8* newData, u32 newDataSize)
{
    memcpy(this->dataPtr + this->currentSize, newData, newDataSize);
    this->currentSize += newDataSize;
}

As you can see, neither Set nor Add check that the incoming newDataSize fits in the buffer size (dataSize). Since this NetworkBuffer class is used as a generic container to interchange data between players online, the contents of newData and the value of newDataSize can be controlled by an attacker, and a buffer overflow can be performed.

Another detail of the network library is that it is asynchronous, so that games can be doing other operations while data is being filled up into the buffer. In order to accomplish this, a double buffer technique is used. This way, the game can access already received data in a NetworkBuffer at the same time as new data is being received. After the second NetworkBuffer is filled, the buffers are swapped and the cycle repeats.

For this PoC, the double NetworkBuffer used to receive Mii data (bufferType = 9) will be exploited . Due to the order of heap allocation, it just happens that the NetworkBuffer object and its contents are placed next to each other. Also, both buffers from the double buffer are contigous in memory. The following diagram represents how the memory looks after the buffer allocation:

Representation of the mii data double NetworBuffer in the game's heap

From now on, the buffer in the top of the image will be referenced as Buffer0, while the buffer in the bottom will be Buffer1. Using this knowledge, an attacker can trigger the buffer overflow in Buffer0 to overwrite the attributes of Buffer1, including its dataPtr member. Since 3DS games do not implement ASLR, all the memory locations in the remote console are known, so dataPtr can be pointed to an arbitrary location. Once the game swaps the buffer, the new data will be copied to the arbitrary location. Doing the following steps, a payload of any size can be copied to the remote console:

  1. Build a specially crafted payload and send it in Buffer0. It will trigger an overflow in the remote console overwriting dataPtr of Buffer1.
  2. Set the contents of Buffer1 with arbitrary data. It will be copied to the arbitrary address pointed by dataPtr of Buffer1 of the remote console.
  3. Increase the arbitrary address and size and start again from step 1.

Below is an animation of the normal operation of the game, followed by performing the steps described above.

Animation of the normal operation of the double buffers, followed by vulnerability operation

This repository contains a PoC that exploits this vulnerability to perform the following operations, depending on the compiler flags:

  • Send a 4 byte value that is written to the application status address of the remote console, forcing it to close and return to the home menu.
  • Send a ROP payload that is stored in the remote console memory. Once the ROP is sent, the stack is overwritten so that the game executes it (the ROP payload itself is not provided in the PoC).

Keep in mind that this PoC does not implement any kind of packet drop detection, as communications between consoles are done using UDP. To obtain the best results, packet drop handling should be implemented in the PoC code or the consoles should be placed in the same network to reduce the chances of packets dropping.

A possible fix of the vulnerable NetworkBuffer class is also provided.

ENLBufferPwn in Mario Kart 8

The vulnerability is also present on the WiiU and Switch version of Mario Kart 8, but only demonstrated for the WiiU release of the game.

Credits

While this vulnerability was discovered by multiple users independently, many of them decided to keep the vulnerability information private. However, the folowing people are responsible for safely disclosing the vulnerability to Nintendo:

License

CC0
To the extent possible under law, PabloMK7, Rambo6Glaz and Fishguy6564 have waived all copyright and related or neighboring rights to ENLBufferPwn. This work is published from: Spain.