Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

HTB First Contact - Automatic Satellite Visibility Solver

English | Español

Automatic solver for the First Contact challenge from Hack The Box.

The challenge provides a Two-Line Element (TLE) describing a satellite and the geographic coordinates of a ground station. The objective is to determine the time windows during the next 24 hours when the satellite is visible from the station.

The satellite is considered visible when its elevation is greater than 30° above the horizon.

This project automates the entire process:

HTB server
    │
    ▼
Receive TLE + ground station coordinates
    │
    ▼
Parse challenge
    │
    ▼
Create satellite model
    │
    ▼
Propagate satellite orbit
    │
    ▼
Calculate visibility events
    │
    ▼
Filter elevation > 30°
    │
    ▼
Generate RISE / SET timestamps
    │
    ▼
Send answer through TCP
    │
    ▼
Receive next challenge

Challenge

The HTB service sends challenges in the following format:

Challenge Sat 1
TLE:
DIGITWIN HTB
1 01337U ...
2 01337 ...

Station location:
(Lat,Long): 54.680197746339395,69.98725738496918

When will it be visible next?>

The answer must contain the timestamps of the visibility windows as space-separated UTC timestamps:

2026-08-27T05:34:30Z 2026-08-27T05:37:56Z ...

The server can send multiple satellite challenges sequentially, so solving them manually is inconvenient. The solver therefore keeps the TCP connection open and automatically processes every challenge.

Requirements

  • Python 3
  • sgp4
  • skyfield

Dependencies:

sgp4
skyfield

Installation

Kali Linux may prevent installing Python packages globally because of PEP 668 (externally-managed-environment).

For this reason, the project uses a Python virtual environment.

sudo apt update
sudo apt install -y python3-venv

Create the virtual environment:

python3 -m venv .venv

Activate it:

source .venv/bin/activate

Install the dependencies:

pip install -r requirements.txt

Alternatively:

pip install sgp4 skyfield

Verify the installation:

python -c "from skyfield.api import EarthSatellite, Topos, load; print('Skyfield OK')"

Running the solver

Run:

python3 solver.py

The solver establishes the TCP connection with the HTB service and waits for the first challenge.

Example:

[+] Connecting to 154.57.164.77:31594
[+] Connected
[+] Automatic solver active

When the server sends a challenge, the solver automatically extracts:

  • TLE line 1
  • TLE line 2
  • Ground station latitude
  • Ground station longitude

It then calculates the visibility windows and sends the result automatically.

Example:

[+] Challenge detected
[+] Latitude : 54.680197746339395
[+] Longitude: 69.98725738496918
[+] Calculating visibility...

[+] Answer:
2026-08-27T05:34:30Z 2026-08-27T05:37:56Z 2026-08-27T07:12:57Z 2026-08-27T07:16:28Z ...

[+] Answer sent!
[+] Waiting for next challenge...

If the answer is correct:

Correct!
Challenge Sat 2
...

The process continues automatically until the server closes the connection.


How the calculation works

1. Two-Line Element (TLE)

The satellite is described using a Two-Line Element set.

A TLE contains orbital parameters that describe the satellite's orbit at a specific epoch.

For example:

1 01337U 00000A   26239.16548611+.00000000  00000-0  19815-5 0 281  1
2 01337  55.9855  39.9692 0066508  37.0687  40.3667 15.18600202207153

Important parameters include:

  • Inclination
  • Right ascension of the ascending node
  • Eccentricity
  • Argument of perigee
  • Mean anomaly
  • Mean motion
  • Epoch

The TLE is not simply a set of static coordinates. It is an orbital model that must be propagated to obtain the satellite's position at future times.

2. SGP4 propagation

The SGP4 (Simplified General Perturbations 4) model is used to propagate the satellite orbit from the TLE epoch to a requested time.

Conceptually:

TLE + time
     │
     ▼
   SGP4
     │
     ▼
Satellite position
and velocity

The sgp4 library implements the SGP4 propagation algorithm.

The raw SGP4 output is expressed in the TEME reference frame. Converting that information into useful observer-relative coordinates requires additional astronomical/geodetic calculations. Skyfield provides this higher-level functionality.

3. Ground station

