Skip to content

Information & PoC for CVE-2024-45200, Mario Kart 8 Deluxe's "KartLANPwn" buffer overflow vulnerability

License

Notifications You must be signed in to change notification settings

latte-soft/kartlanpwn

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Kart"LAN"Pwn (CVE-2024-45200)

Latte Softworks Website Latte Softworks Discord

Information & Proof-of-Concept for Mario Kart 8 Deluxe's "KartLANPwn" stack-based buffer overflow vulnerability
Written by @regginator

CVE CVE-2024-45200
CVSS 3.1 Undetermined (Nintendo.. claims it's a 4.3/10)
Bounty Paid $512
H1 Report #2611669
Discovered July 2nd, 2024
Fixed Sept. 11th, 2024 (v3.0.3)
Disclosed Sept. 29th, 2024

Contents

Background Information

KartLANPwn is a vulnerability in Mario Kart 8 Deluxe's incorrect usage of the Pia P2P networking library, in which individual implementations of "CopyAppData" 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. KartLANPwn affects the usage of Pia's implementations of LAN/LDN multiplayer and NEX online multiplayer.

This vulnerability affects all versions of Mario Kart 8 Deluxe up to and including v3.0.1 (v3.0.2 for China/Tencent), and has specifically been demonstrated via the "LAN Play" feature on the v3.0.1 retail release of MK8DX.

As of 2024/09/11, Nintendo has deployed a fix for KartLANPwn alongside v3.0.3 for all regions, excluding China. As of 2024/09/27, v3.0.3 has now also been released for China. We have safely disclosed this information after receiving permission from Nintendo.

Introduction

The proprietary Pia networking library is used by first-party Nintendo Switch games with local or online-play support to provide peer-to-peer netcode implementations for LAN/LDN (local multiplayer) and the NEX protocol, used for online multiplayer.

For demonstration's sake, we will specifically be focused on Pia's LAN protocol. The room host's console opens a UDP "discovery" socket at :30000 on a local broadcast address (255.255.255.255) and other consoles on the same network are supposed to advertise "browse requests" from their own socket (also on :30000) to the router to forward to other devices on the same network.

The room host (our 'server') sends back an initial "browse reply" that's supposed to contain information about the room (the host's display name, Mii data, # of players, etc). Within the browse-reply packet, the length of the application data to be copied into the out buffer can be controlled with a value of up to 150, even though out is only 128 bytes wide. This allows for overflowing values on the stack frame (in this specific case, for a pop {r4-r8, pc})

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)

Index Pseudo-Type Description
0 u8 Packet type (0x1)
1 u32 Size 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
431 u32 Length of application data

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

"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;
}

Proof-of-Concept

See kartlanpwn-poc.py

We've provided a simple PoC script written in Python, which acts as a fake room host that replies to peers' consoles with a specially crafted "browse-reply" packet that will crash the game's process when you open the "LAN Play" menu in MK8DX from a console on the same network as the computer running the script.

Requirements

Either download the repo's zip from GitHub directly, or clone using git:

git clone https://github.com/latte-soft/kartlanpwn.git && cd kartlanpwn
python3 kartlanpwn-poc.py

Demonstration of PoC

See video demonstration (YouTube):

YouTube - KartLANPwn Demonstration (CVE-2024-45200)

And for you ARM nerds, here's a screenshot from GDB of the resulting process segfault:

GDB screenshot

Closing Thoughts

It only took a couple of days to figure out the details of the bug itself, but actually making use of the overflow? That's a whole other can of worms. The Nintendo Switch kernel's usermode doesn't play around; it's extremely strict in every crevice it can be. We spent many hours exchanging and tampering with different ideas and leads, to no ultimate avail for real (arbitrary) code execution. In our specific case, even reliable ROP didn't appear very doable, being that pretty much all relative networking-related functions were class-based, plus we also only had direct write access to r4-r8. (*_this my beloved) Plus, w/out a previous information leak, it isn't too doable to just skip a mov r4, r0 or what-have-you to control the _this pointer. Fun stuff!

Report-wise, everything was actually a relatively smooth process this time with Nintendo triage from time of report, to disclosure. While the bounty payout of $512 was far less than I anticipated (aren't they all?), anything beats the "Nintendo Ninjas" showing up at my door..

Nintendo most definitely learned their lesson per se from the simpler days of the Wii, 3DS, and even Wii U. They did their homework; successful exploitation of any kind beyond denial-of-service crashing from usermode on the Switch is nearly impossible. ASLR, forced No-eXecute pages (you cannot directly write to executable memory pages, games need to use a dedicated sysmodule just for JIT!), inability to ROP, among other pain points. (waiting for the modding scene to eat these words in no time..) On the other hand, in the last couple of months, I have learned a ton about a completely new platform and architecure (to me anyway) in a very short amount of time, not to mention the awesome people I've had the pleasure of working with on KartLANPwn! (Thanks Pablo and fishguy 😄)

Credits

Report Timeline

Date Info
2024/07/18 Report submitted to Nintendo via HackerOne
2024/07/31 Report triaged internally
2024/09/11 Fix released alongside Mario Kart 8 Deluxe v3.0.3 for all regions, excluding China
2024/09/12 Bounty paid out by Nintendo
2024/09/12 Other 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/27 Mario Kart 8 Deluxe v3.0.3 released for the Chinese region
2024/09/29 Nintendo granted disclosure, this repository made public
2024/09/30 CVE-2024-45200 published by the NVD

License

CC BY 4.0

KartLANPwn © 2024 by reggie ([email protected]), Latte Softworks (https://latte.to) is licensed under CC BY 4.0.
To view a copy of this license, visit https://creativecommons.org/licenses/by/4.0/


This gif was created on July 3rd, 2024:

Evil LAN-play error..

About

Information & PoC for CVE-2024-45200, Mario Kart 8 Deluxe's "KartLANPwn" buffer overflow vulnerability

Topics

Resources

License

Stars

Watchers

Forks

Languages