2010-11-23 26 views
4

私はSQLインジェクション攻撃についてもっと学びたいと思っています。私はその原則を理解していますが、私が実際にこれらの攻撃のいくつかを見ると、彼らは彼らが何をしているのか分かりません。SQLインジェクション攻撃のフォーマットが間違っていますか?

引用符が不揃いで、HEX文字で難読化されていることがよくあります。

私は16進数の文字を取得しません...確かに、それらはブラウザによってASCIIに翻訳されますので、何がポイントですか?

しかし、私は主に奇妙な引用によって混乱しています。私は今、例を見つけるのが苦労しているのですが、通常、声明の終わりの前にある時点で引用が終わるように見えるでしょう。

おそらく例は、このような文は何をして1または1 = 1

」の一般的な用途やっているのですか?

+0

良い質問です。私が唯一の人物であることを見て悲しいことに、SQLインジェクションの悪用にこの技術を実際に使っています。 – rook

答えて

2

私は... HEX文字を得ることはありません、 は確かに彼らは、ブラウザ

いやバック ASCIIに変換されます。

しかし、私は主に奇妙な引用を と混同しています。私は、今の例を見つけるのトラブル を持っていますが 通常 文の終わりまでにいくつかの点で引用意志 終わりは、ときに私 はそれが最後になるだろうと思っただろうと思われますか?

パラメータ置換を使用する代わりに、インラインSQLを構築するとします。特別な理由がなくても、PHPとよく似たmake-believe言語を使用します。だから、

$sql = "delete from foo where bar = '" + $param + "'"; 

、今、そのよう...

$param = "' or 1=1 --" 

(私たちは--のようなふりをしているよう$paramがブラウザによって設定されることを想像すると、ここでSQLコメント・シーケンスである。そうでない場合の方法がありますその周りも)

これで、文字列の置換が行われた後のSQLはどうなっていますか?

delete from foo where bar = '' or 1=1 --' 

fooのすべてのレコードを削除します。

これは意図的に簡単ですが、不均等な引用が何であるかについての良い考えを与えるはずです。

+1

@Rook - 答えのほとんどは、16進符号化とは関係ありません。私はちょうどブラウザについての彼の仮定を修正し、移動しました。また、私は彼の質問がmysql固有のものであるかどうか分からないので、mysql_queryに関する議論はかなり偽ります。 – Donnie

+0

これは質問に答えません。あなたが投稿したSQLインジェクション攻撃の1つを読むべきです。 – rook

2

名前欄にフォームを送信するフォームがあるとします。 nameは変数$ Nameで使用されました。あなたは、このクエリを実行します。

INSERT INTO Students VALUES ('$Name') 

それはに変換されます。

INSERT INTO Students VALUES ('Robert'); DROP TABLE STUDENTS; --') 

- コメント区切りです。その後、すべてが無視されます。 'は文字列リテラルを区切るために使用されます。

攻撃で16進文字を使用するには、いくつかの理由があります。 1つは難読化であり、もう1つは素朴なセキュリティ対策をバイパスするものです。

+0

バッチクエリは、最も普及しているSQLサーバではサポートされていません。また、唯一のコメントデリミタではありません。 MySQLは/ * ...そして、実際のクエリを隠すことができないので、難読化のための16進符号化を使用することは非常にまれです。これは主に、16進値を中心に一重引用符が不要なために使用されるため、注入が複雑な場合は引用符の数を心配する必要はなく、注入クエリ全体のロジックを整えること –

+0

これはSQL ServerのSQLインジェクションの例。これは 'mysq_query()'では決して動作せず、16進符号化にも対処しません。 – rook

+1

+1のXKCD参照:http://xkcd.com/327/ –

1

不均等引用については、考える声明

SELECT * FROM admin WHERE username='$_GET["user"]' and password='$_GET["pass"]' 

次私は、有効なユーザーが「管理者」であることがわかっている場合、私は

を以下しまいます 'or 1=1を挿入 - コーダは、単一引用符など危険な文字のためのユーザー入力をサニタイズしていないところ、SQLインジェクションが発生します
SELECT * FROM admin WHERE username='admin' and password='something' or 1=1 

