Wave

Category - IT

A Mystery Involving Hardware Security Modules and Value Tokens

Forbidden Tempura 10/7/2025

Context Historical context In July, 2021, the phenomenon known as the “Gigaleak” continued. The Gigaleak was a drip-feed of part of the ill-gotten data from the 2018 Nintendo data breach. On July 20, 2021, the iqcvs.tar.xz file was uploaded to the now-defunct file sharing website anonfiles.com and thereby made available to the public by The Hacker Known as 4chan. This file contains a dump of CVS repositories. The repository sw contains the BroadOn network infrastructure around the middle of the year 2006. This is shortly before the Nintendo Wii launched. The network infrastructure was initially launched alongside the iQue Player, a variant of the Nintendo 64 featuring downloadable games and some anti-piracy measures of questionable quality (non-HTTPS link) intended for the Chinese market, which was and still is notorious for being particularly prone to piracy. It was developed by a company then called BroadOn Communications Corp., a California corporation. The iQue Player u

ITInfodump

A Brief Look at the 3DS Cartridge Protocol

Forbidden Tempura 6/2/2024

About a week ago, there has been a little addition to the 3dbrew wiki page about 3DS cartridges (carts) that outlines the technical details of how the 3DS cartridge controller and a 3DS cartridge talk to each other. I would like to take this opportunity to also include the 3DS itself in the conversation to illuminate which part of which device performs which step. I will then proceed to outline where I think the corresponding design decisions originate. Finally, I will conclude with some concrete ideas for improvement. But first, we need to talk about parallel universes This protocol makes no sense unless you have a basic overview of the 3DS AES engine. The 3DS AES engine can load 128-bit AES keys in two ways: Using key-derivation from a keyX and keyY (officially called KeyId and KeySeed, respectively). Directly specifying a full AES key. The key derivation from a keyX and keyY works as follows: AES key = (((keyX ROL 2) XOR keyY) + C1) ROR 41, where ROL is left rotation on a 128-bit

ITGamesInfodump

Reconstructing the 3DS Bootstrapping Process at the Factory

Forbidden Tempura 5/13/2024

Motivation The Nintendo 3DS was a fairly popular console. In spite of that, surprisingly little is known about how it is put together at the factory. Working with information that was uncovered during the so-called Gigaleak, I will try to recover as much information as I can about the manufacturing process up and until the point the 3DS is able to complete a normal boot sequence. One-Time Programmable (OTP) region Every 3DS ships with 0x100 of one-time programmable persistent memory at 0x10012000-0x10012100, containing console-unique keys and information. This obviously has to occur before any normal firmware runs on the system because significant amounts of all data written would fail to account for console-unique information and thus the encrypted values would be all encrypted for the wrong keys. An interesting observations: ctr.7z (SHA-256: 8b05072361254437277576d53c08b95e5f076c6b33a2871fad74eaa5561d1d38) ctr/sources/bootrom/CTR/private/build/bootrom/ctr_bootrom/ARM9/main.c has a pr

ITGamesInfodump

If it has Text, it is Pain

Mia Rose Winter 5/1/2024

I've been meaning to write tests for Wave for a while. Honestly, in my 12 years of dev I never actually wrote one outside of the odd academic homework assignment, so I had no idea how to approach it. After a couple of videos and video presentations about general unit tests, TDD and stuff, I actually got intrigued, and with a bug discovered just today by a coworker in Wave I was baffled by I thought, okay, let's dissect this little Käfer. Prerequisites: What does Wave do here actually If you have not authored an article on Wave before, let me give you some background. When you want to load a specific article in the article view, there are three methods, two actively used and one historical, to find it. The first and most direct, the “permalink” if you will, is going to /article/{id}, with the UUIDv4 ID of the article. This is used for stuff like the article editor and during the draft and review process when the other method doesn't work, and maybe one day there will be a &l

ITTutorialInfodumpC#

Migrating PVs in Kubernetes

4censord 3/10/2024

Migrating PVs in Kubernetes In kubernetes, data storage is provided by so called persistent volumes. Kubernetes itself contains a bunch of different options out of the box, notably HostPath and NFS. HostPath has the advantage of being incredibly simple. You just take a directory from your host, and make it available in a pod. But, because it is host specific, that does not work very well if you have more than one host and want to be able to tolerate host failures. NFS has the advantage of being standard, to the extend that every NAS or storage solution from the last 20 years supports it. But, perfomance often isn't great. And, unless you are using NFSv4, NFS has some challenges surrounding things like file locking. But those arent important for anything exept rare cases like databases… Kubernetes supports having multiple types of PVs, and groups them together in StorageClasses. When requesting a PV from kubernetes (using a pvc), you can specify which storageclass you want. If yo

ITTutorial

Continuing on an HTTP-Server in rust

4censord 3/3/2024

