DVWA SQL Injection 過關秘籍.
LOW
1if( isset( $_REQUEST[ 'Submit' ] ) ) {
2 // Get input
3 $id = $_REQUEST[ 'id' ];
4
5 // Check database
6 $query = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
7 // 並沒有做什麼注入防護
8 // 嘗試構造:
9 // select first_name, last_name from from users where user_id = '1' and 1=1;
10 // select first_name, last_name from from users where user_id = '1' and 1=2;
11 // select first_name, last_name from from users where user_id = '1' or 1=1;
12
13 $result = mysql_query( $query ) or die( '<pre>' . mysql_error() . '</pre>' );
14
15 // Get results
16 $num = mysql_numrows( $result );
17 $i = 0;
18 while( $i < $num ) {
19 // Get values
20 $first = mysql_result( $result, $i, "first_name" );
21 $last = mysql_result( $result, $i, "last_name" );
22
23 // Feedback for end user
24 echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
25
26 // Increase loop count
27 $i++;
28 }
29
30 mysql_close();
31}
Medium
1if( isset( $_POST[ 'Submit' ] ) ) {
2 // Get input
3
4 // 換成了Post 這也太普通了
5 // 使用一些網絡請求工具照樣改,比如BurpSuite,PostMan,curl.
6 $id = $_POST[ 'id' ];
7 $id = mysql_real_escape_string( $id );
8 // mysql_real_escape_string 可以對以下字符進行轉義
9 // \x00, \n, \r, \, ', " 和 \x1a.
10 // 值得注意的是 mysql_real_escape_string 函數所在的MYSQL擴展在
11 // PHP 5.5.0 起已廢棄,並在自 PHP 7.0.0 開始被移除。
12
13 // Check database
14 $query = "SELECT first_name, last_name FROM users WHERE user_id = $id;";
15 // 嘗試構造:
16 // SELECT first_name, last_name FROM users WHERE user_id = 1 or 1=1;
17
18 $result = mysql_query( $query ) or die( '<pre>' . mysql_error() . '</pre>' );
19
20 // Get results
21 $num = mysql_numrows( $result );
22 $i = 0;
23 while( $i < $num ) {
24 // Display values
25 $first = mysql_result( $result, $i, "first_name" );
26 $last = mysql_result( $result, $i, "last_name" );
27
28 // Feedback for end user
29 echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
30
31 // Increase loop count
32 $i++;
33 }
34
35 //mysql_close();
36}
High
1if( isset( $_SESSION [ 'id' ] ) ) {
2 // Get input
3 $id = $_SESSION[ 'id' ];
4
5 // Check database
6 // 看起來做了返回條目限制
7 $query = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
8 // 沒什麼套路
9 // SELECT first_name, last_name FROM users WHERE user_id = '1' or 1=1 # ' LIMIT 1;
10
11 $result = mysql_query( $query ) or die( '<pre>Something went wrong.</pre>' );
12
13 // Get results
14 $num = mysql_numrows( $result );
15 $i = 0;
16 while( $i < $num ) {
17 // Get values
18 $first = mysql_result( $result, $i, "first_name" );
19 $last = mysql_result( $result, $i, "last_name" );
20
21 // Feedback for end user
22 echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
23
24 // Increase loop count
25 $i++;
26 }
27
28 mysql_close();
29}
impossible
1if( isset( $_GET[ 'Submit' ] ) ) {
2 // Check Anti-CSRF token
3 checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
4
5 // Get input
6 $id = $_GET[ 'id' ];
7
8 // Was a number entered?
9 if(is_numeric( $id )) {
10 // Check the database
11 // 這是!PDO!
12 // PDO 是一種PHP中比較先進的面向對象形式的數據庫訪問技術
13 // 不過即使是面向對象它還是事務腳本形式的。
14 // 提供了防SQL注入的功能。
15 $data = $db->prepare( 'SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;' );
16 // 無法注入
17
18 $data->bindParam( ':id', $id, PDO::PARAM_INT );
19 $data->execute();
20 $row = $data->fetch();
21
22 // Make sure only 1 result is returned
23 if( $data->rowCount() == 1 ) {
24 // Get values
25 $first = $row[ 'first_name' ];
26 $last = $row[ 'last_name' ];
27
28 // Feedback for end user
29 echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
30 }
31 }
32}
33
34// Generate Anti-CSRF tsoken
35generateSessionToken();
Extension
二次注入:
網站有管理員admin.
一位惡意用戶註冊了admin'#用戶.
惡意用戶更新了自己的密碼.
更新SQL:
update from users set password = ‘$password’ where username = ‘$username’ and password ‘$password’
替換為惡意用戶寫入的數據:
update from users set password = #{password} where username = ‘admin’#’ and password = ‘$password’
注意# 後面的語句被註釋掉了, 所以真正被執行的只有.
update from users set password = #{password} where username = ‘admin’
惡意用戶可以無視管理員admin的密碼驗證,直接修改密碼。