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.