This post is basically a direct continuation of the recent Computerphile Video Coding a Web Server in 25 Lines - Computerphile The video explains the absolute basics of the HTTP protocol, and implements a very basic HTTP-server in rust. This blog-post will go into more detail about some HTTP headers, and some other HTTP request types, implementing some of them in the process. At the end of the video, our source-code looks like this: use std::io::BufRead; use std::io::Write; fn main() { let listener = std::net::TcpListener::bind("127.0.0.1:8081").unwrap(); for mut stream in listener.incoming().flatten() { let mut reader = std::io::BufReader::new(&mut stream); let mut line = String::new(); reader.read_line(&mut line).unwrap(); match line.trim().split(' ').collect::<Vec<_>>().as_slice() { ["GET", resource, "HTTP/1.1"] => { loop { let mut line = St

ITTutorial

Wave on Kubernetes

4censord 2/25/2024

Kubernetes is an increasingly more popular deployment option for services. Originally developed by Google0, Kubernetes provides functionality for multi host containerized deployment of applications. Today, i will take a look at deploying wave onto my Kubernetes.[1] This does not explain how to interact with Kubernetes Wave depends on some other services to be fully functional, namely A PostgreSQL server for persistent data storage A redis server for session storage and synchronization A reverse proxy for TLS termination An SMTP server for sending email. Dependencies Because we want to focus on running wave, let's just get the other stuff out of the way. All our stuff will be happening in the wave-dev namespace, so let's create that first: kubectl create namespace wave-dev PostgreSQL Deployed via helm from the bitnami/postgresql chart using the following values: # postgres.yaml --- auth: username: "wave" password: "wavepw12345" database: "wave" us

ITTutorial

Effectively Serving a Large Amount of Images

Mia Rose Winter 2/18/2024

When you build an app, especially a web app, you will inevitably think about how to serve the user your images. In a static setting, that's easy, put them into a folder and add a relative link to it in your page, maybe with an async flag if you are fancy, done, the browser does the rest. But in a dynamic setting, you don't have that luxury, you usually want users to upload images… and now you need to decide how those images get to your server, and later, get to every visitor needing it. Image processing first, some general advice. When people can upload images, you first have to ensure their security. Never just put their upload anywhere reachable by outsiders, it may be a JPEG with Exif data containing the location the image was shot, the people in it and that's a big privacy no-no. You also need to protect your other users, whatever just got uploaded may, somehow, alter the behavior of your page or even execute malicious code (hello GitHub). Lastly, there is also the aspect of

ITTutorial

Designing User Experience for Inexperienced Users

Mia Rose Winter 2/11/2024

Studying media information technologies while working and designing software at a financial company, I have made observations I feel are rarely, if ever, talked about, and it is actively harming many companies. When you study something with IT that isn't just building Mainframes and backends, you will inevitably run into user experience and accessibility lectures. The flow of information, the way you should lay out things, the colors and contrasts you need, what you should avoid, what you need to implement, these kinda things are essential for an application to be “User friendly”. A lot goes into the study of user experience, UX; not only what ratios of colors are the most readable to people with bad eye sight, or how to structure a website to be best navigable with accessibility software like screenreaders, there is also a lot psychology, how to guide a persons gaze, convey information in a coherent and efficient manner. Looking at the products of many big companies, you w

ITOpinion

ActivityPub - Annoyingly useful

Melody 2/2/2024

So, ActivityPub. You probably love its existence, considering that you probably found this article (or me or the creator of Wave) over one of the services implementing it, be it Mastodon, Misskey (or one of its many soft and hard forks), Plemora/Akoma or other. And they all do a great job of providing a nice UI for all the things you can do with ActivityPub (except for Akoma, I will stand with my take of its UI being badly made). What you don't see is the protocol layer though. And this is where it gets ugly. ActivityPub has a few parts. Endpoints and what you transmit to and from those endpoints. The endpoints are fine. One inbox and one outbox endpoint per user and the same for the entire server too. Easy to solve with path parameters. The public page (the one you see when visiting the user) could be on that path too or a different one. Don't matter. Easy to do. Webfinger? Also easy to do. Not funky yet. All nice and consistent. The problem is what you have to transmit. Because Activ

IT

Compose 5000 lines deep, or how to Containerize responsibly

Mia Rose Winter 1/27/2024

If you are like me, and you have just learned how docker and docker compose worked, you will probably head out to rebuild your own little server, or start one anew, watch some tutorials, look for some tools, and end up with a little compose file to start your infrastructure. It probably has a reverse proxy like nginx, traefik or Caddy, a little static website and maybe something for fun, a little self made project, a node app, a lil' blazor app, maybe just some open source link shortener you found (obligatory Just Short It! mention). A total of a hundred lines, not bad, manageable. But it doesn't stay like that, does it? Rise of the stacks Now, you may get interested in some more advanced tech. Like, let's say, a blogging engine (like Wave), but that doesn't just take a container for a website, it also comes with a postgres database, a redis cache, maybe even more (at point of writing, Wave is still in alpha), so there goes another block in your compose, another 80 lines or so, now we

ITTutorial

Setting up a new Linux Server

Mia Rose Winter 11/22/2023

Every goddamn time I create a new VPS or something and install ubuntu I have to google together all the little steps and commands I need to run to give it a baseline of security, I am writing this one down now. Creating a custom user Script kiddies love pinging random servers with root and see where they can get in, I once ordered a new server but didn't configure it until the next day, and when I logged in with root it told me there had been 900 logging attempts (over night!). So yea, let's create our own account: Add a new user $ sudo useradd -m -G sudo rose -m is to also create a home directory for that user (we put our ssh key there), -G sudo adds them to the sudoers group Set up a password: $ sudo passwd rose now open another terminal, ssh with that new user into the server and see if you can run commands with sudo ls or something. When you have valiated your newly created user works and can use sudo, you can exit that root-user terminal. Transfer SSH keys You always wanna use

ITTutorial
Powered by Wave