10
2
Fork 0
has-writeup/ground-segment/can-you-hear-me-now
Erin Moon 754f31758b wheres-the-sat 2020-06-03 17:59:52 -05:00
..
README.md wheres-the-sat 2020-06-03 17:59:52 -05:00

README.md

Can you hear me now?

Category: Ground Segment Points (final): 59 points Solves: 75

LaunchDotCom's ground station is streaming telemetry data from its Carnac 1.0 satellite on a TCP port. Implement a decoder from the XTCE definition.

Given files: telemetry.zip

Write-up

by erin (barzamin).

The provided zip file contains telemetry.xcte, an XTCE file defining the telemetry protocol streaming from the challenge server.

XTCE is a XML-based protocol description format, used to provide a machine-readable definition of the bit layout in a telemetry stream. I could use COSMOS to load this XTCE definition, but instead I just figured out what the XTCE file meant (without really reading the XTCE specification, because nobody has time for that) and wrote a quick decoder by hand. I have never touched XTCE before this and only briefly looked at CCSDS during a rocketry project for school before deciding not to use it, so any knowledge I have about it comes from things like "google" and "NASA presentations from 2008" and "definitely legitimately obtained specification pdfs".

I captured some telmetry data from the server by running

(cat THE_TICKET) | nc hearmenow.satellitesabove.me 5032 > data

telemetry.xtce describes every packet in the payload is headed by a header of the form (apparently, "abstract" things in XTCE are an instanceable template for a description of parameters; this one gets instanced in every packet as the header):

<xtce:SequenceContainer name="AbstractTM Packet Header"
                        shortDescription="CCSDS TM Packet Header"
                        abstract="true">
  <xtce:EntryList>
    <xtce:ParameterRefEntry parameterRef="CCSDS_VERSION"/>
    <xtce:ParameterRefEntry parameterRef="CCSDS_TYPE"/>
    <xtce:ParameterRefEntry parameterRef="CCSDS_SEC_HD"/>
    <xtce:ParameterRefEntry parameterRef="CCSDS_APID"/>
    <xtce:ParameterRefEntry parameterRef="CCSDS_GP_FLAGS"/>
    <xtce:ParameterRefEntry parameterRef="CCSDS_SSC"/>
    <xtce:ParameterRefEntry parameterRef="CCSDS_PLENGTH"/>
  </xtce:EntryList>
</xtce:SequenceContainer>

The parameterRefs point to xtce:Parameters in the xtce:ParameterSet nearer the top of the file; the parameters in the header are defined there as

<!-- Parameters used by space packet primary header -->
<xtce:Parameter parameterTypeRef="3BitInteger" name="CCSDS_VERSION"/>
<xtce:Parameter parameterTypeRef="1BitInteger" name="CCSDS_TYPE"/>
<xtce:Parameter parameterTypeRef="1BitInteger" name="CCSDS_SEC_HD"/>
<xtce:Parameter parameterTypeRef="11BitInteger" name="CCSDS_APID"/>
<xtce:Parameter parameterTypeRef="2BitInteger" name="CCSDS_GP_FLAGS"/>
<xtce:Parameter parameterTypeRef="14BitInteger" name="CCSDS_SSC"/>
<xtce:Parameter parameterTypeRef="2ByteInteger" name="CCSDS_PLENGTH"/>

The {n}BitInteger parameter types are defined further up in the file as exactly what you'd expect them to be. We now know what packet headers look like; let's look for something flag related. A Flag Packet is defined in several places in the file (once as an "abstract" packet, which I don't really understand the significance of); it contains a body of parameters FLAG1 through FLAG120, all defined upfile as 7-bit integers

<xtce:Parameter parameterTypeRef="7BitInteger" name="FLAGxxx"/>

The header associated with the flag packet is

<xtce:BaseContainer containerRef="AbstractTM Packet Header">
    <xtce:RestrictionCriteria>
        <xtce:ComparisonList>
            <xtce:Comparison parameterRef="CCSDS_VERSION" value="0"/>
            <xtce:Comparison parameterRef="CCSDS_TYPE" value="0"/>
            <xtce:Comparison parameterRef="CCSDS_SEC_HD" value="0"/>
            <xtce:Comparison parameterRef="CCSDS_APID" value="102"/>
        </xtce:ComparisonList>
    </xtce:RestrictionCriteria>
</xtce:BaseContainer>

The APID is specific to the flag packet; we can just search for it in the stream and decode from there. I threw together some python (using bitflags) to decode the flag from the data I recorded:

from bitstring import Bits, BitArray, ConstBitStream

b = ConstBitStream(filename='./data')
packetlocs = list(b.findall('0x0066'))
print(f"found packets:  {packetlocs}")

for loc in packetlocs:
  b.pos = loc
  ver = b.read(3).uint
  ty = b.read(1).bin
  sec_hd = b.read(1).bin
  apid = b.read(11).uint
  gp_flags = b.read(2).bin
  ssc = b.read(14).uint
  plength = b.read(16).uint

  print(ver, ty, sec_hd, hex(apid), gp_flags, ssc, plength)

  flag = []
  for i in range(120):
    flag.append(chr(b.read(7).uint))
  print(''.join(flag))

Which produced the flag:

λ ~/has/cyhmn  
» python decode.py
found packets:  [600, 1904, 3208]
0 0 0 0x66 11 1919 94
flag{delta98823mike:GAFbfoYquKzWaSFdWeYHGMDosGaBTnMbwD_kqwuj
MhhNPaA9t7Iay8GY6CdGUwrYVa_AetBJEqJ6XO1XHl0kbHA}OP`P<

Resources and other writeups