常見sql注入的類型


這里只講解sql注入漏洞的基本類型,代碼分析將放在另外一篇帖子講解

目錄

  • 最基礎的注入-union注入攻擊
  • Boolean注入攻擊-布爾盲注
  • 報錯注入攻擊
  • 時間注入攻擊-時間盲注
  • 堆疊查詢注入攻擊
  • 二次注入攻擊
  • 寬字節注入攻擊
  • base64注入攻擊
  • cookie注入攻擊-http請求頭參數注入
  • XFF注入攻擊-http請求頭參數注入
  • 知道絕對路徑的注入

0x01最基礎的注入-union注入攻擊

  1. 判斷是get型還是post型注入;
  2. 找到正確的閉合規則;
  3. order by 查詢字段數;
  4. union select 1,2.....查看顯示位是第幾位,沒有的話就試試把id=1的顯示位讓出來,讓其等於id=-1;
  5. 第二、三位顯示出來了,那么即可在這兩個位置寫入sql語句;
  6. 查詢當前數據庫,當前mysql用戶 union select 1,user(),database();
  7. 查詢當前數據庫里面的表 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema="data_name";
  8. 查詢到敏感表名user,繼續查詢表里面的字段 union select 1,2,group_concat(column_name) from information_schema.columns where table_name="user";
  9. 查詢字段,例如“id”、"passwd"的內容 union select 1,id,passwd from user;
  10. 拿到用戶、密碼登入后台。

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 報錯注入攻擊

  1. 只要注入點有sql報錯信息,那么就可以使用報錯注入;
  2. 還是一樣,引號報錯,然后找到閉合規則,頁面正常顯示,則可以在閉合規則中開始寫入報錯注入的sql語句;
  3. updatexml報錯獲取當前數據庫:
    and updatexml(1,concat(0x7e,(select database()),0x7e),1)
  4. floor報錯獲取當前數據庫:
    and (select 1 from (select count(*),concat((database()),floor (rand(0)*2))x from information_schema.tables group by x)a)
  5. 兩種方式都可行,如果第一個不行就試試第二個
  6. 接着可以利用select語句替換掉上面database()來繼續獲取數據庫中的表名、字段名,查詢語句和union注入攻擊的語句相同;
  7. 只不過這里不能再使用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 堆疊查詢注入攻擊

  1. 可以使用堆疊注入的地方也可以使用布爾盲注與時間盲注;
  2. 同樣先找出正確的閉合規則,然后也看兩種狀態來猜解庫名、表名等;
  3. 堆疊注入的語句為
    ;select if(length(database())>1,sleep(3),1)
    ;select if(substr(database(),1,1)='r',sleep(3),1)
  4. 按照原理來說,分號后面可以執行新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 寬字節注入攻擊

  1. 如果遇到單、雙引號被轉義,變成了反斜杠,導致參數id無法逃逸單引號的包圍;
  2. 一般情況下,此處就不存在sql注入漏洞的;
  3. 但是如果數據庫的編碼為GBK時,就可以使用寬字節注入,因此在不知道是否是GBK編碼時,都可以嘗試去使用寬字節注入;
  4. 寬字節的格式是在地址后先加一個  %df  ,再加單引號,因為反斜杠的編碼為%5c,在GBK編碼中,%df%5c是繁體字“連”,因此,單引號成功逃逸,爆出sql錯誤;
  5. 因此構造閉合規則時,在單引號前面加上  %df 就行了;
  6. 之后在閉合規則中寫入同union注入的一些查詢語句就行了;

0x08 base64注入攻擊

  • 如果遇到url的參數id的值看起來像base64的,先拿去url解碼,然后如果是base64,拿去base64解碼,解出來的應該就是id的值(1,2等數字);
  • 那么如果要對這個url進行sql注入測試,就需要對id后面的所有值進行base64編碼;
  • 注入的方式步驟都是跟union注入一樣的,只不過后面的所有值(整個payload)都要進行base64編碼后傳給url的c參數提交,包括閉合規則。

0x09 HTTP請求頭參數注入-cookie注入攻擊

  1. 抓包對一個url的http請求頭的所有參數進行sql注入測試,里面的所有參數都有可能存在注入點,如果響應包出現sql報錯,那么測試的這個參數就是注入點;
  2. 常見的http頭部注入的參數有:
    【Referer】、【X-Forwarded-For】、【Cookie】、【X-Real-IP】、【Accept-Language】、【Authorization】
  3. 如果測試到cookie參數的時候,響應有報sql錯誤,那么就是cookie注入攻擊;
  4. 和union注入的差別就在於注入點不一樣,之后使用union注入的方法即可。

0x10 HTTP請求頭參數注入-XFF注入攻擊

  • XFF注入即HTTP頭部的X-Forwarded-for參數存在sql注入;

  • 例如測試此參數的值  X-Forwarded-for:127.0.0.1'  響應有sql報錯,那么此處就是注入點;

  • 之后使用union注入的方法完成即可。

0x11 知道絕對路徑的注入

  1. 如果通過一些方式爆出了網站的根目錄,並且知道此站點存在sql注入;

  2. 猜測此數據庫可能有file權限,那么我們就可以使用語句:into outfile 來寫shell到網站的根目錄下,之后用菜刀連接;

  3. 如果數據庫沒有file權限,那么我們用sqlmap的參數 --is-dba  來查看當前數據庫的用戶是否有管理員權限;

  4. 如果有管理員權限,我們就可以使用sqlmap里面的參數命令  --os-shell  來上傳、反彈shell,最終getshell;

  5. 如果file、管理員權限都沒有,那么另尋思路,日志、緩存寫入等。

 

簡單的介紹了大致遇到的sql注入存在的類型,但是實際情況下可能會遇到更奇葩的sql注入利用方法,但是掌握了這些基本的sql注入之后,對后面sql注入的進階會更有幫助;之后還會介紹sql注入常用到的繞過技術。

 


免責聲明!

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



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