HexBrain

Nintendo · Report #2611669

[Switch, PIA/MK8DX] Stack buffer overflow and potential RCE in PIA (LAN/LDN, possibly NEX) room info deserialization

Validstatus
mediumseverity
36upvotes
30 Sept 2024disclosed

Summary

Background Information

A vulnerability was discovered in Mario Kart 8 Deluxe's incorrect usage of the Pia P2P networking library, in which implementations of "CopyAppData" (See pseudocode below) are sometimes called with an outBufSize larger than the out buffer itself. This can potentially lead to user-mode remote code execution (RCE) on peers' consoles if chained with an info leak.

As of 2024/09/11, Nintendo has deployed a fix for this vulnerability alongside v3.0.3 for all regions, excluding China. As of 2024/09/27, v3.0.3 has now also been released for China.

A complete write-up is included here: https://github.com/latte-soft/kartlanpwn

Report Timeline

DateInfo
2024/07/18Report submitted to Nintendo via HackerOne
2024/07/31Report triaged internally
2024/09/11Fix released alongside Mario Kart 8 Deluxe v3.0.3 for all regions, excluding China
2024/09/12Bounty paid out by Nintendo
2024/09/12Other researchers quite quickly found out about the fix for "a security flaw in the game's netcode" in the bindiff for v3.0.3
2024/09/27Mario Kart 8 Deluxe v3.0.3 released for the Chinese region
2024/09/29Disclosure granted by Nintendo

LAN Protocol (Browse-Reply Packet)

At least in the case of the Pia version MK8DX is using, for what we're focusing on, browse-reply packets for LAN are constructed as follows:

(All int types are encoded as big-endian)

IndexPseudo-TypeDescription
0u8Packet type (0x1)
1u32Size of session info body (1266 in our case)
5(42 bytes)Misc session info fields, irrelevant to us
47(0x180 bytes)Start of space for application data
431u32Length of application data

The rest of session info follows, though unimportant for crafting a packet for this vulnerability

"LAN_CopyAppData" Pseudocode

For the sake of demonstration, below is rough pseudocode from the LAN implementation of "CopyAppData". While nothing is inherently wrong with this function alone, incorrect usage (in MK8DX's case) can allow for the stack frame to be overwritten by our input application data in packet.

(function located @ +0xA0F8C0 in main for MK8DX v3.0.1)

void LAN_CopyAppData(int* r0, int packet, int out, uint outBufSize) {
    int u1 = 68612;

    if (out != NULL) {
        // The actual length to read from the `packet` buffer at the start of our
        // application data (which our 'server' controls)
        uint appDataLength = *(uint *)(packet + 432);

        // In some cases, outBufSize is input as a larger number than the bounds of the
        // `out` buffer, which allows a stack buffer overflow (in our specific case, `*out`
        // is 128 bytes long, and outBufSize is 150!)
        if (appDataLength <= outBufSize) {
            memcpy(out, packet + 48, outBufSize); // packet[47], start of application data

            u1 = 0;
        }

        *r0 = u1;
        return;
    }

    *r0 = 68615;
    return;
}

{F3640876}

How it was found

The write-up for this report has not been downloaded yet, or the program disclosed it without one. Read it on HackerOne.

This report was disclosed publicly on HackerOne and belongs to its author and the program. See the original