最近、私のサイトはSQLインジェクションを介してハッキングされました。ハッカーは次のクエリを使用して私のDB名を取得しました。彼らが書いたこのクエリは理解できません。
クエリ:
=-999.9%20UNION%20ALL%20SELECT%20concat(0x7e,0x27,Hex(cast(database()%20as%20char)),0x27,0x7e),0x31303235343830303536,0x31303235343830303536,0x31303235343830303536--
クエリが実行された後、「74545883
"。
クエリの仕組みを説明できますか?
overflow attack のように見えます。既存のクエリとUNION
- edしました。 URLエンコードされているため、すべての_%20
_を(スペース)で置き換えます。
_=-999.9 UNION ALL SELECT CONCAT(0x7e,0x27,Hex(cast(database() as char)),0x27,0x7e),0x31303235343830303536,0x31303235343830303536,0x31303235343830303536-
_
それを分解する:
=-999.9
_は現在のクエリを終了しています0x31303235343830303536
_はNULL
-既存のクエリの列数と一致しているだけです。 _SELECT * FROM users
_があり、users
に4つの列がある場合、UNION
にも4つの列が必要です。その結果、彼らはそれらの列を埋めるために `NULL値を使用しました。CONCAT()
にあります。それらは、126、39、16進値としてのデータベース名、39、および126を組み合わせています。--
_はmysqlコメントです-クエリの残りを無視しますこの攻撃から判断すると、入力をmysql_real_escape_string()
でラップしておらず、攻撃してクエリから飛び出し、独自に実行することができたようです。
詳細は owasp.org を参照してください。
これは完全なクエリではなく、実際にこの文字列がWebアプリに入力されました。
ここで、最初に%20をユニオン部分の空白スペースで置き換えます。次の結果が得られます。
SELECT concat(0x7e,0x27,Hex(cast(database() as char)),0x27,0x7e),0x31303235343830303536,0x31303235343830303536,0x31303235343830303536--
ユーザーが数字を予期していた場所に文字列を配置したようです。したがって、最初にクエリの元の条件を完了するための番号(999.9)があることがわかります。次に、UNIONパーツが追加されます。最後に、UNION部分の後にコメント文字が追加され(-)、残りのクエリ(システムによって追加される可能性がある)がバイパスされます。
コードをフォーマットして理解を深めることができます。
SELECT
concat
(
0x7e,
0x27,
Hex(cast(database() as char)),
0x27,
0x7e
),
0x31303235343830303536,
0x31303235343830303536,
0x31303235343830303536
これで、結果の最初の列の部分文字列に、データベースベース名の16進数でエンコードされた形式が含まれます。実際には、一重引用符(0x27)で囲み、次に〜(0x7e)で囲みます。
クエリは DATABASE() を使用してデータベース名を返し、次に HEx() 関数を使用してこれを16進値に変換しました。
彼らがこれを手に入れたら、彼らは [〜#〜] unhex [〜#〜] 関数を使用できました
UNHEX
の例をご覧ください
mysql> SELECT UNHEX('4D7953514C');
-> 'MySQL'
mysql> SELECT 0x4D7953514C;
-> 'MySQL'
mysql> SELECT UNHEX(HEX('string'));
-> 'string'
mysql> SELECT HEX(UNHEX('1267'));
-> '1267'
彼らがどのように侵入したかを知るのは良いことですが、全体として、SQLインジェクションを回避するためにコードを修正する必要があります。
-999.9 UNION ALL SELECT
CONCAT('Hex(cast(database() as char))'),
0x31303235343830303536,
0x31303235343830303536,
0x31303235343830303536
私はあなたがログに他のエントリを持っている必要があると思います。
これは、Havijを使用したインジェクションの例です。0x7eおよび0x27は〜に対応し、 'id = 999999.9 + union + all + select + 0x31303235343830303536、(select + concat(0x7e、0x27、unhex (Hex(cast(sample_tbl.name + as + char)))、0x27,0x7e)+ from + test
。sample_tbl + Order + by + id + limit + 0,1)+-このクエリはテーブルtestのテーブルsample_tblから、列名のフィールド値である〜 'Alfred'〜をレンダリングします。
〜 'r3dm0v3_hvj_injection'〜は http://www.string-functions.com/hex-string.aspx によるHavij署名コードunhex 0x7233646D3076335F68766A5F696E6A656374696F6Eです
まず、クエリはHTMLエンコードされているように見えます。 %20
sにスペースを含めると、もう少し読みやすくなります。また、クエリの一部を何かの16進数表現に変換しています。ステートメントのその部分も16進数でデコードしてみてください。
SQLを文字列として動的に作成し、DBMSに送信しようとすると、SQLインジェクションリスクが発生します。検索バーなどで使用するためにシステムに格納されている次のような文字列を想像してください。
SELECT * FROM SOME_TABLE WHERE SOME_COLUMN=
クエリを完了して攻撃を仕掛けるには、次のように入力する必要があります。
'x' or 1=1
その場合、クエリは次のようになります。
SELECT * FROM SOME_TABLE WHERE SOME_COLUMN='x' or 1=1
SOME_COLUMN
は任意の変数にすることができ、どこで失敗するかは問題ではありません。重要なのは1=1
は常にtrueであるため、攻撃者はそのテーブルのすべての行にアクセスできる可能性があります。
これについて理解したら、コードを調べて、動的に作成されたすべてのクエリをPrepared Statementsに置き換えます。 OWASPサイトには、防御的コーディングに関するリソースもたくさんあります。