システム環境
dvwa上のインターネット関連情報は比較的古いので、私は、脆弱性の再住むそれぞれの種類しばらくdvwa、ついでに初期エントリPHPコードの監査関連の知識にしたいです。設置環境は、直接オンラインチュートリアル参照することができます初心者のためのガイドを:あなた自身の侵入テスト環境を構築する方法をあなたに教え、私たちは非常に詳細に書かれているし、ステップバイチュートリアルのステップに従って直接インストールすることができます。
簡単な紹介
SQLインジェクションは、それはSQLインジェクションでは、悪質なSQL文を実行するための目的を達成するために、SQLクエリ文の構造を破壊し、悪質なSQLコマンドを注入することにより、攻撃者を指します。SQLインジェクションの脆弱性被害が甚大で、多くの場合、データベース全体が「オフパンツ」である原因は、しかし、SQLインジェクションは、今も最も一般的なWeb脆弱性の一つです。別の後に非常に最近の火災事件の大使館が黒で、それはハッカーであることをすると、一般的なSQLインジェクションの脆弱性に依存することであると述べました。
アイデアのマニュアル注入
、SQLMAPもちろん使いやすいアーティファクトを自動化されたが、それでも手を注入し、手動の注入に続いては、ステップのいくつかを説明するいくつかのアイデアを持っている必要があります。
1は、注射があるかどうかを判断し、注入は、文字または数値である
フィールドのSQLクエリステートメント推測2.ソリューション
フィールドの表示順序を決定する3.
4.現在のデータベースを取得
データベーステーブルを取得5.
6.捕捉テーブルは、フィールド名
7.ダウンロードデータ
4レベルのコード分析以下
低サーバ側コアコード
<?php
if( isset( $_REQUEST[ 'Submit' ] ) ) {
// Get input
$id = $_REQUEST[ 'id' ];
// Check database
$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
// Get results
while( $row = mysqli_fetch_assoc( $result ) ) {
// Get values
$first = $row["first_name"];
$last = $row["last_name"];
// Feedback for end user
echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
}
mysqli_close($GLOBALS["___mysqli_ston"]);
}
?>
任意のチェックおよび濾過明白なSQLインジェクションせずに、クライアントからのパラメータID低レベルのコードを見ることができます。
エクスプロイト
は、次の手順をに基づいてソースコードを見ることができない手動注入で推奨されているように、現実のシナリオでは、バックエンドのコードを参照することはできません
が注入されているかどうかを判断1.、注入は、文字または数値であります
入力し
1'or'1'='1
たクエリの成功を。
入力し
1'and'1'='2
たクエリが失敗し、リターンはnull
プレゼンス噴射示す文字
2. SQLクエリ溶液中のフィールドの数を推測する
推測により順序によって
入力1'or 1#によって1 = 1ため 、 クエリが成功しました
2#による1'or 1 = 1順序を入力し、クエリが成功します
入力を続行し、1'or 3#による1 = 1順序、クエリが失敗します
2つのフィールドのみでのSQLクエリの実行の説明は、これは、姓最初の名前です。ここにも労働組合を入力フィールドの数を推測するために1,2,3 ...ソリューションを選択することができます
のフィールドの表示順序を決定する3
入力1「組合を1,2#を選択し、クエリが成功しました。
表ID =「ID」....から姓SQL文の最初の名前SELECT、するための手順
4.現在のデータベースゲット
入力1「組合は1、データベース(選択 )#を、 クエリが成功します。
現在のデータベースはdvwaです。
データベース内の捕捉テーブル
入力1「組合1、GROUP_CONCAT(選択 TABLE_SCHEMA =データベース()#INFORMATION_SCHEMA.TABLESからTABLE_NAME)を、 クエリが成功し
2つのデータベースのテーブルには、ユーザーは、ゲストブックの、現在ありません。
テーブルのフィールド名を取得6
入力1「組合は1、GROUP_CONCAT(選択ユーザー#TABLE_NAME = information_schema.columnsからCOLUMN_NAME)」を、 クエリが成功しました。
テーブルには8つのフィールド、それぞれのuser_id、FIRST_NAME、LAST_NAME、_user、パスワード、アバター、LAST_LOGIN、failed_loginを持っています。
7.ダウンロードしたデータ
入力1「または1 = 1組合選択 GROUP_CONCAT(user_idは、FIRST_NAME、LAST_NAME)、GROUP_CONCAT(パスワードを)のユーザー#から、クエリが成功します
ミディアムコアコード・サーバー
<?php
if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
$id = $_POST[ 'id' ];
$id = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $id);
$query = "SELECT first_name, last_name FROM users WHERE user_id = $id;";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query) or die( '<pre>' . mysqli_error($GLOBALS["___mysqli_ston"]) . '</pre>' );
// Get results
while( $row = mysqli_fetch_assoc( $result ) ) {
// Display values
$first = $row["first_name"];
$last = $row["last_name"];
// Feedback for end user
echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
}
}
// This is used later on in the index.php page
// Setting it here so we can close the database connection in here like in the rest of the source scripts
$query = "SELECT COUNT(*) FROM users;";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
$number_of_rows = mysqli_fetch_row( $result )[0];
mysqli_close($GLOBALS["___mysqli_ston"]);
?>
フロントページは、ユーザーの希望を制御するために、ドロップダウン選択形式を提供しながら、\のX1Aはエスケープ、中レベルの特殊記号\ X00をmysql_real_escape_stringの機能を使用してコード、\ nは、\ rを,,」、」見ることができます入力。
エクスプロイト
フロントエンドは、ドロップダウン選択メニューを使用しますが、我々はまだ不正なクエリパラメータを提出し、キャプチャによってパラメータを変更することができますが。
1注射があるか否かを判定する、注射は、文字や数字、ある
捕捉パラメータIDは1「または1 = 1#、所定の変更します
エーテル、クエリが成功したパラメータIDが1または1 = 1#で変更
説明は、デジタル型インプラントです。(それはデジタル型インプラントであるので、デジタル型インプラントは、引用符を使用する必要がないため、サーバ側mysql_real_escape_stringの関数は、空になるであろう。ので)
2. SQLクエリ溶液中のフィールドの数を推測
EtherealのパラメータIDを変更することは、3#によって1次ですエラー
SQLクエリの実装では、ステートメント中国の2つのフィールドのみ、すなわち、ここでは最初の名前、姓をフィールド。
3のフィールドの表示順序を決定する
1,2#を選択するパラメータID 1つの組合を変更するには、キャプチャを、クエリが成功しました。
SQLステートメントの実装はまず名前、テーブルのID = IDから姓を選択するために.... WHERE
4.取得し、現在のデータベースの
1つの組合へのキャプチャidパラメータの変更は1、データベース()を選択し 、#をクエリが成功しました。
dvwaの現在のデータベースの説明。
データベーステーブルへのアクセス
エーテルTABLE_SCHEMA =データベース()#INFORMATION_SCHEMA.TABLESからGROUP_CONCAT(TABLE_NAME)、パラメータIDは1つの組合は、1を選択している変更、クエリが成功しました。
二つのテーブルdvwa説明データベース、およびゲストブックのユーザー
テーブル取得の6フィールド名
パラメータID 1組合へのキャプチャの変更1を選択し、GROUP_CONCAT(COLUMN_NAME information_schema.columns TABLE_NAME =「ユーザー」#から)、 クエリが失敗しました。
単一引用符ので「に変換されます。図16は、パラメータIDの変更キャプチャするために、バンドをバイパスするために利用することができる
GROUP_CONCAT(COLUMN_NAME、1を選択1組合を TABLE_NAME = 0×7573657273#information_schema.columnsから)
説明ユーザテーブルは8つのフィールド、それぞれのuser_id、FIRST_NAME、LAST_NAME、ユーザー、持っている パスワード、アバター、last_login、failed_loginを。
7.ダウンロードデータの
パラメータIDを変更するには、キャプチャが1または1 = 1組合選択GROUP_CONCATあるユーザー#から(user_idは、FIRST_NAME、LAST_NAME)、GROUP_CONCAT(パスワード)、 クエリが成功します。
これは、FIRST_NAME、LAST_NAME、パスワードデータをUSER_IDすべてのユーザーのユーザーテーブルになりました。
ハイサーバー側のコアコード
<?php
if( isset( $_SESSION [ 'id' ] ) ) {
// Get input
$id = $_SESSION[ 'id' ];
// Check database
$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>Something went wrong.</pre>' );
// Get results
while( $row = mysqli_fetch_assoc( $result ) ) {
// Get values
$first = $row["first_name"];
$last = $row["last_name"];
// Feedback for end user
echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
}
((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
?>
これは、中レベルのコードに比べて見ることができ、ハイレベルの出力だけに一つだけの結果を制御することを期待して、SQLクエリ文で空腹LIMIT 1を追加します。
エクスプロイトは、
LIMIT 1を加算しながら、しかし、低レベルに似たので直接のデモ最後のステップ手動注入プロセスは、データ、入力1または1 = 1組合選択GROUP_CONCATをダウンロードするので、我々は#は、それをコメントアウトすることができます (user_idは、FIRST_NAME、LAST_NAME ユーザーから)、GROUP_CONCAT(パスワード) #、 クエリが成功しました
特別な言及が表示されたページが同じではありませんハイレベルなクエリの提出と、検索結果ページで、また302回のジャンプを実行し、目的はありませんで、注入プロセスの間にSQLMAPため、一般的なSQLMAPインジェクションを防ぐためです提出されたクエリの結果ページ上のクエリは、何のフィードバック、およびなし、さらに注射アプローチがありません。
インポッシブルサーバーのコアコード
<?php
if( isset( $_GET[ 'Submit' ] ) ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// Get input
$id = $_GET[ 'id' ];
// Was a number entered?
if(is_numeric( $id )) {
// Check the database
$data = $db->prepare( 'SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;' );
$data->bindParam( ':id', $id, PDO::PARAM_INT );
$data->execute();
$row = $data->fetch();
// Make sure only 1 result is returned
if( $data->rowCount() == 1 ) {
// Get values
$first = $row[ 'first_name' ];
$last = $row[ 'last_name' ];
// Feedback for end user
echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
}
}
}
// Generate Anti-CSRF token
generateSessionToken();
?>
あなたは「Tuokuを防ぐ効果的に、出力は成功します、クエリ結果の数は一瞬だけ返されながら、効果的に、SQLインジェクションを防ぐため、コードとデータのラインを引かれ、インポッシブルレベルのコードはPDO技術を使用して、見ることができます」、アンチCSRFtokenメカニズムは、さらに安全性を向上させるために添加します。