SQL手工注入進階篇


0.前言

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

  如果你還不熟悉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注入。

  (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的知識已經講完了,下一篇我們將會着重講解如何繞過后端對傳輸參數的一些過濾繞過。

  如果還有什么補充的地方,請各位師傅在評論區留言。

 


免責聲明!

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



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