Hello.

Just taking a deviation from the KMDF drivers and sharing a writeup for the challenge “GGs” in Hack-a-Sat 4. GGs was a part of “Aerocapture the Flag”. There were a total of 4 challenges in this category, all of them focused on Orbital Mechanics problems.

Hack-a-Sat(ellite)?

Hack-a-Sat is an annual CTF competition that focuses on Satellite Exploitation. The challenges range from mathematical problems in Astrodynamics, Orbtial Mechanics, and other categories such as pwn and rev but with a flavour of space :).

The challenges were interesting and difficult. With NASA announcing the astronauts for Artemis II, space is in the air!

This was the qualification round. The finals will be held at DEFCON 23.

The Challenge

The challenge involved maintaining direction of a radio antenna on a satellite, within 10° of NADIR.

You need to connect to challenge using netcat nc ggs.quals2023-kah5Aiv9.satellitesabove.me 5300 would prompt for the ticket. Upon entering that we get the following prompt ->

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
Tx0actical@Tx0actical ~ % nc ggs.quals2023-kah5Aiv9.satellitesabove.me 5300
Ticket please:
ticket{delta276142juliet4:GAt9v1A87_*****REDACTED*****} 

Randomizing challenge with seed: 14466048559470314466

We're deploying a satellite to Geostationary orbit and our engineers told us that we dont need an ADCS system.
However, the earth observing radio sensor we are using is directional and must always be pointing close to NADIR. 

You may put the radio sensor facing any direction you want on the spacecraft
We will evaluate the satellites pointing for 10 orbits
The antenna must remain within 10 degrees of NADIR.
The launch vehcile company said they will deploy our satellite with the antenna facing NADIR and an angular velocity matching the earth's rotation
The intertia matrix for this satellite is 
 [[100   0   0]
  [  0 500   0]
  [  0   0 500]] kg-m^2
Which body fixed axis would you like to mount the antenna ( eg: x,y,z ) : 

So here’s our challenge, let’s see what we can do!

Approach

Based on the information provided, the initial orientation of the satellite is already aligned with the NADIR and has an angular velocity matching the Earth’s rotation. Therefore, we can take advantage of the satellite’s natural rotation to maintain the antenna within 10° NADIR.

To do this, we can mount the antenna along the axis with the lowest moment of inertia. From the provided inertia matrix for first satellite, it can be seen that the x-axis has the lowest moment of inertia (100 kg-m^2), followed by the y and z axes (500 kg-m^2 each).

Therefore, we would be mounting the antenna along the x-axis to take advantage of the satellite’s natural rotation and maintain the antenna pointing close to NADIR.

The expected format of the array input for this would be 1,0,0 which corresponds to the direction vector of the x-axis. Putting in the values we get ->

1
2
3
4
5
6
7
8
Normalizing the axis
Pointing axis [1. 0. 0.] NADIR.
Propegating for 10 orbits. This may take a some time...please wait
Good --- lets design another satellite.
The intertia matrix for this satellite is 
 [[448.26475545  97.29984362 -92.46784697]
  [ 97.29984362 317.00560902 173.90672699]
  [-92.46784697 173.90672699 334.72963553]] kg-m^2

Great! Now we to mount antenna for the next satellite.

To determine the axis to mount the antenna, we need to find the principal axes of the inertia matrix. The principal axes are the eigenvectors of the inertia matrix, and they represent the directions along which the moments of inertia are maximum, minimum, and intermediate.

Using a Python script or a linear algebra calculator, we can calculate the eigenvectors of the given inertia matrix.

The code I used to calculate eigenvalues and their corresponding eigenvectors ->

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import numpy as np

I = np.array([[448.26475545,  97.29984362, -92.46784697],
              [ 97.29984362, 317.00560902, 173.90672699],
              [-92.46784697, 173.90672699, 334.72963553]])

eigenvalues, eigenvectors = np.linalg.eig(I)
smallest_eigenvalue_idx = np.argmin(eigenvalues)
smallest_eigenvector = eigenvectors[:, smallest_eigenvalue_idx]

print(f"The smallest eigenvalue is {eigenvalues[smallest_eigenvalue_idx]}")
print(f"The corresponding eigenvector is {smallest_eigenvector}")

Output of this would be ->

1
2
The smallest eigenvalue is 100.00000000115942
The corresponding eigenvector is [-0.35963608  0.6763771  -0.64278761]

The eigenvectors are normalized and correspond to the x, y, and z axes of the body-fixed frame, respectively. The first eigenvector, [-0.35963608 0.6763771 -0.64278761], represents the direction with the lowest moment of inertia, and it corresponds to the x-axis.

The expected format of the array input for this would be -0.35963608,0.6763771,-0.64278761 which corresponds to the direction vector of the x-axis.

After we mount the antenna for satifying the 10° criteria for a single satellite for 10 orbits. We will be presented with another 5 intertial matrics for 5 different satellites.

Performing these steps for all satellites we get the flag after the criteria is satisfied for the last satellite ->

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
 [[454.91246281 123.87699033 -25.62460015]
  [123.87699033 159.65076628  70.40301031]
  [-25.62460015  70.40301031 485.43677091]] kg-m^2
Which body fixed axis would you like to mount the antenna ( eg: x,y,z ) :  -0.33573627,0.92242782,-0.190809
Normalizing the axis
Pointing axis [-0.33573627  0.92242782 -0.190809  ] NADIR.
Propegating for 10 orbits. This may take a some time...please wait
Good --- lets design another satellite.
The intertia matrix for this satellite is 
 [[ 417.48255604   71.73131967 -145.09468221]
  [  71.73131967  437.64491512  126.12888297]
  [-145.09468221  126.12888297  244.87252884]] kg-m^2
Which body fixed axis would you like to mount the antenna ( eg: x,y,z ) :  -0.45419556,0.39482618,-0.79863551
Normalizing the axis
Pointing axis [-0.45419556  0.39482618 -0.79863551] NADIR.
Propegating for 10 orbits. This may take a some time...please wait
Good --- lets design another satellite.
Wow I guess we didnt need the ADCS after all
flag{delta276142juliet4:GFhrhPtICA_SnmCjsTJtwt4gfJkvtrJ63JskZawC8Mzbvx3xcDpCPusLxeJZnt8sWdeVIU_HmPWoeVUNKTbij9c}
Bye...
Tx0actical@Tx0actical ~ % 

And that’s how we get the flag!

Thoughts

This was an introductry challenge with a hint of orbital physics and astrodynamics. Other challenges were more complex than this, and hence we found it impossible to progress ahead in face of extreme odds. But nonetheless, we persevered and came 115 out of some 400 teams.

Stay Tuned!

Tx0actical. Out.