hack-a-sat 2021: iq writeup

Hack-A-Sat is a capture the flag style event with challenges related to space, space operations and space craft. The 2021 edition is the second time this challenge ran and its qualification round took place on the weekend of June 2021. Our team participated for fun and we were able to solve a few challenges. This post talks about the challenge named IQ and presents my solution to it.

Accessing hack-a-sat challenges is done with netcat or similar. After loging into the CTF dashboard and selecting the challenge, the player is provided a hostname and port to connect to as well as an identification ticket. Using netcat the player connects to the hostname on the given port and is presented with the challenge after entering the identification ticket.

IQ challenge description

The full text of the IQ challenge is the following:

 1IQ Challenge
 2   QPSK Modulation
 3          Q
 4          |
 5    01    |     11
 6    o     |+1   o
 7          |
 8          |
 9    -1    |     +1
10===================== I
11          |
12          |
13    00    |     10
14    o     |-1   o
15          |
16          |
17Convert the provided series of transmit bits into QPSK I/Q samples
18                  |Start here
19                  v
20Bits to transmit: 01000011 01110010 01101111 01101101 01110101 01101100 01100101 01101110 01110100 00001010
21Provide as interleaved I/Q e.g. 1.0 -1.0 -1.0  1.0 ...
22                                 I    Q    I    Q  ...
23Input samples:

In this challenge the player must convert a given bit stream to QPSK Modulation. The input expected is a series of pairs of “1.0” and “-1.0” matching the given bit stream pattern.

IQ challenge solution

Without going into the math behind it, in QPSK modulation a set of two bits can be represented by the presence of a symbol at specific coordinates. The challenge provides the following bit set to coordinate mapping:

1"00" : "-1.0 -1.0"
2"01" : "-1.0 1.0"
3"11" : "1.0 1.0"
4"10" : "1.0 -1.0"

To solve the challenge take each two bits from the input stream and convert them to the corresponding pair above. The code below is my solution to the challenge using Python.

 1bits = "01000011 01110010 01101111 01101101 01110101 01101100 01100101 01101110 01110100 00001010".replace(" ","") # remove spaces
 2
 3# create dictionary to hold modulation mapping
 4modulation = { "00" : " -1.0 -1.0",
 5               "01" : " -1.0 1.0",
 6               "11" : " 1.0 1.0",
 7               "10" : " 1.0 -1.0"
 8             }
 9
10# split input into two bit symbols
11n = 2
12qbits = [bits[i:i+n] for i in range(0, len(bits), n)]
13
14# create list to hold the solution by using the bit pairs as keys and appending the values from the dictionary above
15iq=[]
16for b in qbits:
17  iq.append(modulation[b])
18
19qpsk = ''.join(iq) # convert list to string
20print qpsk.strip() # strip spaces from beginning and of string and print