這里只講解sql注入漏洞的基本類型,代碼分析將放在另外一篇帖子講解
目錄
- 最基礎的注入-union注入攻擊
- Boolean注入攻擊-布爾盲注
- 報錯注入攻擊
- 時間注入攻擊-時間盲注
- 堆疊查詢注入攻擊
- 二次注入攻擊
- 寬字節注入攻擊
- base64注入攻擊
- cookie注入攻擊-http請求頭參數注入
- XFF注入攻擊-http請求頭參數注入
- 知道絕對路徑的注入
0x01最基礎的注入-union注入攻擊
- 判斷是get型還是post型注入;
- 找到正確的閉合規則;
- order by 查詢字段數;
- union select 1,2.....查看顯示位是第幾位,沒有的話就試試把id=1的顯示位讓出來,讓其等於id=-1;
- 第二、三位顯示出來了,那么即可在這兩個位置寫入sql語句;
- 查詢當前數據庫,當前mysql用戶 union select 1,user(),database();
- 查詢當前數據庫里面的表 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema="data_name";
- 查詢到敏感表名user,繼續查詢表里面的字段 union select 1,2,group_concat(column_name) from information_schema.columns where table_name="user";
- 查詢字段,例如“id”、"passwd"的內容 union select 1,id,passwd from user;
- 拿到用戶、密碼登入后台。
0x02 Boolean注入攻擊-布爾盲注
- 查看現象,能報錯,但沒有報錯信息,正確查詢也顯示不了查詢內容就屬於布爾盲注,只存在兩種狀態,對或錯;
- 由頁面的兩種不同返回的狀態來判定我們的閉合規則;
- 為了方便,我們這里假設返回正確用“yes”,返回錯誤用“no”來表示這兩種狀態
- 找到閉合規則后,我們在閉合規則里面 and 1=1 和 and 1=2 測試一下,看看最后返回是不是兩種狀態;
- 布爾盲注要用到length()和substr()語句,用兩種狀態來猜解數據庫、表名等的長度和正確字母;
- 先用 and length(database())>2 來猜數據庫的長度,使用的是二分法;
- 再用 and substr(database(),1,1)='t' 來確定第一個字母,可用burp跑,26個字母,哪個字母返回yes則代表第一個字母就是它;
- and substr(database(),2,1)='t' 代表當前數據庫的第二個字母;
- 最后結合長度,成功的將數據庫猜解出來;
- 后面的操作跟union注入的步驟差不多了,只是sql語句寫在 上文的 database() 處。
0x03 報錯注入攻擊
- 只要注入點有sql報錯信息,那么就可以使用報錯注入;
- 還是一樣,引號報錯,然后找到閉合規則,頁面正常顯示,則可以在閉合規則中開始寫入報錯注入的sql語句;
- updatexml報錯獲取當前數據庫:
and updatexml(1,concat(0x7e,(select database()),0x7e),1)
- floor報錯獲取當前數據庫:
and (select 1 from (select count(*),concat((database()),floor (rand(0)*2))x from information_schema.tables group by x)a)
- 兩種方式都可行,如果第一個不行就試試第二個
- 接着可以利用select語句替換掉上面database()來繼續獲取數據庫中的表名、字段名,查詢語句和union注入攻擊的語句相同;
- 只不過這里不能再使用group_concat了,因為報錯注入只顯示一條結果,所以需要使用limit語句;
0x04 時間注入攻擊-時間盲注
- 沒有明確的現象,不管是對是錯都返回一個狀態;
- 但是如果用sleep(5)方法,能讓響應時間延遲為5秒以上,那么就為時間盲注;
- 我們用sleep(5)函數構造了一個時間延時的狀態,因此,我們又有了兩種狀態,像布爾盲注一樣可以根據這兩種狀態來判定數據庫、表名和字段名的長度和正確的每個字母;
- 同樣的找到正確的閉合規則,當然,這個閉合規則得配合着 and sleep(5)語句來構造,哪一個閉合規則執行了sleep(5),那么就是正確得閉合規則;
- 時間盲注配合着 if(A,B,C) 語句結合使用,含義是:如果A是 true,則返回B(也就是執行B),否則返回C(執行C);
- 那么判斷當前數據庫名的長度的語句為:
if (length(database())>1,sleep(5),1)
就是說如果數據庫長度大於1,那么響應延時5秒,否則執行select 1(也就是不延時),由此來推出數據庫長度。
- 判斷當前數據庫名的第一個和第二個字母的語句:
if(substr(database(),1,1)='s',sleep(5),1)
if(substr(database(),2,1)='s',sleep(5),1)
只有第一個字母等於26個字母中正確的字母時,才會延時5秒,因此可以通過burp或者sqlmap來跑。
- 根據數據庫名長度以此內推即可得出完整的數據庫的庫命、表名、字段名和具體內容。
0x05 堆疊查詢注入攻擊
- 可以使用堆疊注入的地方也可以使用布爾盲注與時間盲注;
- 同樣先找出正確的閉合規則,然后也看兩種狀態來猜解庫名、表名等;
- 堆疊注入的語句為
;select if(length(database())>1,sleep(3),1) ;select if(substr(database(),1,1)='r',sleep(3),1)
- 按照原理來說,分號后面可以執行新sql語句,但是很多時候沒必要,如果遇到其他注入方法(或者繞過方式)不行的情況下可以試試這個注入方式;不是很常用。
0x06 二次注入攻擊
- 二次注入一共有兩個url,url一用來注入,也就是注入點,插入sql語句的地方,另外一個url用來返回信息;
- 也就是url一插入了sql語句,url一的響應里面就會返回這條信息對應的id值,然后url二就傳入這個新id值,然后訪問,響應回來之后將會爆出sql語句查詢的結果,正確或者錯誤的sql信息;
- 就相當於url是一個用戶注冊的地方,用戶注冊后會在數據庫里面加入新id存放用戶的注冊信息,那么這個id可以傳給url二來訪問,url二就可以顯示出用戶的注冊信息,但如果注冊信息含義惡意sql語句,url二就會顯示出敏感的數據庫信息;
- 跟union注入攻擊差不多,只是回顯的信息需要在另外的url中顯示出來了;
- 后面就是union注入攻擊的常規操作。
0x07 寬字節注入攻擊
- 如果遇到單、雙引號被轉義,變成了反斜杠,導致參數id無法逃逸單引號的包圍;
- 一般情況下,此處就不存在sql注入漏洞的;
- 但是如果數據庫的編碼為GBK時,就可以使用寬字節注入,因此在不知道是否是GBK編碼時,都可以嘗試去使用寬字節注入;
- 寬字節的格式是在地址后先加一個 %df ,再加單引號,因為反斜杠的編碼為%5c,在GBK編碼中,%df%5c是繁體字“連”,因此,單引號成功逃逸,爆出sql錯誤;
- 因此構造閉合規則時,在單引號前面加上 %df 就行了;
- 之后在閉合規則中寫入同union注入的一些查詢語句就行了;
0x08 base64注入攻擊
- 如果遇到url的參數id的值看起來像base64的,先拿去url解碼,然后如果是base64,拿去base64解碼,解出來的應該就是id的值(1,2等數字);
- 那么如果要對這個url進行sql注入測試,就需要對id后面的所有值進行base64編碼;
- 注入的方式步驟都是跟union注入一樣的,只不過后面的所有值(整個payload)都要進行base64編碼后傳給url的c參數提交,包括閉合規則。
0x09 HTTP請求頭參數注入-cookie注入攻擊
- 抓包對一個url的http請求頭的所有參數進行sql注入測試,里面的所有參數都有可能存在注入點,如果響應包出現sql報錯,那么測試的這個參數就是注入點;
- 常見的http頭部注入的參數有:
【Referer】、【X-Forwarded-For】、【Cookie】、【X-Real-IP】、【Accept-Language】、【Authorization】
- 如果測試到cookie參數的時候,響應有報sql錯誤,那么就是cookie注入攻擊;
- 和union注入的差別就在於注入點不一樣,之后使用union注入的方法即可。
0x10 HTTP請求頭參數注入-XFF注入攻擊
-
XFF注入即HTTP頭部的X-Forwarded-for參數存在sql注入;
-
例如測試此參數的值 X-Forwarded-for:127.0.0.1' 響應有sql報錯,那么此處就是注入點;
- 之后使用union注入的方法完成即可。
0x11 知道絕對路徑的注入
-
如果通過一些方式爆出了網站的根目錄,並且知道此站點存在sql注入;
-
猜測此數據庫可能有file權限,那么我們就可以使用語句:into outfile 來寫shell到網站的根目錄下,之后用菜刀連接;
-
如果數據庫沒有file權限,那么我們用sqlmap的參數 --is-dba 來查看當前數據庫的用戶是否有管理員權限;
-
如果有管理員權限,我們就可以使用sqlmap里面的參數命令 --os-shell 來上傳、反彈shell,最終getshell;
-
如果file、管理員權限都沒有,那么另尋思路,日志、緩存寫入等。
簡單的介紹了大致遇到的sql注入存在的類型,但是實際情況下可能會遇到更奇葩的sql注入利用方法,但是掌握了這些基本的sql注入之后,對后面sql注入的進階會更有幫助;之后還會介紹sql注入常用到的繞過技術。