Hack-A-Sat 2020 CTF

By Michael Milvich
Hack-A-Sat 2020 CTF

Hack-A-Sat 2020

Hello! I am Michael Milvich and I recently joined Anvil's embedded security group. I have been a computer security consultant for over fifteen years with a focus on embedded systems, starting out with hacking SCADA and ICS systems at the Idaho National Laboratory for the Department of Energy. After which, I moved to Seattle and worked for IOActive where I broadened my infosec horizon to encompass a wide variety of embedded systems across many industries. During this time I have participated in many Capture The Flag (CTF) competitions (competitions with computer security challenges) with my friends as well as with both current- and former co-workers from my professional life as the ACMEPharm team. When the ACMEPharm team saw the Hack-A-Sat 2020 CTF announcement we were immediately attracted to it. Satellites? How could we not participate?

Hack-A-Sat 2020 CTF took place last weekend from May 22nd 5:00 PM PDT and ran for 48 hours straight. We thoroughly enjoyed the challenges and thought the organizers did an outstanding job assembling the challenges and running the contest. I decided to write up some walkthroughs on some of the challenges I worked on that were my favorite:

  • I see what you did there
  • SpaceDB
  • Vax the Sat
Those were my favorites (sorry XTCE challenges)! This post will provide a brief overview of these challenges and link to more detailed descriptions and walkthroughs on how to solve them at the ACMEPharm GitHub repository. A lot of people helped out with these challenges so I want to stress that this was the combined work of the entire ACMEPharm team and that people from different information security industry companies as well as completely different backgrounds were all involved with hacking on this CTF for the past weekend.

I see what you did there

I picked this challenge because it combined side channel attacks, something we would do against an embedded system, with satellite orbit tracking. Here is the description of the challenge from the organizers:

Your rival seems has been tracking satellites with a hobbiest antenna, and it's causing a lot of noise on my ground lines. Help me figure out what he's tracking so I can see what she's tracking.

The challenge provided a two set of signal files containing the RF emissions recorded from control cables used to control the antenna's azimuth and elevation angles. The first set was a set of known signals, that is the satellite the antenna was following at the time the captures were made is known. A second set contained unknown signals where the satellite the antenna was following while the captures were made is unknown. The challenge is to find out which satellite the antenna was pointing at while the unknown captures were being made. Basically we had to turn a signal looking something like this:

Into a satellite name, such as CANX-7.

To solve this problem we:

  1. Wrote a script to recover the PWM signal from the captured signal files.
  2. Converted the PWM into azimuth and evolution degrees.
  3. Found all the satellites that the antenna was pointing at.
  4. Since there could be multiple satellites at differing altitudes, we repeated steps 2 & 3 a few times until only one satellite was visible at every observation.
To read the full writeup of this challenge go here ACMEPharm GitHub: I see what you did there:

SpaceDB

The next challenge I wrote a walk-through for was the SpaceDB challenge. This challenge was based on Kubos and I found it interesting, as it was my first exposure to satellite mission planning.

This time the problem was presented to us as a failed "over-the-space" update challenge.

The last over-the-space update seems to have broken the housekeeping on our satellite. Our satellite's battery is low and is running out of battery fast. We have a short flyover window to transmit a patch or it'll be lost forever. The battery level is critical enough that even the task scheduling server has shutdown. Thankfully can be fixed without without any exploit knowledge by using the built in APIs provied by kubOS. Hopefully we can save this one!

Can we save the satellite before it runs out of power? Of course! But the path was full of twist and turns. To solve this challenge we:

  1. First figured out what Kubos is and how it works.
  2. Spoofed data into the telemetry database to trick the system into thinking it had more battery power than it did. This caused the satellite to launch the scheduling service.
  3. Used the scheduling service to modified the existing mission schedules to:
    1. "Fix" the bug caused by the update and ensure the satellite would point to the sun in order to charge its batteries.
    2. Transmit the flag to the ground station during the small window of time when the satellite was within communication range of the ground station.
Click the link to read the full writeup: ACMEPharm GitHub: SpaceDB.

Vax the Sat

This challenge was frustrating! I cannot resist old obsolete computer architectures. So, although frustrating, this challenge was too intriguing to pass. There was no way I was not going to solve this challenge! We did eventually solve it, unfortunately it was after the CTF completed so it didn't count towards ACMEPharm's final score.

