My avatar

flewkey

Level 10 Computer Mage

nds-constrain’t

Published on 2020-07-11 by flewkey

Once upon a time, shutterbug2000 discovered nds-constrain’t: a bug in Nintendo’s NTR SSL library that allowed it’s connections to be easily intercepted. This made it possible to connect to alternative online services without ROM patching.

The bug itself is simple: the NDS SSL library does not care whether or not a certificate is authorized to act as a certificate authority. This means that — with any valid certificate — we can sign whatever we want, including a certificate under a false hostname.

A guide to using this bug for fun and profit is now available on the official page, which is much better written than mine. However, you are free to keep reading this one.

Update (2020-12-31): I have corrected some mistakes in this post. There is also information at the bottom of this post regarding OpenSSL which is important to setting up nds-constrain’t properly.

Update (2022-07-13): These instructions will only work with OpenSSL 1.1.1 and lower. OpenSSL 3.0 requires different steps, and I’ll leave those for someone else to figure out.


Getting the Wii client certificate

As explained in the official page for nds-constrain’t, the Wii client certificate is signed by Nintendo and considered valid. Therefore, we can use it’s key to sign whatever we want. You could grab it from a Wii, but it is much easier to download it from Larsenv’s page. Choose the “Wii NWC Prod 1” key pair.

Converting it to a useable format

The file is a PKCS12, and we can’t do anything useful with it until we extract the certificate and the private key. Thankfully, this is pretty simple.

openssl pkcs12 -in WII_NWC_1_CERT.p12 -passin pass:alpine -passout pass:alpine -out keys.txt

That command will export the X.509 certificate and private key from the archive, and store the output in keys.txt. They can then be copied into their appropriate files, which I will name NWC.crt and NWC.key.

Signing your certificate

Instructions for this are listed on the official guide. I have copied them for reference.

openssl genrsa -out server.key 1024
openssl req -new -key server.key -out server.csr
openssl x509 -req -in server.csr -CA NWC.crt -CAkey NWC.key -CAcreateserial -out server.crt -days 3650 -sha1

Update (2021-05-07): The second command will prompt you for values to be used in your certificate. The Common Name in this certificate should be the domain name that it will be valid for (e.g. “flipnote.hatena.com”). Most people will want to set it to “*.*.*” (without the quotes), which will make it valid for all subdomains. See this paste for reference.

NGINX users need to create a file for the certificate chain as well.

cat server.crt NWC.crt > server-chain.crt

Using your phony certificate

Once the SSL certificate is installed, you may run into issues connecting with your DS. This because your NDS only knows how to use SSLv3, with either the RC4-SHA or RC4-MD5 cipher set. Webservers don’t support this by default, so this requires special configuration.

NGINX configuration

First, you need to compile a custom version of NGINX that supports SSLv3 and the RC4 ciphers. Instructions on how to do this are included further down this page.

Then, add the following lines to your NGINX configuration.

ssl_protocols SSLv3;
ssl_ciphers RC4-SHA:RC4-MD5:@SECLEVEL=0;

Assuming that you have added your certificate chain and key, your DS should be able to connect. It is worth noting that most services for Nintendo consoles make liberal use of headers, and some headers (e.g. http_x_gamecd) contain underscores, which shouldn’t be in the header field. You should also configure NGINX to pass request headers to your server if you haven’t already.

underscores_in_headers on;
proxy_pass_request_headers on;

Apache configuration

First, you need to compile a custom version of Apache that supports SSLv3 and the RC4 ciphers. Instructions on how to do this are included further down this page.

Then, use the following SSL settings.

SSLProtocol SSLv3
SSLCipherSuite RC4-SHA:RC4-MD5

Unfortunately, because lowering the security level of OpenSSL in the cipher string results in an error in Apache, Apache users must also modify their OpenSSL configuration. This is usually located in /etc/ssl/openssl.cnf. However, since we are using a custom version of OpenSSL, we will make the change in /usr/local/ssl/openssl.cnf instead.

At the top, add the following:

