4

だから私は二次SQLインジェクションを複製しようとしてきました。これは、私が用意した 2 つの PHP ベースのサイトのサンプル テンプレートです。それを有権者登録フォームと呼びましょう。ユーザーが登録すると、登録有権者かどうかを確認できます。

insert.php

<?php

$db_selected = mysql_select_db('canada',$conn);
if (!db_selected)
    die("can't use mysql: ". mysql_error());

$sql_statement = "INSERT into canada (UserID,FirstName,LastName,Age,State,Town)
                    values ('".mysql_real_escape_string($_REQUEST["UserID"])."',
                    '".mysql_real_escape_string($_REQUEST["FirstName"])."',
                    '".mysql_real_escape_string($_REQUEST["LastName"])."',
                    ".intval($_REQUEST["Age"]).",
                    '".mysql_real_escape_string($_REQUEST["State"])."',
                    '".mysql_real_escape_string($_REQUEST["Town"])."')";

echo "You ran the sql query=".$sql_statement."<br/>";
$qry = mysql_query($sql_statement,$conn) || die (mysql_error());
mysql_close($conn);
Echo "Data inserted successfully";
}
?>

select.php

<?php


$db_selected = mysql_select_db('canada', $conn);
if(!db_selected)
    die('Can\'t use mysql:' . mysql_error());
$sql = "SELECT * FROM canada WHERE UserID='".addslashes($_POST["UserID"])."'";
echo "You ran the sql query=".$sql."<br/>";
$result = mysql_query($sql,$conn);
$row=mysql_fetch_row($result);

$sql1 = "SELECT * FROM canada WHERE FirstName = '".$row[1]."'";
echo "The web application ran the sql query internally=" .$sql1. "<br/>";
$result1 = mysql_query($sql1, $conn);
$row1 = mysql_fetch_row($result1);

mysql_close($conn);
echo "<br><b><center>Database Output</center></b><br><br>";

echo "<br>$row1[1] $row1[2] , you are a voter! <br>";

echo "<b>VoterID: $row[0]</b><br>First Name: $row[1]<br>Last Name: $row[2]
    <br>Age: $row[3]<br>Town: $row[4]<br>State: $row[5]<br><hr><br>";
}
?>

したがって、二次 SQL インジェクションがどのように機能するかを示すために、これを意図的に脆弱にしました。ユーザーは、名前のセクションにコードを入力できます (現在行き詰まっている場所で、さまざまな方法を試しましたが、取得できないようですそれは何でもすることです)。次に、名前のセクションに挿入したコードを有効にしたい場合は、ユーザー ID を入力するだけで、コードが挿入されます。

例: insert.php ページに次のように入力します: userid = 17

firstname = (ここに何かを挿入する必要があります)

姓 = ..

年齢 = ..

町 = ..

状態 = ..

次に、詳細を確認して 17 と入力すると、挿入された SQL スクリプトがアクティブになります。これによってどのような脆弱性を示すことができるかについて、いくつかの例を得ることができますか?

4

2 に答える 2

4

実証するものは何ですか?

二次 SQL インジェクションは SQL インジェクションにすぎませんが、安全でないコードは最初の行ではありません。

したがって、実証するには:

1) エスケープせずに実行すると望ましくないことを行う SQL インジェクション文字列を作成します。

2)その文字列をDBに安全に保存します(エスケープあり)。

3) コードの他の部分でその文字列をフェッチし、エスケープせずに別の場所で使用します。

編集:いくつかのサンプルコードを追加しました:

テーブル:

CREATE TABLE tblUsers (
  userId serial PRIMARY KEY,
  firstName TEXT
)

フォームからファーストネームを受け取る、次のような SAFE コードがあるとします。

$firstname = someEscapeFunction($_POST["firstname"]);

$SQL = "INSERT INTO tblUsers (firstname) VALUES ('{$firstname }');";
someConnection->execute($SQL);

これまでのところ、 someEscapeFunction() がうまく機能すると仮定すると、うまくいきました。SQL を注入することはできません。

firstname の値として次の行を送信しても問題ありません。

ブラ'); tblUsers から削除します。///

ここで、同じシステム上の誰かが firstName を tblUsers から tblWhatever に転送したいと考え、次のようにするとします。

$userid = 42;
$SQL = "SELECT firstname FROM tblUsers WHERE (userId={$userid})";
$RS = con->fetchAll($SQL);
$firstName = $RS[0]["firstName"];

そして、エスケープせずに tblWhatever に挿入します。

$SQL = "INSERT INTO tblWhatever (firstName) VALUES ('{$firstName}');";

これで、firstname に deletecommand が含まれていても実行されます。

于 2012-10-18T10:16:07.573 に答える
3

次の名前を使用:

' OR 1 OR '

これにより、 の 2 番目の SQL で where 句が生成されます。

WHERE FirstName = '' OR 1 OR ''

したがって、結果はテーブルの最初のレコードになります。

LIMIT 句を追加すると、テーブルからすべての行を抽出できます。

' OR 1 ORDER BY UserID ASC LIMIT 0, 1 --

明らかに、一度に 1 行しか抽出されないため、これを繰り返して LIMIT の 0 をインクリメントする必要があります。この例では、コメント--を使用して残りの SQL を終了しています。そうしないと、LIMIT の後に一重引用符が追加されるため、クエリが失敗する原因となります。

上記は単純な例です。より複雑な攻撃は、information_schema を使用して DB 全体にアクセスできる UNION SELECT を使用することです。

またaddslashes()、クエリの1つで使用しています。これはmysql_real_escape_string()、PDO や MySQLi などでプリペアド ステートメントやパラメーター化されたクエリを使用する場合ほど安全ではありません。

于 2012-10-18T10:31:30.403 に答える