The challenge presents you with a foothold on a satellite ground station network with access to a client system. With compromised credentials we connected to a service running on a server that communicates to a satellite allowing us to command the satellite:
.--.                 .--.                                     }-O-{
|__| .--------.      |__| .--------.      ,--..Y   ) ) )       [^]
|=.| |.------.|      |=.| |.------.|      \   /`.        _____/o o\_____
|--| ||CLIENT|| <--> |--| ||SERVER|| <-->  \.    \      ^""""":{o}:"""""^
|  | |'------'|      |  | |'------'|       |"""--'             /.\
|__|~')______('      |__|~')______('       / \                 \_/
     10.0.0.21            10.0.0.20
The service provides an ACSII base satellite UI:
##############################################################################
#                # RSSI -80dBm               .-"-.         #                 #
# EPS STAT:  [1] #                          /     \        # OBC STAT:  [1]  #
#   COM  PWR [*] #                 }--O--{  |#    |        #                 #
#   OBC  PWR [*] #                   [^]     \___/         #                 #
#   ADCS PWR [ ] #                  /ooo\     ^\           #                 #
#                #  ______________:/o   o\:_____)________  #                 #
#                # |=|=|=|=|=|=|:A|":|||:"|A:|=|=|=|=|=|=| #                 #
#                # ^--------------!::{o}::!--------------^ #                 #
# COM STAT:  [1] #                 \     / /               # ADCS STAT: [3]  #
#                #       ____       \.../ )     ____       #                 #
#                #      |\/\/|=======|*|=======|\/\/|      #                 #
#                #      :----"       /-\       "----:      #                 #
#                #                  /ooo\                  #                 #
#                #                 #|ooo|#                 #                 #
#                #                  \___/                  #                 #
#                # LAT: 38.897789      LONG: -77.036301    #                 #
##############################################################################
# HELP  ADCS RST  ADCS NOOP  ADCS STATE  ADCS CFG  ADCS CFG_POS  EPS RST     #
# EPS NOOP  EPS STATE  EPS CFG COM RST COM NOOP COM STATE  OBC RST  OBC NOOP #
# INFO:                                                                      #
# ERROR:                                                                     #
##############################################################################
COMMAND $

The stated goal of the challenge was to hijack the satellite point the satellite at a specific location on the ground, a supposedly abandoned United States Air Force (USAF) radio station in the middle of the desert.

After a going through the ASCII UI we initially thought the goal of the challenge was to figure out an authenticating checksum that appeared to be needed in order to run the ADCS CFG_POS command and set the location the satellite was pointing at. Little did we know! It turns out the checksum algorithm was:
  • Written in VAX assembly.
  • Implemented a virtual machine (admittedly a tiny VM with only one opcode).
  • The checksum algorithm was actually implemented in instructions for this VM.
  • Most coordinate and checksum inputs end up causing the emulated checksum algorithm to enter an infinite loop and never exit (for days we thought we had something wrong in our simulator)!
  • The actual checksum didn't matter! The code implements a classic strlen(), strncmp() flaw that leads to a direct shortcut to printing out the flag:
if (strncmp(passphrase, computed_checksum, strlen(computed_checksum)) == 0) {
    printf("%s\n", flag);
}
That was a lot to work through and we didn't make it in time for the contest. Read all our frustrations by clicking on the link to read the full writeup: ACMEPharm GitHub: Vax the Sat.

Closing Thoughts

I really enjoyed the Hack-A-Sat 2020 CTF, thanks go to the US Air Force, Defense Digital Service, and the Defcon Aerospace Village for presenting the Hack-A-Sat contest. I like CTFs as they allow me to broaden my experiences and allow me to learn. Hack-A-Sat was no different, during this CTF I got to:
  • Pretend I am an aerospace engineer and calculate the orbit of satellites and their relationships to ground locations.
  • Pretend I am a mission designer and program satellites to perform a sequence of events.
  • Discovered the excellent Skyfield python library for doing orbital calculations.
  • Interacted with a Kubos system and created a new mission using an exposed GraphQL endpoint.
  • Was exposed to the XTCE (XML Telemetric and Command Exchange) standard for describing spacecraft telemetry and command structures and write my own decoder/encoder to solve a few challenges.
  • Discovered that many, if not all the open source mission planning on control software is very finicky about OS versions. I had difficulty installing most of them, hence the need to write my own XTCE encoder/decoder.
  • Realized the importance of power. Almost all of the challenges involving a satellite had some component that required addressing power, either shutting down or powering on modules, charging batteries, pointing solar panels, etc...
I am looking forward to next year! Hopefully, there will be a Hack-A-Sat 2021! Thanks again to all the ACMEPharm folks who came out and joined in!

About the Author

Michael Milvich is a Fellow at Anvil Secure. Prior to joining Anvil, Michael worked as a Senior Principal Consultant IOActive Inc, and as a Cyber Security Researcher at Idaho National Laboratory (INL). Michael got his start in embedded security hacking SCADA and ICS systems and later broadened to encompass a wide variety of embedded systems across many industries. Michaelโ€™s strong technical background combined with his years of general consulting have been utilized to assist some of the leading technologies and most advanced security groups in improving their security posture.

Tools

awstracer - An Anvil CLI utility that will allow you to trace and replay AWS commands.


awssig - Anvil Secure's Burp extension for signing AWS requests with SigV4.


dawgmon - Dawg the hallway monitor: monitor operating system changes and analyze introduced attack surface when installing software. See the introductory blogpost


nanopb-decompiler - Our nanopb-decompiler is an IDA python script that can recreate .proto files from binaries compiled with 0.3.x, and 0.4.x versions of nanopb. See the introductory blogpost


ulexecve - A tool to execute ELF binaries on Linux directly from userland. See the introductory blogpost

Recent Posts