← Back to Writeups
HTBN/AWeb

Orbital

XESXOR8/23/20263 min read
#web#htb#n/a

Orbital

Platform: HackTheBox | Category: Web | Difficulty: N/A | Author: D3v0o0Nu11 | Date: 2026-02-10

Description

In order to decipher the alien communication that held the key to their location, she needed access to a decoder with advanced capabilities - a decoder that only The Orbital firm possessed. Can you get your hands on the decoder?

Solution Approach

Core idea: Identify the weakness from source review or fingerprinting first. Iterate with incremental payloads instead of guessing.

Steps

  1. In this challenge we're given the source code.

  2. Let us start by analyzing the Dockerfile.

Dockerfile

FROM python:3.8-alpine

### Install packages

RUN apk add --no-cache --update mariadb mariadb-client supervisor gcc musl-dev mariadb-connector-c-dev

### Upgrade pip

RUN python -m pip install --upgrade pip

### Install dependencies

RUN pip install Flask flask_mysqldb pyjwt colorama

### Setup app

RUN mkdir -p /app
RUN mkdir -p /communication

### Switch working environment

WORKDIR /app

### Add application

COPY challenge .

### Setup supervisor

COPY config/supervisord.conf /etc/supervisord.conf

### Expose port the server is reachable on

EXPOSE 1337

### Disable pycache

ENV PYTHONDONTWRITEBYTECODE=1

### copy flag

COPY flag.txt /signal_sleuth_firmware
COPY files /communications/

### create database and start supervisord

COPY --chown=root entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
  1. Notice the "copy flag" seems to be our interest here, it seems the flag stored in /signal_sleuth_firmware directory.
  2. Next i checked the other files and found another interesting part inside entrypoint.sh file.
#!/bin/ash

### Secure entrypoint

### Initialize & Start MariaDB

mkdir -p /run/mysqld
chown -R mysql:mysql /run/mysqld
mysql_install_db --user=mysql --ldata=/var/lib/mysql
mysqld --user=mysql --console --skip-networking=0 &

### Wait for mysql to start

while ! mysqladmin ping -h'localhost' --silent; do echo 'not up' && sleep .2; done

function genPass() {
    echo -n 'ichliebedich' | md5sum | head -c 32
}

mysql -u root << EOF
CREATE DATABASE orbital;
CREATE TABLE orbital.users (
    id INTEGER PRIMARY KEY AUTO_INCREMENT,
    username varchar(255) NOT NULL UNIQUE,
    password varchar(255) NOT NULL
);
CREATE TABLE orbital.communication (
    id INTEGER PRIMARY KEY AUTO_INCREMENT,
    source varchar(255) NOT NULL,
    destination varchar(255) NOT NULL,
    name varchar(255) NOT NULL,
    downloadable varchar(255) NOT NULL
);
INSERT INTO orbital.users (username, password) VALUES ('admin', '$(genPass)');
INSERT INTO orbital.communication (source, destination, name, downloadable) VALUES ('Titan', 'Arcturus', 'Ice World Calling Red Giant', 'communication.mp3');
INSERT INTO orbital.communication (source, destination, name, downloadable) VALUES ('Andromeda', 'Vega', 'Spiral Arm Salutations', 'communication.mp3');
INSERT INTO orbital.communication (source, destination, name, downloadable) VALUES ('Proxima Centauri', 'Trappist-1', 'Lone Star Linkup', 'communication.mp3');
INSERT INTO orbital.communication (source, destination, name, downloadable) VALUES ('TRAPPIST-1h', 'Kepler-438b', 'Small World Symposium', 'communication.mp3');
INSERT INTO orbital.communication (source, destination, name, downloadable) VALUES ('Winky', 'Boop', 'Jelly World Japes', 'communication.mp3');
CREATE USER 'user'@'localhost' IDENTIFIED BY 'M@k3l@R!d3s$';
GRANT SELECT ON orbital.users TO 'user'@'localhost';
GRANT SELECT ON orbital.communication TO 'user'@'localhost';
FLUSH PRIVILEGES;
EOF

/usr/bin/supervisord -c /etc/supervisord.conf
  1. The admin creds hardcoded, the strings stored as the password is from the genPass() call.

  2. As we can see from the Dockerfile, the password must be -> ichliebedich.

  3. Open the web app.

  4. Looks like the intended solution is SQL Injection to retrieve the admin password.

  5. Anyway let us enter the creds.

  6. Tried to click every nav options but does not redirect me to another page, the only thing work is the logout option.

  7. Then i tried to click everything until i found the exported button is functional.

  8. It pops us to download a mp3 music, which means it do some request, let us intercept the request and tamper it using Burp Suite.

NOTES: The mp3 does not relevant to this challenge.

  1. Send it to repeater and change the json "name" value to our flag location using LFI.

  2. Actually there's many known methods to bypass the filter for LFI. I used these:

  3. Succeed to receive the flag using this method --> ....//signal_sleuth_firmware.

  4. Got the flag!

Flag

REDACTED

Lessons Learned

  1. Identify the weakness from source review or fingerprinting first.
  2. Iterate with incremental payloads instead of guessing.
  3. Reuse the same pattern in future engagements.