Sqli-Labs 是一個印度人的開源項目平臺。里面包含了基本的各種注入類型,同時又有get和post類型,以及一些基本的繞過學習。
項目地址:https://github.com/Audi-1/sqli-labs
Lesson-1 #Get - Error based - Single quotes - String (基于錯誤的GET單引號字符型注入)
運行測試環境:http://localhost/sqli-labs-master/Less-1/
輸入ID參數1:http://localhost/sqli-labs-master/Less-1/?id=1,返回正常,繼續測試陸續輸入2,3,4,5,6....,均返回正常,而且隨著參數ID值的改變,頁面返回的name和Password的值也會出現不同
根據上面情況,推測出數據庫操作指令:
【SELECT name,Password FROM TABLE WHERE ID=INPUT_ID】
試著來讓其報錯,報錯的方法通常有 單引號 and1=1 and 1=2 雙引號 反斜杠 注釋 等等
我輸入單引號進行測試:
【http://localhost/sqli-labs-master/Less-1/?id=1%27】
網站報出錯誤信息:
【You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1'' LIMIT 0,1' at line 1】
根據報錯信息可以推測出更加詳細的SQL語句:
由錯誤提示【'??? '??? 1'??? '???? LIMIT 0,1??? '】推測的SQL語句存在單引號
【SELECT name,Password FROM TABLE WHERE ID='$ID'】
發現報了SQL語句的語法錯誤,應該存在SQL注入,由于沒有過濾單引號,我們可以通過閉合單引號來構造payload:
利用order by測試數據庫中的列數:
【http://localhost/sqli-labs-master/Less-1/?id=1' order by 3 #】
發現當3的時候不報錯,4的時候報錯,知道數據庫表中有三個字段
直接使用UNION語句聯合查詢,但是發現只出現一行?!
【http://localhost/sqli-labs-master/Less-1/?id=1' union select 1,2,3 #】
So,查看網站源代碼:
源碼中mysql_fetch_array()被調用了一次,mysql_fetch_array()函數從結果集合中取出一行數據輸出,導致不管怎么查詢只能查詢第一行數據。
mysql_fetch_array(data,array_type)
data:可選。規定要使用的數據指針。該數據指針是 mysql_query() 函數產生的結果。
array_type:可選。規定返回哪種結果。可能的值:
??? MYSQL_ASSOC - 關聯數組
??? MYSQL_NUM - 數字數組
??? MYSQL_BOTH - 默認。同時產生關聯和數字數組
如果我傳入的ID值為非負數(負數或者0),浮點數字符或者字符串呢?
看到只有第二列和第三列的結果顯示在網頁上。
那我們就根據第二列或者第三列來查詢數據庫的信息:
user():返回當前數據庫連接使用的用戶
database():返回當前數據庫連接使用的數據庫
version():返回當前數據庫的版本
【http://localhost/sqli-labs-master/Less-1/?id=0'union select 1,version(),3#】
也可以使用數據庫的連接函數來查詢多條信息,常用concat和concat_ws函數
char碼值對應列表(附)
Char("32") 空格 SPACE???????????? Char("33") !????????????????????? Char("34")
"Char("35") #??????????????????????????????? Char("36") $???????????????????? Char("37") %
Char("38") &???????????????????????????????? Char("39") ’?????????????????????? Char("40") (
Char("41") )?????????????????????????????????? Char("42") *????????????????????? Char("43") +
Char("44") ,?????????????????????????????????? Char("45") -?????????????????????? Char("46") .
Char("47") /?????????????????????????????????? Char("58") :?????????????????????? Char("59");
Char("60") <????????????????????????????????? Char("61") =????????????????????? Char("62")>
Char("63") ??????????????????????????????????? Char("64") @
CONCAT()函數用于將多個字符串連接成一個字符串
CONCAT(str1,str2,…)
返回結果為連接參數產生的字符串。如有任何一個參數為NULL ,則返回值為 NULL。
如果所有參數均為非二進制字符串,則結果為非二進制字符串。
如果自變量中含有任一二進制字符串,則結果為一個二進制字符串。
一個數字參數被轉化為與之相等的二進制字符串格式;若要避免這種情況,可使用顯式類型 cast。
查詢users表中的列名:
寫一個獲取用戶名和密碼的腳本(基于POCsuite):
驗證測試(爆出用戶名密碼):
最后用注入神器SQLMAP來驗證一下,結果如下:
SQL Injection:就是通過把SQL命令插入到Web表單遞交或輸入域名或頁面請求的查詢字符串,最終達到欺騙服務器執行惡意的SQL命令。
具體來說,它是利用現有應用程序,將(惡意)的SQL命令注入到后臺數據庫引擎執行的能力,它可以通過在Web表單中輸入(惡意)SQL語句得到一個存在安全漏洞的網站上的數據庫,而不是按照設計者意圖去執行SQL語句。