Reverse engineering 3DS Pokemon Mystery Gifts
I was recently motivated to see there was any way to recreate mystery gift events that were distributed for the 3DS Pokemon Games. Knowing that fan made servers had been created for the DS Pokemon games (See wiimmfi and Poke Classic Network) - I wondered whether it was possible to do the same for the later games.
Setting up a MITM server
My first hurdle was to configure a 3DS so that SSL packets could be inspected. Setting up a MITM server would be easy but getting the 3DS to accept a non Nintendo cert would be harder. Thankfully, my console was already running a custom firmware and SciresM on GitHub had already done the hard work to figure out exactly what bytes to patch in order to disable SSL verification completely. See Disable SSL Verification on the 3DS for a full write up. Now I could update the 3DS proxy to point towards my MITM software of choice (Charles Proxy).
Some endpoints used by Nintendo/Pokemon require a client certificate (ClCertA.p12) to connect - this is included in SciresM’s Repo. Charles allows these to be configured under SSL Proxying Settings. I configured Charles to use the cert for all *.nintendo.net
and *.nintendowifi.net
endpoints. Although this covers more than is required - it simplifies identifying which endpoints actually require the cert.
Initial Digging
Now I was all setup to sniff traffic sent by the games. Next was to try and figure out how the mystery gift system actually worked.
Unfortunately sniffing packets will only get you so far when mystery gifts haven’t been distributed for quite some time. So I scoured the internet to see if I could find anyone else who attempted this when the gifts were still live.
My initial research pointed me to 3 different posts. Hacking Pokemon 6th gen Mystery gift server, Reverse Engineering the Mystery Gift Protocol for XY/ORAS and Pokemon Gift Server Development (translated). These resources gave me an initial look into how the system worked but I was still limited by not knowing the full end to end flow and missing copies of all the signed events.
Enter the Mystery Machine
Thankfully, I missed one key resource during my first round of research. One of the posters of the above articles had actually already created a functioning mystery gift server which is still alive today.
To leverage this I setup charles to map requests to some endpoints to forward over to mys.salthax.org
. This allows for a successful capture of the the end to end flow of receiving a mystery gift! I’m simplifying slightly as mys.salthax.org
does not respond correctly in some cases so had to write a flask server to take the requests and map them correctly onto mys.salthax.org
.
Digging into the packets
At a high level, the flow for redeeming a mystery gift (via code) is:
- Perform connection test by making GET request to
http://conntest.nintendowifi.net/
- Perform
POST
tohttps://nasc.nintendowifi.net/ac
- Get the active policies for the user’s region by making a
GET
request tohttps://nppl.c.app.nintendowifi.net/p01/policylist/3/GB
(for a UK based user) - Validate the user’s code and get the ID of the event the code belongs to.
POST
tohttps://3ds1-fushigi.pokemon-gl.com/api/serial.auth
. - Lookup all available pokemon matching this event id for this event mode (SER_EU_E - Serial code pokemon for the European region and English language).
GET
request tohttps://npfl.c.app.nintendowifi.net/p01/filelist/h0VRqB2YEgq39zvO/FGONLYT?c=GB&l=en&a1=SER_EU_E&a2=586
. Returns a list of Pokemon files. - Get the file returned from above to get the signed Pokemon event file.
GET
request tohttps://npdl.cdn.nintendowifi.net/p01/nsa/h0VRqB2YEgq39zvO/FGONLYT/0586_Mewtwo_EU_E