Reverse Engineering the Mystery Gift Protocol for XY/ORAS
So over the last week or so I was bored and decided to poke around and see how exactly the Mystery Gift protocol worked for Gen VI Pokemon games. My motivation actually came primarily from some of the findings that you could actually spoof a Hoopa by changing your SSID to “McDonalds Free Wifi”, and this made me somewhat curious as to how the differences in SSIDs were determined in finding a Mystery Gift.
As a forewarning to how I conducted this research, this was all done using MITM as opposed to looking at the game’s code. This basically means that what I found could be a small subset of what there actually is. I should also mention early on that you cannot do https MITM without full pre-menu ARM11 kernel hax of some sort, (ie a FIRM relaunch from ARM9 as seen in use for emuNAND or ARM11 kernel off homemenuhax somehow). Basically it only works by adding a root cert early while the ssl module starts. I should also mention that you cannot spoof or create custom events without a way to edit the game’s code, ie NTR, HANS, CIA hax, or similar. This is because the servers use https, and on top of that, signed BOSS-encrypted files. Anyhow, to the protocol:
The first thing queried is Nintendo’s NPFL server, which contains usually a file list or metadata for what is on their NPDL server. The actual contents and communication varies between game to game, however it is commonly used for fetching updated songs for something like eShop or badge data for Badge Arcade. In the case of the McDonalds Hoopa, the URL which is first queried is https://npfl.c.app.nintendowifi.net/p01/filelist/cRFY0WFHNjPh44If/FGONLYT?ap=11012900000&c=US&l=en&a1=MYS_US_E&a3=N&tm=2 . The main information that interested me was the sorting arguments at the bottom. Querying just FGONLYT with no arguments actually gives you something like this. This data contains most if not all password Pokemon, tournament connections, and if there’s a currently available Pokemon, Mystery Gifts. However, in this case it did not contain any MYS items. However, when you add ap=11012900000, additional events are added. This is the kind of reply you would get from something like the URL above. Without the ap argument, it’s just empty, for now. The contents of what is downloaded is also prepended with an SHA1 hash of the contents.
But what does that AP number even mean? Well, to explain that I’ll have to go a bit back into the significance of the McDonalds SSID in the first place. On the 3DS, a list of every single Nintendo Zone SSID is kept, along with other metadata regarding them. Yellows8 has been parsing this list for quite some time here, although it’s actually missing some data like the security keys and IDs for each point. However, extracting the Nintendo Zone hotspot.conf manually reveals that the ID for “Mcdonalds Free WiFi” is actually 1012900000, so ap=1<AP ID>. I don’t know for certain, but if I had to guess the first 1 would probably be the region ID.
So when the 3DS connects to a Nintendo Zone acces point, Pokemon detects this and pulls the appropriate AP ID and includes it in the request, yielding additional Mystery Gift events specific to certain locations. This also means that if you spoof this first request, you can obtain these events fairly easily without changing your SSID. This can be done by just hosting the reply on a local server. I ran some tests though, and unfortunately you cannot pull older events. The date is most likely checked (possibly 3DS-side, I haven’t actually tested this), so older events cannot be spoofed as current.
What happens next is the currently available events is pulled (In this case, 553_Hoopa_US_E_NZ) and is used to download https://npdl.cdn.nintendowifi.net/p01/nsa/cRFY0WFHNjPh44If/FGONLYT/553_Hoopa_US_E_NZ?ap=11012900000&tm=2. Note that, again, the ap argument is being used. It will not work without this, and again for spoofing this file can be rehosted and the URL changed in the game’s code. This though is the actual bulk of the information stored in the Mystery Gift. This file can actually be downloaded without the need of client certificates from a 3DS, however it’s an encrypted BOSS:
Not much to see when it’s all encrypted. And unfortunately to decrypt these, you need either ARM9 or homebrew access. As of writing, the boss service wasn’t documented well enough to do this through homebrew and I didn’t feel like trying to figure it out, so I went with the former. Decrypted and with BOSS header stripped, however, you get something a lot more interesting:
As of now I only have a little bit of it documented, but I at least got to the end of the protocol. Everything about the Pokemon is stored in this BOSS file I’m fairly certain. However since the BOSS files are both encrypted and have proper signature checks, it’s nigh impossible to edit them without changing how the game itself downloads and reads the gifts. With game modification, you could very well not use BOSS at all and just download the raw data unencrypted, but I haven’t attempted to do that yet.
Having the protocol completely done, I think what I may end up doing though some time in the future is setting up a server to start logging changes in Mystery Gift/other events, and downloading the BOSS files to be examined decrypted to start piecing the actual format together. But other than that, it was an interesting bit of research and I can safely say my curiosity has been satisfied.