OrbitLink is designed to provide penetration testers and students an opportunity to apply their skills against a set of (somewhat) realistic applications that simulate the activity on a satellite control network. My experience with these networks is derived from the resources shown below as well as participating in the Hack-A-Sat competitions at DefCon.
The data used in each of these applications is broken down in resources, but more specifically a "correlated time stamp update" and "science mode" packet for TT&C was derived from a Utah State University White Paper on Satellite Telemetry. The SOSI data is a random sampling taken from SpaceTrack API using RayDay 203, 2023. For the images, the samples provided are mostly hotdog related as it is an inside joke.
OrbitLink provides a web front end and a suite of applications to simulate transmitting Telemetry Tracking and Control (TT&C) data, receiving images, and receiving Space Object Surveillance and Identification (SOSI) data.
Below is a visual represntation of the communications flow between the web gateway and each of the controls. For details on each control program see controls.md.
graph TD
a(OrbitLink Web Gateway)
b(imagery_control.py)
c(sosi_control.py)
d(ttc_control.py)
a-->d
b-->a
c-->a
Python Flask web front-end which displays information from the OrbitLink suite
/displays index.html which holds 3 iframes for/sosi,/ttc, and/imagery/sosidisplays the .json file nameddata/sosi_store.tlewhich holds all received SOSI communications and sorts the output in descending order based on timestamp/ttcdisplays the .json file nameddata/ttc.jsonwhich holds a log of all TTC commands send to the specified host and sorts the output in descending order based on timestamps in the[time_data]and[mode_data]fields respectively- Note: This page does not accurately display connectivity with the remote host, only that data is being successfully sent.
/imageryrenders the most recently received image file in theimagesdirectory- Note: The image byte code is sent in base64 encoded strings, to generate those strings you can use the following python code:
#Write images to base64 string where images is a list of image byte code for i, image_string in enumerate(images): remainder = len(image_string) % 4 if remainder != 0: image_string += '=' * (4 - remainder) image_data = base64.b64decode(image_string) output_path = 'resources/con_image{}.png'.format(i+1) with open(output_path, "wb") as binary_image: binary_image.write(image_data)
python app.py -ttc <ttc_control_ip> --headless
-ttcspecifies the IP of the destination host running the ttc_control.py application--headlessruns just the flask web server without all the listeners/senders
SOSI Data Forwarder (sender), TT&C Command Forwarder (receiver), and Imagery Forwarder (sender) Applications
-
OrbitLink Controls:
sosi.exe sosi_control -dst <orbitlink_ip>
imagery.exe imagery_control -dst <orbitlink_ip>
ttc.exe ttc_control -
All Python (in the control programs) has been written in order to be compatible with version 3.4
Below is a diagram which displays all the communications between the different controls, a simulated "space" (which is the control creating a network connection to itself), and the communications with the OrbitLink hub. Using this information, we'll create a list of methods to degrade or manipulate the data in order to render this application suite ineffective.
sequenceDiagram
participant Space
%% Group for SOSI
box "SOSI Control"
participant SOSI_Control
end
%% Group for Imagery
box "Imagery Control"
participant Imagery_Control
end
%% Group for TTC
box "TTC Control"
participant TTC_Control
end
%% Group for ORBITLINK
box "ORBITLINK"
participant ORBITLINK_SOSI
participant ORBITLINK_Imagery
participant ORBITLINK_TTC
end
%% For SOSI
Space->>SOSI_Control: TrackWrite() to Port 7073
SOSI_Control->>SOSI_Control: TrackStore() to sosi_store.tle
SOSI_Control->>ORBITLINK_SOSI: QueueWrite() to Port 7074
ORBITLINK_SOSI->>ORBITLINK_SOSI: TrackStore() on Port 7074 to data/sosi_store.tle
%% For Imagery
Space->>Imagery_Control: ImageGen() to Port 6960
Imagery_Control->>Imagery_Control: ImageStore()
Imagery_Control->>Imagery_Control: ImageQueue()
Imagery_Control->>ORBITLINK_Imagery: ImageTransport() to Port 8069
ORBITLINK_Imagery->>ORBITLINK_Imagery: ImageStore() on Port 8069
%% For TTC
ORBITLINK_TTC->>TTC_Control: CommandWrite() to Port 7474
TTC_Control->>TTC_Control: CommandRecv() on Port 7474
TTC_Control->>Space: CommandWrite() to Port 7474 (Invalid host)
- Blocking UDP port
7073onsosi_controlwill no longer allow SOSI data to be received from "space" - Blocking UDP port
8067onOrbitLinkwill no longer allow the master SOSI database to be updated - Blocking UDP port
7074onOrbitLinkwill no longer allow SOSI data to be stored - Deny write access to
sosi_store.tleonOrbitLinkwill no longer allow the web front end to display SOSI data and no new data can be stored
- Blocking UDP port
6960onimagery_controlwill no longer allow images to be generated from the data received from "space" - Deny write access to the
imagesfolder onimagery_controlwill no longer allow images to be generated from the data received from "space" - Blocking TCP port
8069onOrbitLinkwill no longer allow the master Imagery database to be updated
- Blocking UDP port
7474onOrbitLinkwill no longer allow TTC commands to be queued for transfer - Blocking UDP port
7474onttc_controlwill no longer allow TTC commands to be sent to "space"
- The SOSI data is transmitted to the
OrbitLinkdatabase via a fairly small packet which contains most of the metadata in the header. As long as a packet crafted can match the size of the header!4s4sBBIHthe distant end should parse and store the data correctly.
- The TTC commands are transmitted to the
OrbitLinkdatabase with no header. The data is either>BIfor a science mode packet or>I BB BB BB BB H Ifor a correlated time stamp packet. As long as the data is sent to the correct port with the correct size thettc_controlshould properly receive the data.
- The imagery portion would be difficult to manipulate as the images are generated via a base64 encoded string that is decoded, read, and used to generate the images on
imagery_control. However the header could be edited and additional images or metadata could be sent in transit. Too many options to list, but not worth the squeeze for manipulation.
The flask web app can be run on any Python 3.8+ client with no dependency installation required using:
python app.py -ttc <ttc_ip>
To run the web app before the clients are properly configured use the --headless flag
If you do run into dependency issues, there is a requirements.txt which lists all the required modules for orbitlink web app. Install using the included dependencies with:
cd ./orbitlink/orbitlink
pip install --no-index --find-links=dependencies -r requirements.txt
Note: The webpage has been designed for Google Chrome in order to render the iframes properly.
Manual Setup:
Install python 3.4.4
Copy python.exe from %INSTALLROOT% to C:\SOSI\sosi.exe
Copy sosi_control.py to C:\SOSI
Rename sosi_control.py to sosi_control
Run 'Site Command'
Site Command:
cd C:\SOSI
sosi.exe sosi_control -dst dst_ip
Manual Setup:
Install python 3.4.4
Copy python.exe from %INSTALLROOT% to C:\IMAGERY\imagery.exe
Copy imagery_control.py to C:\IMAGERY
Rename imagery_control.py to imagery_control
Run 'Site Command'
Site Command:
cd C:\IMAGERY
imagery.exe imagery_control -dst dst_ip
Manual Setup:
Install python 3.4.4
Copy python.exe from %INSTALLROOT% to C:\TTC\ttc.exe
Copy ttc_control.py to C:\TTC
Rename ttc_control.py to ttc_control
Run 'Site Command'
Site Commands:
cd C:\TTC
ttc.exe ttc_control
Connect to the ESXI server
Connect-VIServer -Server <ESXi_Hostname_or_IP> -User <username> -Password <password>- Upload the Python 3.4 Installer to the VM's Datastore:
$datastore = "your_datastore_name"
$localInstallerPath = "C:\path\to\python-3.4.msi"
$remoteInstallerPath = "/vmfs/volumes/$datastore/python-3.4.msi"
Set-VMHostDatastore -VMHost <ESXi_Hostname_or_IP> -Name $datastore | New-DatastoreItem -Path $remoteInstallerPath -ItemType File -SourcePath $localInstallerPath- Install Python on the VM using PowerCLI
$vmName = "Your_VM_Name"
# The path on the VM where the installer was uploaded
$vmInstallerPath = "C:\python-3.4.msi"
# Command to execute the installer
$installCmd = "msiexec.exe /i $vmInstallerPath /qb"
# Execute the command on the VM
Invoke-VMScript -VM $vmName -ScriptText $installCmd -GuestUser "windows_username" -GuestPassword "windows_password"- Clean Up (Optional)
Remove-DatastoreItem -Item $remoteInstallerPath -Confirm:$falseConnect to the ESXI server
Connect-VIServer -Server <ESXi_Hostname_or_IP> -User <username> -Password <password>- Create application directory on the VM (replace
APP,Your_VM_Name,windows_usernameandwindows_password)
$vmName = "Your_VM_Name"
# Command to create directory
$mkdirCmd = "mkdir C:\APP"
# Execute the command on the VM
Invoke-VMScript -VM $vmName -ScriptText $mkdirCmd -GuestUser "windows_username" -GuestPassword "windows_password"- Copy python.exe from C:\Python34 to application directory (replace
APP,windows_usernameandwindows_password)
$copyCmd = "Copy-Item -Path C:\Python34\python.exe -Destination C:\APP\APP.exe"
# Execute the copy command on the VM
Invoke-VMScript -VM $vmName -ScriptText $copyCmd -GuestUser "windows_username" -GuestPassword "windows_password"- Copy APP_control.py from Local Host to VM's C:\APP (replace
APP,path_on_host,windows_usernameandwindows_password)
$localFilePath = "C:\path_on_host\APP_control.py"
$vmFilePath = "C:\TTC\APP_control.py"
# Copy file to the VM
Copy-VMGuestFile -Source $localFilePath -Destination $vmFilePath -VM $vmName -LocalToGuest -GuestUser "windows_username" -GuestPassword "windows_password"- Rename APP_control.py to APP_control on the VM (replace
APP,windows_usernameandwindows_password)
$renameCmd = "Rename-Item -Path C:\APP\APP_control.py -NewName C:\APP\APP_control"
# Execute the rename command on the VM
Invoke-VMScript -VM $vmName -ScriptText $renameCmd -GuestUser "windows_username" -GuestPassword "windows_password"- On main host (replace
ttc_host)
cd orbitlink\orbitlink
python.exe app.py -ttc ttc_host- On site hosts (replace APP)
cd C:\APP
APP.exe APP_control- Included some sample data taken from Space-Track.org which shows every element (ELSET) published on the indicated Julian date, prepended by the year.
- Also included is a list of LEO, GEO, MEO, and HEO objects indicated by filename. Note, the specific orbit data is in a "3LE" three line element which indicates the name of the space object, followed by the TLE. This data is for every object in the specified group that has received an update within the past 30 days. (CAO: 20230723)
- TT&C Academic Resource: White Paper
- SpaceTrack API
- Utah State University White Paper on Satellite Telemetry section 2.2 has a table that shows the data used for measuring telemetry and could be used to make TT&C more realistic, section 3.1.3 shows the science packet breakdown, section 3.2.2 shows an overview of the overall TT&C packet
- MIT Course List on Satellite Engineering
- MIT PDF on Satellite Communications has some good information on link equations
- MIT PDF on Satellite Engineering has a high level overview of the communications
- Included sample images (mostly hotdog related), and their base64 strings named accordingly