これにより、パスワードの値に関係なく、式の左側が常に真となるため、結果が常にtrueに戻ります。

これはSQLインジェクションの最も単純な例です。攻撃者は引用符を使用する必要はありません。また、残りのクエリを--/*などのコメント区切り文字でコメントアウトする必要があります、注入点の後にさらに多くのパラメータが渡されている場合。

HEXエンコーディングに関しては、フィルタリングを避けるいくつかの理由があるかもしれません。クエリですべての値を引用することを心配する必要がないため、16進でエンコードされた値を使用する方が簡単です。 あなたが一緒にそうようなconcatに共同記譜二つのフィールドを使用したい場合は、このインスタンスに有用である:第三行を提供するでしょう

inject.php?id=1 and 1=0 union select 1,2,concat(username,0x3a3a,password) from admin 

はisntance admin::adminのために返す、目に見えるものです。私は進エンコーディングを使用しなかった場合、私はこれを行う必要があります:

inject.php?id=1 and 1=0 union select 1,2,concat(username,'::',password) from admin 

これは、前述のaddslashes機能を備えた、だけでなく、下手に書かれた正規表現のサニタイズ機能を持つか、非常に複雑なクエリを持っているかの問題である可能性があります。

SQLインジェクションは非常に幅広いトピックであり、私が取り上げてきたことはほとんど紹介されていません。

+0

これは質問に答えません。 – rook

+0

@Rook。それはあなたと同じように16進数では深く進まなかったが、彼はあなたがした以上に質問に答えた。私は彼が1つの話題だけではなく、全体の問題を経験したということです。 –

+0

漫画から抜粋された@ VPの回答とは違って、これは実際には本当の攻撃シナリオです。そしてそれは私のものとほとんど同じです。しかし、私はまだ 'load_file()'と 'into outfile'がもっと有用な例だと考えています。 – rook

2

SQLインジェクションで引用符を使用できない場合があります。この場合、攻撃者は文字列の16進符号化などの符号化方式を使用する必要があります。例えば、'/etc/passwd'は、引用符を必要としない0x2f6574632f706173737764と書くことができます。引用符が禁止されている脆弱なクエリの例を次に示します。 :

mysql_query("select name from users where id=".addslashes($_GET[id]));

あなたがload_file()のようにMySQLの機能を使用する場合は、進エンコーディングを使用する必要があります。

のPoC:この場合/vuln.php?id=1 union select load_file(0x2f6574632f706173737764)

/etc/passwdファイルが読み出されていると2行であろう。ここで

は、私は私のMySQLのSQLインジェクションの悪用に使用進エンコード機能のバリエーションです:

function charEncode($string){ 
    $char="char("; 
    $size=strlen($string); 
    for($x=0;$x<$size;$x++){ 
     $char.=ord($string[$x]).","; 
    } 
    $char[strlen($char)-1]=")%00"; 
    return $char; 
} 

私はexploiting HLStats 1.35ため、この正確な方法を使用します。私はを使って<?php?>をディスクに書き込むためのxssフィルタをバイパスするために私のphp nuke exploitにこの関数を使用しました。 into outfileは、関数または16進数でエンコードされた文字列への出力を受け入れないクエリ演算子であることに注意することが重要です。つまり、引用された文字列をパスとして受け入れるだけですから、上記の脆弱なクエリinto outfileは攻撃者によって使用できません。ここで、は、関数呼び出しであり、16進符号化を使用できます。

+0

Excellent回答。私は興味があります、なぜMySQLは '/ etc/passwd'として' 0x2f6574632f706173737764'を解釈しますか? –

+0

@Vincent Savard 0xは多くの言語の構文の一部です。 PHPはその値を数値として解釈します。 MySQLはascii文字列を参照しています。ここで2fは '/'で、65は文字 'e'です.74は' t'です...等々。 – rook

+0

@Rook:はい、私は約0xを知っていましたが、それが文字列として解釈されたことに驚いています(PostgreSQLの解釈は数字であり、私が知っているすべての言語もそうです)。精度をありがとう。 –

関連する問題