openssl_conf = default_conf

At the bottom, add the following:

[default_conf]
ssl_conf = ssl_sect

[ssl_sect]
system_default = system_default_sect

[system_default_sect]
CipherString = DEFAULT:@SECLEVEL=0

Working around this in Apache is a bit more difficult. For information about working around invalid headers in Apache, see this example. If you continue having issues with NDS connectivity, please contact me.

Having fun

The possibilities are infinite. Want to run services through a debugging proxy? Implement WFC protocols? Make a Flipnote Studio server? All of this is possible without ROM patches!


The issue with OpenSSL

By default, modern versions of OpenSSL disable SSLv3 and the RC4 ciphers. We need those to talk to the Nintendo DS, so we need to compile a custom version of OpenSSL to use with the webserver.

NGINX with custom OpenSSL

Download and extract the OpenSSL and nginx sources. Then, configure NGINX like so:

./configure --with-http_ssl_module --with-openssl=/path/to/openssl/src \
--with-openssl-opt=enable-ssl3 --with-openssl-opt=enable-ssl3-method \
--with-openssl-opt=enable-weak-ssl-ciphers

Run “make” and “sudo make install” like usual. Be sure that you run the version of NGINX in /usr/local for nds-constrain’t. You might want to uninstall any existing versions of NGINX to avoid confusion.

Gentoo users can add the “sslv3” and “weak-ssl-ciphers” USE flags to OpenSSL and rebuild it. Since there is no weak-ssl-ciphers USE flag at the time of writing, you might want to add my flewkey-overlay and unmask dev-libs/openssl::flewkey-overlay. After that, install NGINX as usual.

Apache with custom OpenSSL

Download and extract the OpenSSL and Apache sources. Then, we must configure OpenSSL like so:

./config enable-ssl3 enable-ssl3-method enable-weak-ssl-ciphers

After this, run “make” and “sudo make install”. OpenSSL will install in /usr/local and /usr/local/ssl by default, so it shouldn’t interfere with the version currently installed on your system. You will also need to make the OpenSSL configuration change made in the “Apache configuration”

Next, we need to actually configure Apache, specifying the location of OpenSSL like so:

./configure --enable-ssl --with-ssl=/usr/local

Run “make” and “sudo make install” like usual. Be sure that you use the version of Apache in /usr/local for nds-constrain’t. You might want to uninstall any existing versions of Apache to avoid confusion.

Gentoo users can add the “sslv3” and “weak-ssl-ciphers” USE flags to OpenSSL and rebuild it. Since there is no weak-ssl-ciphers USE flag at the time of writing, you might want to add my flewkey-overlay and unmask dev-libs/openssl::flewkey-overlay. After that, install Apache as usual.


Contributions

Thanks to shutterbug2000 for discovering nds-constrain’t, as well as Lauren Kelly and jaames for their work on the official guide. These individuals have contributed a lot to the Nintendo and Flipnote Studio communities in general.

Greetings to Adam Gilbert, MeGaMoV and Brandon Serpas.


Articles from blogs that I like

Announcing git snail-mail

You’ve heard of git-over-email thanks to git send-email — now you can enjoy git snail-mail: a new tool making it easier than ever to print out git commits on paper and mail them to your maintainers. Running git snail-mail HEAD~2.. prepares the last two commi…

From Drew DeVault's blog
Published on April 1, 2022

When optimizations make the code worse, aka GCC and Clang are fucking retarded.

Both GCC and Clang are obsessed with constant / value range propagation. Unfortunately they are far too stupid to actually apply such optimizations appropriately. A common pattern that both compilers completely fuck up is testing a pointer for NULL and … …

From DeadFish Shitware
Published on January 16, 2022

Computer Science Basics: Types (in dart)

Inside of the dart language most types come from from the parent type Object which could be called the root type in this case. From the root type in the case of dart you can end up with a type tree a little like this for the basic types. With this tree her…

From Technically Alex's blog
Published on May 11, 2021

Generated with the spectacular power of openring