The challenge provides:

Latitude
Longitude

For example:

Lat = 54.680197746339395
Lon = 69.98725738496918

These coordinates represent the observer on Earth's surface.

The solver creates a Skyfield Topos object:

station = Topos(
    latitude_degrees=lat,
    longitude_degrees=lon
)

This allows the satellite's position to be evaluated relative to the ground station.

4. Elevation angle

The important quantity for the challenge is the elevation angle.

The elevation describes how high the satellite appears above the local horizon.

Conceptually:

                 Satellite
                    *
                   /|
                  / |
                 /  | elevation
                /   |
---------------*----+
            Station
          Horizon

The challenge defines visibility as:

elevation > 30°

Therefore, the relevant threshold is:

ELEVATION = 30.0

5. Finding visibility events

Instead of manually sampling the satellite position every second, the solver uses:

satellite.find_events(
    station,
    t0,
    t1,
    altitude_degrees=30.0
)

Skyfield searches the requested time interval for events where the satellite crosses the specified elevation.

The returned event types are:

0 → rise above 30°
1 → culmination
2 → set below 30°

Therefore:

RISE
  │
  ▼
Satellite crosses 30°
  │
  ▼
CULMINATION
  │
  ▼
Satellite reaches its maximum elevation
  │
  ▼
SET
  │
  ▼
Satellite falls below 30°

The challenge only requires the beginning and end of each visibility window, so culmination events are discarded.

For example:

RISE          CULMINATION          SET
  │                 │                │
  ▼                 ▼                ▼
05:34:30          05:36:10         05:37:56

The answer therefore contains:

05:34:30 05:37:56

6. Next 24 hours

For every challenge, the solver creates a time interval:

now = datetime.now(timezone.utc)
end = now + timedelta(hours=24)

This means the calculation is performed relative to the current UTC time.

The resulting interval is passed to find_events():

t0 = ts.from_datetime(now)
t1 = ts.from_datetime(end)

Only events inside this 24-hour interval are considered.

7. Current visibility window

The challenge explicitly allows the current visibility window to be skipped.

Therefore, if the satellite is already above 30° when the calculation begins, the first relevant event may be:

SET

The solver does not output that incomplete window.

Instead, it waits for the next:

RISE → SET

pair.

This prevents the answer from containing a visibility window that started before the requested calculation interval.


Automatic TCP interaction

The solver does not require manually running nc.

It creates the TCP connection directly from Python:

sock = socket.create_connection(
    (HOST, PORT),
    timeout=10
)

The server's response is continuously read:

data = sock.recv(4096)

The received data is stored in a buffer.

When the solver detects:

When will it be visible next?>

it knows that the challenge is ready to be solved.

The challenge is parsed using regular expressions to extract the TLE and station coordinates.

After calculating the answer, it is immediately sent back:

sock.sendall(
    (response + "\n").encode()
)

The buffer is then cleared and the solver waits for the next satellite.

This creates the following loop:

Receive challenge
      ↓
Parse TLE
      ↓
Parse coordinates
      ↓
Calculate 24-hour visibility
      ↓
Generate timestamps
      ↓
Send answer
      ↓
Wait for next challenge
      ↓
Repeat

Why Skyfield?

It would be possible to use the low-level sgp4 library directly, but that would require implementing additional calculations for the observer's position, Earth rotation, coordinate transformations, and topocentric altitude.

Skyfield is built around astronomical calculations and provides a higher-level interface for working with Earth satellites and observer locations.

The important call for this challenge is:

satellite.find_events(
    station,
    t0,
    t1,
    altitude_degrees=30.0
)

This directly matches the problem definition.

Result

The solver successfully automated the complete HTB First Contact challenge.

It processed multiple dynamically generated TLEs and ground station locations, calculated the corresponding visibility windows, submitted the answers automatically, and completed the challenge.

Correct!
Correct!
Correct!

HTB challenge completed.

References

Disclaimer

This repository is intended for educational purposes and for use with authorized Hack The Box laboratory environments.

The solver is designed specifically for the HTB First Contact challenge.

About

Automatic solver for Hack The Box First Contact, calculating satellite visibility windows from TLE data and ground station coordinates.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages