Writeup - Sharing is Caring (irisCTF 2024)
irisCTF 2024 - Sharing is Caring Writeup
- Type - network/misc
- Points - 500
Description
1 | Sharing is caring, don't ya know? Sharing a communications channel, that is! |
Writeup
This problem was categorized as “Networks”, although a note from the author said it could also fit in the RF (Radio Frequency) category. I went into this not really knowing much at all about the topic, but used ChatGPT, googlefu, and lots of analysis to figure out the solution!
Let’s first analyze the prompt because it gave important context that was needed to solve the challenge. There are two people sharing a single communication channel, Eve and Alice. Alice has a single device connected to the channel, presumably sending out the flag. Eve has multiple devices, which I’m assuming are also transmitting information on the channel. It also states that this “isn’t your typical home network”, which means the communications/networking setup here is uncommon.
Here’s the important thing to note about channels: one of their biggest enemies is collisions. If two people transmit at the same time on the same channel, then their signals will mix (amplitudes will add up) and it can make the signals indistinguishable. So since both Alice and Eve are transmitting on the same channel, we need to figure out how to isolate Alice’s signal from Eve’s signals to retrieve the flag.
Red Herring #1
My first thought went to something I learned about in my university’s Digital Communications class, CSMA. CSMA stands for “carrier-sense multiple access”, and has two modes: collision avoidance and collision detection. CSMA is pretty much a way for multiple devices using the same communications channel to avoid and detect transmission collisions, which seems like our exact problem! I started doing research but everything I learned was pretty much just:
- Listen for data already being transmitted. If there’s data, then wait. If there’s not, then transmit.
- If a collision is detected, then both parties transmitting will stop, wait a random interval, then start again.
While important in modern-day networks, it didn’t seem super helpful in our case.
Analyzing the Given Files
This is the perfect time to discuss and analyze the files we were presented with. Inside the compressed archive were 5 files: 1.key
, 2.key
, 3.key
, 4.key
, and signal.txt
. Each of the key files were filled with 200 random bytes, no strings or magic bytes or anything.
1 | user@computer $ xxd 1.key |
My guess was each key corresponded to a device on the channel, so there were 5 devices total (1 for Alice, 4 for Eve). Also, since they’re called “keys”, I figured they were decryption keys or something, but couldn’t figure out what for. Decryption keys aren’t typically this long, plus 200 bytes is an odd keysize. My research yielded nothing, so I set those aside and tried to understand the last file, signal.txt
.
signal.txt
contained a single array with 1,280,000 integers, ranging from -5 to +5. I did some analysis and found out that the only values were [-5, -3, -1, 1, 3, 5]
, so odd numbers. I figured the order was significant, and perhaps even a crude way of shipping data points meant to be charted. Each element in the list was a value meant to be plotted on a y-axis, and each point was simply equidistant apart on the x-axis (probably some measure of time). I had ChatGPT generate a Python script that would chart the first 50 values for me:
At this point I had several questions pop up:
- Why is the range
-5
to5
? - Why are there only odd numbers? More specifically, why is there never a
0
value? - Why are there a million values?
- What do keys have to do with this?
- Why doesn’t the graph show nice, even sine waves?
Rules of Engagement
I started to hypothesize what the answers for these questions might be until I found an answer that satisfied them all, giving me the rules of transmission in this situation. First let’s review collisions; let’s say there are 2 devices on the same channel, both sending waves with an amplitude of +1
. These will collide and a receiver will only see a wave with an amplitude of +2
(assuming the waves are synchronized). However, if one device is transmitting with an amplitude of +1
and the other with an amplitude of -1
, then they will cancel out and the receiver won’t see any signal.
Now imagine a situation with 5 devices! When you see a signal with an amplitude of +1
, what does that mean? It could be that only one device is transmitting with an amplitude of +1
, 3 devices are transmitting with amplitudes +1
, +1
, and -1
, you can’t be sure!
I had assumed that the 5 devices could transmit or not transmit whenever they wanted. If this was the case, there’s approximately a 0% chance that amplitudes would only be odd with 1.2 million data points. HoWeVeRrR, if we assume that all 5 devices are always transmitting, and either with an amplitude of -1
or +1
, then that issue is resolved. The sum of those 5 amplitudes will always have to be odd, and the max/min fit +5
/-5
.
This resolves questions 1, 2, and 5, but introduces a sixth one: How can I isolate Alice’s signal if 5 devices are always transmitting and colliding at the same time?
More Patterns… They’re Everywhere!
I thought to myself, “Well, what do I know about the data Eve is transmitting? Nothing….. or at least that I know of. All I have are the keys, maybe for some reason they’re transmitting the keys?” I went with that thought and tried some things out.
Eventually, I found that if you turn the 200-byte keys into 1600-bit binary strings, then treat a 1
as a signal of -1
, and a 0
as a signal of 1
, adding the amplitude for the first 1600 bits ALWAYS gave a sum that was +/- 1 of the signal. Here’s an example:
- First 4 bytes of
1.key
->8c8b83b4
=10001100 10001011 10000011 10110100
- Translate all
1
into-1
, and0
into1
=[-1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1]
I did this for all 200 bytes of all 4 keys and ended up with 4 big arrays:
1 | 1.key - [-1, 1, 1, 1, -1, -1, 1, 1, ...] |
Now since all these signals are being transmitted at the same time, I should add them up to see what the total signal looks like for 4 of the 5 devices on the channel - [0, 2, 0, 0, -4, 0, 4, 2, ...]
. How does the signal amplitude compare? [-1, 3, 1, -1, -3, -1, 5, 3, ...]
. If you look carefully, you’ll notice that each of signal amplitude values are within +/-1
of the numbers I calculated. This held true for the first 1600 bits, which was too many to be a coincidence.
This meant I could find the difference and use that to calculate what the amplitude of the first 1600 bits of the last device on the channel, which is likely Alice’s key! (note I still didn’t know what to do with it, but at least I had it!)
I wrote a quick python script and got Alice’s key:
1 | user@computer $ xxd alice.key |
That was the last pattern that I needed to find before I put all the puzzle pieces together.
CDMA
I was still struggling to figure out how it was possible to isolate a single signal from a collision mess of 5 signals when I asked ChatGPT.
I knew it wasn’t TDMA or FDMA because these devices were transmitting with the same frequencies at the same time, but CDMA?? I had never heard of that! Apparently it uses “unique codes” (just like keys??) to differentiate their signals in some way. I went ahead and did more investigation into CDMA. I stumbled upon this website that described CDMA pretty well.
A long, unique “code” (also known as a PN code, PRN code, or “key” in our situation) is used to send a message by multiplying it with a single bit from the message and sending that signal out. Remember how 1.key
was encoded as the signal [-1, 1, 1, 1, -1, -1, 1, 1, ...]
? Well, if the first bit from the message is a 1
, then that signal is sent out. However, if the first bit is 0
, then the opposite of that signal is sent out ([1, -1, -1, -1, 1, 1, -1, -1, ...]
). The entire code/key is sent for a single bit of the message, which meant 1600 signal bits gave us 1 message bit. That’s a HUGELY inefficient ratio, but makes sense why 1.2 million signal bits were sent!
That answers all the questions I posed except how to isolate the signals from one another, even if encoded in DS-CDMA. But some reasoning and Python helped me there! We have all 5 keys (or perhaps the opposite of Alice’s key, but that can easily be resolved with testing), and know only those 5 devices are transmitting. Each device will either transmit their key or the opposite of their key, so 2 possibilities. With 5 devices, 2**5
is 32, meaning there are only 32 possible combinations of signals sent out. If I mapped each of those 32 possibilities out and split my signal into 1600-bit chunks, I could figure out which bits were being sent for each device at the same time!
I decided to use MD5 hashes of these 1600-bit variations to match to our 32 possibilities and wrote this cool, little, script using perfect programming technique:
1 | import math |
Running the script:
1 | user@computer $ python3 solve.py |
Flag: irisctf{0h_n0_youv3_d3feat3d_spr3ad_s1gnals_and_1nt3rcept3d_my_c0mms}