SQL手工注入進階篇

0.前言

  上一篇咱們介紹了SQL手工注入的流程以及步驟,但在實際的安全問題以及CTF題目中,查詢語句多種多樣,並且是確定會對用戶的輸入進行一個安全過濾的,而這些過濾並不必定是百分百安全的,如何利用一些技巧繞過一些安全過濾,這就是咱們這一篇要介紹的事情。php

  若是你還不熟悉SQL注入的流程以及步驟,請先閱讀個人上一篇博文。sql

  文中有誤之處,還請各位師傅指出。數據庫

 

1.各類select語句繞過

 (1)select xxx from xxx limit $num;

  上篇咱們講解了where條件查詢的注入方法,那麼若是不是where而是其餘語句呢,例如limit限制,這可能會出如今限制每頁展現多少行中用到,例如對於以下語句後端

  select * from student limit $num;安全

  $num是咱們上傳的變量,假如咱們依然使用order進行查列數將於返回以下結果函數

 

   Mysql會提示語法錯誤,由於排序須要在分頁的前面使用,那麼這個時候咱們該如何查列數呢,答案是上次提到的利用into @,@,@,@就是‘@’字符,它表明Mysql的一個臨時變量。測試

  例如  編碼

 

  必須保證變量數等於列數,利用這個特性咱們就能夠查出列數。加密

  (2)updata,insert,delete相關

  和select相似,仍是先找到參數的位置,再判斷注入類型,最後構造表達式進行SQL注入。spa

  (3)order by注入

  前面已經講了利用order by查列數,實際上order by能夠經過位運算來執行表達式

select * from student order by 1|(sleep(5));

 

2.時間函數進行盲注

  有些時候當網頁沒有錯誤回顯時,能夠考慮使用時間函數進行盲注。原理是利用條件判斷進行睡眠,咱們只須要觀察響應時間便可。

  例如

select * from student where id=1 and if(user()='root@localhost',sleep(5),null);#判斷用戶

select * from student where id=1 and if(substr(user(),1,1)='r',sleep(5),null);#逐字判斷

  咱們能夠先用一個永真條件判斷sleep()是否可用,當sleep()被禁用的時候,咱們能夠用下面其餘幾種延時方法代替。

 (1)延時方法

  • sleep()函數。
  • benchmark(count,expr),重複expr函數count次,咱們能夠利用一些MySql自帶的加密函數做爲expr執行屢次達到睡眠的效果。具體執行次數能夠根據CPU來進行變更。
select * from student where id=1 and if(true,benchmark(10000000,sha(1)),null);
  • 笛卡爾積,利用計算笛卡爾積達到延時;
select count(*) from information_schema.columns A,information_schema.columns B;#count(*)返回行數
  • get_lock(str,timeout),這個須要開啓兩次會話,第一次給str進行上鎖,第二次再執行就會等待timeout的時間,若timeout爲負,則無限等待。get_lock()只會在執行release_lock()或隱式的會話停止時顯式釋放鎖,事務提交或回滾不會釋放鎖。
  • length(str),利用rpad構造長字符串,再用length返回一列。
select LENGTH(concat(rpad(1,9999999,'a'),rpad(1,9999999,'a'),rpad(1,9999999,'a'),rpad(1,9999999,'a'),rpad(1,9999999,'a'),rpad(1,9999999,'a'),rpad(1,9999999,'a')));

 

  • rlike,regexp,先利用rpad或者式repeat構造長字符串再利用rlike正則匹配返回一列,經過控制構造的字符串長度控制時間。
select concat(rpad(1,9999999,'a'),rpad(1,9999999,'a'),rpad(1,9999999,'a'),rpad(1,9999999,'a'),rpad(1,9999999,'a'),rpad(1,9999999,'a'),rpad(1,9999999,'a')) rlike '(a.*)+(a.*)+(a.*)+(a.*)+(a.*)';

  p.s.構造字符串長度不能超出MySql內存限制,不然會報錯。

 (2)條件判斷

  • if(expr,expr1,expr2).
  • case when xx then xx;利用case when語法達到判斷條件的方法。

 (3)字符串截取

  • substr(str,pos,len),同Python的substr()函數,但MySql中首位置爲1或-len。
  • mid(str,pos,len),基本同上
  • substring_index(str,delim,count),返回第count個delim串左邊的全部內容
select substring_index('a.b.c.d','.',3);#返回a.b.c
  • left(str,len),返回str左邊len個字符。
  • right(str,len),返回str右邊len個字符。

  本質上時間盲注就是bool盲注的一種,利用回顯消息不一樣,只是這裏的回顯沒有顯式顯示在屏幕上罷了。

 

3.bool盲注

  利用回顯的不一樣來猜想數據庫的信息,例如order by就是一種bool盲注,通常能夠利用二分或者逐位拆解的方式進行盲注。能夠利用一些位運算的短路機制進行鏈接表達式。

 

4.多行注入

  當調用數據庫函數支持多行sql語句才能使用,原理就是利用';'結束語句插入本身的sql語句。

 

5.MySql編碼注入

(1)弱類型轉換

  先來看這樣一個查詢語句select * from student where name=1;

  

 

  爲何能夠被查詢呢,由於name會被轉換成數字和1比較,而MySql的默認轉換和php的轉換相似,找到第一個不爲數字的字符就結束。利用這個特性咱們能夠進行一些查詢判斷。

(2)寬字節注入

  噹噹前數據庫使用了GBK編碼的時候,會把兩個字符轉化爲漢字(前一個字符大於128),利用這個特性再配合後端的過濾實現注入。

  例如當後端過濾'將其變成\'的時候,若是式gbk編碼,則傳入的就是%5C%27,這時候咱們提交%df'則會被編碼成%df%5C%27,而前面的%df%5c則會被編碼成中文,達到了注入效果。

(3)SQL字符集特性

  對於utf8_unicode_ci字符集,不區分大小寫,並且Ä=A,Ö=O,Ü=U等條件都成立,且ß=ss,

  對於utf8_general_ci字符集,ß=s。

  更多條件等式能夠自行測試。

(4)進制轉換

  若是表名和列名過濾了字符能夠將其轉換爲16進制實現,前面帶上0x

6.總結

  本篇博文就是在上一篇的基礎上講解了一些其餘的注入方法,已經引入了不少MySql函數。到如今 對Mysql的知識已經講完了,下一篇咱們將會着重講解如何繞事後端對傳輸參數的一些過濾繞過。

  若是還有什麼補充的地方,請各位師傅在評論區留言。

相關文章
相關標籤/搜索