Google全体を検索して、以下を回避する方法を確認しました(これは [〜#〜] dvwa [〜#〜] の高度なセキュリティからです):
<?php
if (isset($_GET['Submit'])) {
// Retrieve data
$id = $_GET['id'];
$id = stripslashes($id);
$id = mysql_real_escape_string($id);
if (is_numeric($id)){
$getid = "SELECT first_name, last_name FROM users WHERE user_id = '$id'";
$result = mysql_query($getid) or die('<pre>' . mysql_error() . '</pre>' );
$num = mysql_numrows($result);
$i=0;
while ($i < $num) {
$first = mysql_result($result,$i,"first_name");
$last = mysql_result($result,$i,"last_name");
echo '<pre>';
echo 'ID: ' . $id . '<br>First name: ' . $first . '<br>Surname: ' . $last;
echo '</pre>';
$i++;
}
}
}
?>
それを解読することは可能ですか?
また、私のもう1つの懸念は中程度のレベルです。 mysql_real_escape_string()は機能しますが、低レベルから同じSQLインジェクションを使用し、引用符を削除すると、保護がバイパスされます。何故ですか?どうしてmysql_real_escape文字列をバイパスするのがとても簡単だったのですか?
中レベルのコード(簡潔なバージョン)は次のとおりです。
$id = $_GET['id'];
$id = mysql_real_escape_string($id);
$getid = "SELECT first_name, last_name FROM users WHERE user_id = $id";
「高」の例は悪用できません。これはgoodアプローチではありません(最近のコードでは、mysql_real_escape_string
を呼び出す代わりにパラメーター化を使用します。stripslashes
はありがたいことに、魔法の引用符の時代の遺物です)ですが、すぐには脆弱にならないように設計されています。
(とにかくSQLインジェクションへ。それはis恐ろしいecho
sのおかげで、XSSの問題につながるHTMLインジェクションに対して脆弱ですが、それはまた別の話です。)
どうしてmysql_real_escape文字列をバイパスするのがとても簡単だったのですか? [中規模の例]
mysql_real_escape_string
は、SQL文字列リテラルコンテキストに含まれる場合、安全のために文字をエスケープするように設計されているためです。クエリのインジェクションポイントに単一引用符が含まれていないと、文字列リテラルコンテキストではなく、生のSQLコンテキストになります。
この状況では、SQLインジェクションは不可能です。このコードはSQLiを適切に妨げており、プラットフォームが古い場合や構成が不適切な場合でも、SQLiの影響を受けません。
...少し異なる構成では、脆弱になる可能性があります。
is_numeric()
が削除され、mysql_real_escape_string()
がaddslashes()
に置き換えられ、サーバーがGBK言語セットを使用するように構成されている場合、 可能性がありますGBK言語エンコーディングを使用したマルチバイト攻撃の例 。
ここに興味深いものがあります:DVWAの高レベルは悪用可能ではありません。これは、DVWAの作成者が当時適切と考えた概念の「正しい」安全な実装です。したがって、SQLインジェクションを高レベルで実行できないのはごく自然なことです。実際にやってみれば、何か新しい発見があるでしょう。たぶんゼロデイ。
私は何年もDVWAで遊んでおり、これを難しい方法で学ばなければなりませんでした。
DVWA 1.9より前は、DVWAは最高のセキュリティレベルとして「高」を使用していましたが、現在は「不可能」のセキュリティレベルを使用しています。したがって、「高」では、次のような入力など、他のSQLインジェクションを実行できます。 'union select user、password from users; -。後にスペースが必要であることに注意してください-そうでなければ、コマンドは構文的に間違っているでしょう。