CTF Circle - Hack-A-Sat 2021 Qualifier CTF
Bit Flipper Challenge Writeup
Written by sen (@sarahemm)

###############
### Summary ###

The 'Bit Flipper' challenge listed a server and port number, and gave a file
called encoded.bin. Upon connecting to the port, it gave an explanation that
you have the ability to flip up to 3 bits within the code for the thermal
protection system of a spacecraft, and that you needed to use this ability to
make the thermal protection system fail. Complicating this is the fact that
the SECDED system will fix flipped single bits, or halt the system if multi-
bit corruption is detected (much like ECC memory on servers).


###########################
### Phase 1 - Discovery ###

To start off, I ran 'file' on the encoded.bin file provided, which said it was
"Non-ISO extended-ASCII text". Running 'cat' on this, it appeared to be a
fragment of Python code, but with corruption all over it. Bits of it appeared
like "Temper?ature Se?nsor" or "if temBp < 15 a?nd not s~tate:". I wasn't sure
why it was all corrupt, but assumed it was just an example of how SECDED can
fix errors. At this point I hadn't yet noticed that it wasn't that characters
had been corrupted, but that extra characters were inserted. SECDED is Single
Error Correcting and Double Error Detection, meaning that it is able to
correct single-bit errors, and is able to detect that multi-bit errors exist
but not correct them.

It seemed like the required change would be to reset either the lower or upper
bounds on the temperature, allowing the temperature to rise or fall beyond the
limits which would result in the flag.


##########################
### Phase 2 - Learning ###

I vaguely knew about how SECDED worked from being around servers that use it,
but didn't know many details about it. I googled 'Hamming SECDED' to try to
learn more about how it worked, finding a simulator at
http://www.ecs.umass.edu/ece/koren/FaultTolerantSystems/simulator/Hamming/HammingCodes.html
This simulator allowed entering hex or binary information, which it would then
add Hamming code to and show you how the process worked. This tool ended up
being a key piece to solving this challenge.

I played with the simulator a bit, trying to find a combination of bit changes
that would generate the same Hamming code despite changing the 35 to an 85 or
95 or something. This wasn't possible, which is obvious in hindsight as this
is the entire point of SECDED!

I had assumed that the parity data was stored elsewhere in the system and so
couldn't be changed, but at this point took a step back and looked over all
the information I had to see what else I might be able to manipulate. Opening
the encoded.bin file in 'less' rather than 'cat', the high-ASCII values stood
out in inverse text, and the regular pattern of them became clear. Every 8
bytes there was one extra byte, which was the "corruption" I had noticed
initially. I realized at this point that it wasn't corruption at all, but the
Hamming parity codes. I tried putting a group of 8 bytes into the simulator
app I'd found earlier, which output a Hamming code that matched the 9th byte
in the bin file.


#########################
### Phase 3 - Solving ###

With all this information, I realized that all I had to do was change the
temperature threshold, then also change the Hamming code in the 9th byte after
it so that it matches again. The challenge then was just to find a combination
of changes that would require 3 or fewer bit flips.

I tried changing the 3 in the high threshold of 35 degrees C to an 8 at first,
but this required 3 bit flips and wouldn't leave us any flips to fix the
parity as well. I tried 9 instead, this required 2 bit flips and only 1 parity
flip, which seemed promising.

I opened the bin file in a hex editor and figured out which bytes needed
flipping, ending up with bits 1 and 3 in byte 273 (change threshold from 35C
to 95C), then bit 1 in byte 278 (fix the parity byte). Entering these values
into the challenge port resulted in the flag!


##################################
### Lessons Learned/Reinforced ###

- I briefly looked at whether there was a Ruby gem to do the Hamming code
  calculations, but decided to just shuttle the data between the editor and
  the website myself which worked fine in the end. Sometimes it's not worth
  making the tooling too fancy! Had this required tens or hundreds of bit
  flips it might have been worthwhile to automate it, but it would have been
  a waste of time in this case.