Skip to content

Instantly share code, notes, and snippets.

==========
Map: 000 - Route 1 (Hau’oli Outskirts) / 003 - Route 1 / 010 - Melemele Sea
Tables: 18
Table 1 (Day):
Encounters (Levels 2-3): Ledyba (20%), Pikipek (20%), Yungoos (20%), Grubbin (15%), Caterpie (10%), Buneary (10%), Pichu (5%)
SOS Slot 1 (Levels 2-3): Ledyba (20%), Pikipek (20%), Yungoos (20%), Grubbin (15%), Caterpie (10%), Buneary (10%), Pikachu (5%)
SOS Slot 2 (Levels 2-3): Ledyba (20%), Pikipek (20%), Yungoos (20%), Grubbin (15%), Caterpie (10%), Buneary (10%), Pikachu (5%)
SOS Slot 3 (Levels 2-3): Ledyba (20%), Pikipek (20%), Yungoos (20%), Grubbin (15%), Caterpie (10%), Buneary (10%), Pikachu (5%)
SOS Slot 4 (Levels 2-3): Ledyba (20%), Pikipek (20%), Yungoos (20%), Grubbin (15%), Caterpie (10%), Buneary (10%), Pikachu (5%)
SOS Slot 5 (Levels 2-3): Ledyba (20%), Pikipek (20%), Yungoos (20%), Grubbin (15%), Caterpie (10%), Buneary (10%), Happiny (5%)
==========
Map: 000 - Route 1 (Hau’oli Outskirts) / 003 - Route 1 / 010 - Melemele Sea
Tables: 18
Table 1 (Day):
Encounters (Levels 2-3): Ledyba (20%), Pikipek (20%), Yungoos (20%), Grubbin (15%), Caterpie (10%), Buneary (10%), Pichu (5%)
SOS Slot 1 (Levels 2-3): Ledyba (20%), Pikipek (20%), Yungoos (20%), Grubbin (15%), Caterpie (10%), Buneary (10%), Pikachu (5%)
SOS Slot 2 (Levels 2-3): Ledyba (20%), Pikipek (20%), Yungoos (20%), Grubbin (15%), Caterpie (10%), Buneary (10%), Pikachu (5%)
SOS Slot 3 (Levels 2-3): Ledyba (20%), Pikipek (20%), Yungoos (20%), Grubbin (15%), Caterpie (10%), Buneary (10%), Pikachu (5%)
SOS Slot 4 (Levels 2-3): Ledyba (20%), Pikipek (20%), Yungoos (20%), Grubbin (15%), Caterpie (10%), Buneary (10%), Pikachu (5%)
SOS Slot 5 (Levels 2-3): Ledyba (20%), Pikipek (20%), Yungoos (20%), Grubbin (15%), Caterpie (10%), Buneary (10%), Happiny (5%)
from struct import unpack as up, pack as pk
from binascii import unhexlify as uhx, hexlify as hx
from Crypto.Cipher import AES
from Crypto.Util import Counter
import sys
pk11key = uhx('') # Insert key here.
def string_to_ctr(ctr):
return Counter.new(128, initial_value=int(hx(ctr), 16))
#define UNLOADED_FILE 1
#include <idc.idc>
static main(void)
{
// set 'loading idc file' mode
set_inf_attr(INF_GENFLAGS, INFFL_LOADIDC|get_inf_attr(INF_GENFLAGS));
GenInfo(); // various settings
Segments(); // segmentation
Enums(); // enumerations

Nintendo Switch RSA-PKCS#1 Public Key Recovery

This is a short writeup of a fun (but ultimately pretty useless) attack I implemented on the Nintendo Switch a few months ago resulting in the recovery of some otherwise unobtainable RSA public keys. Since public keys aren't private keys, this is pretty useless, apart from letting us validate some signatures on PC. Even so, the attack is a pretty cool one, so I thought I'd write it up.

Every Switch gamecart has a unique certificate (called its "CERT"), storing an RSA signature followed by some kind of unknown but unique encrypted data. I was trying to reverse how these certificates work, and the obvious first step was to try to see how they were validated. However, when I tried looking through the FileSystem (FS) module, which should be responsible for validating these certificates, I found no references to the format at all. The "CERT" magic number was nowhere to be seen, and I couldn't find an RSA modulus that validated the signatures I had. This was in

# Pure python AES128 implementation
# SciresM, 2017
from struct import unpack as up, pack as pk
def sxor(s1, s2):
'''Xors two strings.'''
assert(len(s1) == len(s2))
return ''.join([chr(ord(x) ^ ord(y)) for x,y in zip(s1, s2)])
class AESCBC:
@SciresM
SciresM / Factory_2.0.0-13 (2.3.0 consoles).json
Last active April 25, 2018 01:09
Known Switch Factory Firmware Revisions
{
"0100000000000807": {
"0": {
"nca": "dafd00b9ad3b05181f71b7e970b371ed.nca",
"size": 4096
},
"2": {
"nca": "bc6b7d53a47ed1598efc7966a3772e8c.nca",
"size": 90112
},
{
"version": {
"format": 1,
"semantics": 1
},
"news_id": 10000,
"published_at": 0,
"pickup_limit": 1209600,
"priority": 50,
"deletion_priority": 0,
int cJSON_GetU8(const cJSON *obj, const char *field, u8 *out) {
const cJSON *config = cJSON_GetObjectItemCaseSensitive(obj, field);
if (cJSON_IsNumber(config)) {
*out = (u8)config->valueint;
return 1;
} else {
fprintf(stderr, "Failed to get %s (field not present).\n", field);
return 0;
}
}
@SciresM
SciresM / tz_5x.idc
Created April 24, 2018 01:12
IDC for the Nintendo Switch's Secure Monitor, version 5.0.0.
#define UNLOADED_FILE 1
#include <idc.idc>
static main(void)
{
// set 'loading idc file' mode
set_inf_attr(INF_GENFLAGS, INFFL_LOADIDC|get_inf_attr(INF_GENFLAGS));
GenInfo(); // various settings
Segments(); // segmentation
Enums(); // enumerations