學習Web安全好幾年了,接觸最多的是Sql注入,一直最不熟悉的也是Sql注入。OWASP中,Sql注入危害絕對是Top1。花了一點時間研究了下Mysql類型的注入。
文章中的tips將會持續更新,先說說這些天研究的
這里博主以數字類型注入類型進行講解,字符類型同理,這里不在敖述。
我們的環境:phpstudy+mysql+php
我們的測試代碼如下:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <?php $id= $_GET['id'];//接受get傳遞的參數名x的值並賦值給變量id $conn = mysql_connect('127.0.0.1','root','root');//連接mysql數據庫 mysql_select_db('shop',$conn);//選擇$conn連接請求下的test數據庫名 $sql = "select * from product where pid=$id";//定義sql語句並組合變量id $result = mysql_query($sql);//執行sql語句並返回給變量result while($row = mysql_fetch_array($result)){//遍歷數組數據並顯示 echo "ID:".$row['pid']."</br>"; echo "pname:".$row['pname']."</br>"; echo "info:".$row['pdesc']."</br>"; } mysql_close($conn);//關閉數據庫連接 echo "<hr>"; echo "Sql="; echo $sql; ?>
這里sql語句直接代入查詢,沒有進行過濾,所以存在sql注入。
Sql注入的測試過程我是這樣理解的,從安全測試不影響企業的角度考慮出發,不從滲透測試角度出發。
過程如下:
判斷數據庫類型--->針對數據庫類型進行Sql注入探測判斷是否存在Sql注入--->簡單注入證明出數據庫名/版本號等--->提交安全漏洞
在實戰測試中,需要大家去進行判斷數據庫類型然后針對性注入。本篇文章都是以Mysql數據庫為例子那么咱們就沒必要浪費時間了。
大家測試sql注入都知道,如果是數字類型的,我們一般都會嘗試
通過and 1=1和and 1=2進行簡單測試。
但是隨着安全的快速發展,現在很少能遇到and 1=1和and 1=2就能簡單判斷出的sql注入,多數都有過濾。那么我們這時候就需要花樣式的tips的進行簡單的探測是否存在sql注入。
發現漏洞你成功了70%,寫出漏洞證明你就完善了后面的30%,所以發現Sql注入這個環節很重要。
以數字類型為例子
在Mysql注入中有哪些語句可以代替and 1=1和and 1=2進行判斷的?
這里先從if開始講起~
語法:select if(expr1,expr2,expr3)
解釋:當expr1為true,則執行expr2,反之執行expr3
在Mysql中我們知道0 =false和null=true,非0的數字代表true
那么我們可以這樣判斷:
通過這種方法去判斷是否存在sql注入,繼續衍生下去,還可以怎么玩?
通過if我們的組合利用將會變得多種多樣,這里不一一舉例子了。
Mysql中盲注有基本的兩種姿勢
1.and sleep(3)
2.and BENCHMARK(10000000,ENCODE('hello','mom'))
如果存在注入,這兩個語句都會產生延遲
在前面講了if,以sleep(3)延遲為例子,benmark延遲同理不講解了。
可以通過這種方法進行盲注測試,然后再if上繼續延生下去:
在Mysql中和and差不多意思的語句是哪個? like?
使用like進行判斷:
如果把順序換下會怎么樣?
如果過濾了and怎么辦?我們如何進行Sql注入判斷?
使用xor,xor用法詳細:https://blog.csdn.net/csdn_0_001/article/details/79515643
這樣判斷等同於and 1=1和and 1=2
因為不想文章內容太過啰嗦,先介紹幾個關系點
1.and和like用法相近
2.or和xor用法相近
and,like,or和xor這幾個都是運算符,所以可以隨便調換,所以在下面的文章中比如:and if(1,1,0)也可以like if那么同理也可以xor if(),也可以or if
就是sql語句稍微有點差別罷了
繼續往下:
and /or/xor/like都能為我們所用,那between呢?事實證明可以。
演示下:
利用between進行盲注
陷入循環延遲中。。。這個延遲時間很長。。。
這樣也是可以判斷sql注入的,那么還能怎么玩?
進行這樣進行sql注入判斷。。
寫到這里我有點累。。繼續吧。。
還是從Mysql if開始說起吧。。。
Mysql中小數不代表false我們還可以怎么玩?
通過這樣嘗試繞過某些限制。。
好吧有點扯淡了。再一個要介紹Myql中的<>
簡單演示下,也能判斷注入
那么之前就說過能and ,就能like,就能xor,就能or進行sql注入判斷,實在是舉例子起來太多。。
xor比較復雜點,以xor為例子吧。。。
認真寫一篇文章真的好累。。
如果過濾了if我們還能怎么辦。。好吧我們還有親戚[想不到吧?]
語法: ifnull(expr1,expr2)
解釋:如果expr1不是null就是expr1,如果expr1是null就是expr2
簡單演示下:
還是以xor為例子演示一遍,or like不說了
如果ifnull也過濾了怎么辦?還有好基友幫忙:
語法:nullif(expr1,expr2)
解釋:如果expr1等於expr2返回null,如果expr1不等於expr2返回expr1
以xor為例子
然后還能測試盲注。
改成1試試。
前面的很多很多都是對Mysql注入的探測,那么還有哪些姿勢可以進行探測呢?
語法:space(n)
解釋:由n個空格字符組成的一個字符串。
先看下ascii表
演示下:
xor演示下:
如果過濾了and/or/xor/between我們還能判斷注入嗎?顯然是可以的,我們怎么做?
使用div進行判斷是否存在注入:
前面講的and if/or if等用法均適用於div,div是mysql中的整除函數:
除了div我們還有什么? 別忘了having
我們還有什么方法可以探測sql注入是否存在的?div的朋友們:
1.mod -- 取余函數
精簡到最短的探測方法:
那么mod也可以和and/or/xor等 一樣配合if等條件函數進行利用:
既然mod可以判斷。那么round函數是否也可以判斷?
round是mysql中的四舍五入函數:
用like進行演示:
除了這些探測方法還有哪些?
使用case when,因為這個語句比較長,我把它放到了最后:
控制流程語句case when一樣可以輔助我們進行sql注入探測:
and CASE WHEN 1>0 THEN sleep(3) ELSE sleep(1) end
使用xor/like/or/mod等都可以進行注入判斷:
以xor為例子:
陷入循環延遲中。。
還有哪些方法可以探測?
漏講了一個知識點:
字符串代表着0
使用xor:
也可以like 1這樣。。你們自己去衍生。。
使用soundex函數進行注入探測:
含義:返回str的一個同音字符串。聽起來“大致相同”的2個字符串應該有相同的同音字符串。一個“標准”的同音字符串長是4個字符,但是SOUNDEX()函數返回一個任意長的字符串。你可以在結果上使用SUBSTRING()得到一個“標准”的 同音串。所有非數字字母字符在給定的字符串中被忽略。所有在A-Z之外的字符國際字母被當作元音。
繼續吧,干到底!
使用函數LOCATE進行sql注入探測:
使用locate模擬 or 1=1和or 1=2
該函數不區分大小寫。
當locate中的第一個參數為null,那就是null。
繼續,已經講到locate了,那么不得不說下position了!
語法:POSITION(substr IN str)
POSITION(substr IN str)是 LOCATE(substr,str)同義詞,和locate用法類似
這次換個方法演示不用xor,使用div,你也可以使用mod或者round。
其實探測方法還有一些,不想一一舉例子了。其實方法都大同小異。
我頭大了 先寫這么多。。針對Mysql的探測,可以根據我這個進行拓撲下去。到時候后期慢慢更新tips的。
陸陸續續講完了Mysql的sql注入探測,那么下一步就是關鍵的注入出數據庫用戶名/數據庫名字/版本號等來簡單的證明是否存在漏洞了。。
咱們本篇文章以講解探測數據庫名字為中心,來列舉一些探測數據庫名字的技巧:
無非圍繞着Mysql的字符串函數居多。
列舉一部分,后面慢慢更新更多的注入數據payload
先從常見的開始講起:
關於字符串截斷的最讓人熟悉的莫過於substring函數了。實在是文章內容太多,很多基礎知識點不想再敖述,直接正片:
通過substring和ascii結合探測數據庫名字:
目前已知我的數據庫名字是shop,先簡單的探測下:
這里只要依次替換前面的數字進行遍歷下去即可
只使用substring:
char(115)是s。
使用left函數進行探測數據庫名字:
這樣依次類推下去。
使用right:
探測方法和left差不多。
繼續結合,if和left結合探測:
使用right:
if,ascii和substring三者結合:
然后substring,soundex結合查看:
倒過來探測所有:
探測數據庫第二位:
substring雙結合+soundex
探測數據庫長度:
使用repeat:
使用elt+substring進行探測:
有必要進下elt,elt語法:ELT(N,str1,str2,str3,...)
解釋:如果N= 1,返回str1,如果N= 2,返回str2,等等。如果N小於1或大於參數個數,返回NULL。ELT()是FIELD()反運算。、
其實前面判斷數據庫是否存在注入的時候忘記講elt了
可以這樣探測:
繼續
探測:探測:
使用field和substring進行探測:
探測如下:
探測數據庫第二位:
使用make_set探測:
探測如下:
使用position探測:
使用or進行探測:
寫這篇文章越寫越覺得自己無知,sql注入真的太復雜了。本篇文章僅僅拋磚引玉。
本篇文章是比較純的談數據庫注入,而沒有考慮到waf,但是考慮到了過濾函數。
本篇文章在判斷數據庫是否存在注入上花了很多功夫
本篇文章在探測數據庫方面僅探測出數據庫第一位字符證明即可,沒有以腳本的形式進行批量獲取。
本篇文章還有很多不足,以后會慢慢完善,也希望大家多提意見和好的思路
本篇文章中多以and +sql語句為主注入,其實在文章的最開頭,博主已經說過,可以and的多半都可以xor/or/like/mod/div/round等進行探測。這里需要大家自己隨機應變應對
本篇文章中在探測數據庫方面多數以substring為主,其實也可以組合left,substr,right,不要讓本篇文章局限了你的思想,一定要衍生出去
本篇文章需要一個善於排版和能理清邏輯清晰的大佬進行專業的二次改寫。
本篇文章很多技巧博主也是第一次知道,很多都是實踐出真知,很多原理博主自己也是一知半解在某些函數結合下所產生的那種效應。
其次博主很菜,希望和互聯網的安全朋友一起學習進步!
不忘初心,方得始終!