本篇主要是摘抄自m0nst3r 大表哥的博客系列 https://m0nst3r.me/archives/page/4/
做下筆記,不時查閱。
0x01 簡介
wfuzz 是一款Python開發的Web安全測試工具,它不僅僅是一個web掃描器:wfuzz能夠通過發現並利用網站弱點/漏洞的方式幫助你使網站更加安全。wfuzz的漏洞掃描功能由插件支持。
wfuzz提供了簡潔的編程語言接口來處理wfuzz或Burpsuite獲取到的HTTP請求和響應。這使得你能夠在一個良好的上下文環境中進行手工測試或半自動化的測試,而不需要依賴web形式的掃描器。
0x02 簡單指令
2.1 基礎指令
一個典型的wfuzz命令只需要指定一個字典和一個要測試的URL即可,如下:
wfuzz -w ../wordlist/general/test.txt https://m0nst3r.me/FUZZ

wfuzz的輸出使我們能夠分析web server的響應,還可根據獲得的HTTP響應信息過濾出我們想要的結果,比如過濾響應碼/響應長度等等。
每一行輸出給我們提供了以下信息:
ID:測試時的請求序號
Response:HTTP響應嗎
Lines:響應信息中的行數
Word:響應信息中的字數
Chars:響應信息中的字符數
Payload:當前使用的payload
2.2 指定payload
wfuzz -w /usr/share/wfuzz/wordlist/general/common.txt http://testphp.vulnweb.com/FUZZ
2.3 指定多個payloads
使用 -z 或 -w 參數可以同時指定多個payloads,這時相應的占位符應設置為 FUZZ, … , FUZnZ, 其中n代表了payload的序號。
比如下面的例子,我們同時暴破文件,后綴和目錄:
wfuzz -w /usr/share/wfuzz/wordlist/general/common.txt -w /usr/share/wfuzz/wordlist/general/common.txt -w /usr/share/wfuzz/wordlist/general/extensions_common.txt --hc 404 http://testphp.vulnweb.com/FUZZ/FUZ2ZFUZ3Z
0x03 過濾器
wfuzz對結果進行過濾是非常重要的:
wfuzz可根據HTTP響應碼和收到的響應的長度(字數,字符數或行數)來過濾。還可以用正則表達式。
過濾的方法有兩種:隱藏或顯示符合過濾條件的結果。
3.1 隱藏響應結果
通過--hc,--hl,--hw,--hh參數可以隱藏某些HTTP響應。隱藏無法找到的頁面的響應如下:
wfuzz -w /usr/share/wfuzz/wordlist/general/common.txt --hc 404 http://testphp.vulnweb.com/FUZZ
可指定多個需要隱藏的條件,如,想要加上隱藏禁止訪問的響應:
wfuzz -w /usr/share/wfuzz/wordlist/general/common.txt --hc 404,403 http://testphp.vulnweb.com/FUZZ
在當HTTP返回碼相同的時候,用行數,字數,字符數來指定過濾規則比較方便進行過濾。
比如,網站一般會指定一個自定義的錯誤頁面,返回碼是200,但實際上起到了一個404頁面的作用,我們稱之為軟404。下面是一個例子:
wfuzz -w /usr/share/wfuzz/wordlist/general/common.txt --hc 404 http://datalayer.io/FUZZ

仔細觀察上面的結果,我們很容易推斷出所有”not found”的返回信息中都有 51個行,138個字,962個字符。
因此,我們需要改進一下我們的過濾條件(增加多個過濾條件):
wfuzz -w /usr/share/wfuzz/wordlist/general/common.txt --hc 404 --hh 962 http://datalayer.io/FUZZ

3.2 顯示響應結果
顯示響應結果的使用方法跟隱藏時的原理一樣,只不過參數變為了:--sc(show code),--sl(show lines),--sw(show word),--sh(show chars)。
3.3 使用Baseline(基准線)
過濾器可以是某個HTTP響應的引用,這樣的引用我們稱為Baseline。
之前的使用--hh進行過濾的例子中,還可以使用下面的命令代替:
wfuzz -w ../wordlist/general/test.txt --hh BBB https://m0nst3r.me/FUZZ{this_is_404}

這條命令的意思應該很容易理解:首先解釋下https://m0nst3r.me/FUZZ{this_is_404}的意思,這里代表wfuzz第一個請求是請求https://m0nst3r.me/this_is_404這個網址
在{ }內的值用來指定 wfuzz 第一個請求中的 FUZZ 占位符,而這第一個請求被標記為 BBB(BBB不能換成別的)基准線。其次這里使用的參數是--hh,也就是以BBB這條請求中的Chars為基准,其他請求的Chars值與BBB相同則隱藏。
3.4 使用正則表達式過濾
在命令行中,參數--ss和--hs可以接受正則表達式來對返回的結果時行過濾:
舉個栗子:在這里一個網站自定義返回頁面的內容中包含 Not Found,想根據這個內容進行過濾可以使用如下的命令:
wfuzz -w wordlist --hs "Not Found" http://127.0.0.1/FUZZ
得出結論使用方法:
wfuzz -w wordlist --hs 正則表達式 URL/FUZZ #隱藏
wfuzz -w wordlist --ss 正則表達式 URL/FUZZ #顯示
0x04 內置工具
4.1 wfencode
這是wfuzz自帶的一個加密/解密(編碼/反編碼)工具,目前支持內建的encoders的加/解密。
wfencode -e base64 123456
MTIzNDU2
wfencode -d base64 MTIzNDU2
123456
wfuzz的encoder列表如下:
Available encoders:
Category | Name | Summary
----------------------------------------------------------------------------------------------------------
url_safe, url | urlencode | 用`%xx`的方式替換特殊字符, 字母/數字/下划線/半角點/減號不替換
url_safe, url | double urlencode | 用`%25xx`的方式替換特殊字符, 字母/數字/下划線/半角點/減號不替換
url | uri_double_hex | 用`%25xx`的方式將所有字符進行編碼
html | html_escape | 將`&`,`<`,`>`轉換為HTML安全的字符
html | html_hexadecimal | 用 `&#xx;` 的方式替換所有字符
hashes | base64 | 將給定的字符串中的所有字符進行base64編碼
url | doble_nibble_hex | 將所有字符以`%%dd%dd`格式進行編碼
db | mssql_char | 將所有字符轉換為MsSQL語法的`char(xx)`形式
url | utf8 | 將所有字符以`\u00xx` 格式進行編碼
hashes | md5 | 將給定的字符串進行md5加密
default | random_upper | 將字符串中隨機字符變為大寫
url | first_nibble_hex | 將所有字符以`%%dd?` 格式進行編碼
default | hexlify | 每個數據的單個比特轉換為兩個比特表示的hex表示
url | second_nibble_hex | 將所有字符以`%?%dd` 格式進行編碼
url | uri_hex | 將所有字符以`%xx` 格式進行編碼
default | none | 不進行任何編碼
hashes | sha1 | 將字符串進行sha1加密
url | utf8_binary | 將字符串中的所有字符以 `\uxx` 形式進行編碼
url | uri_triple_hex | 將所有字符以`%25%xx%xx` 格式進行編碼
url | uri_unicode | 將所有字符以`%u00xx` 格式進行編碼
html | html_decimal | 將所有字符以 `&#dd; ` 格式進行編碼
db | oracle_char | 將所有字符轉換為Oracle語法的`chr(xx)`形式
db | mysql_char | 將所有字符轉換為MySQL語法的`char(xx)`形式
encoders是通過payload參數傳進去的。有兩種方法:
wfuzz -z file --zP fn=common.txt,encoder=md5 http://testphp.vulnweb.com/FUZZ
wfuzz -z file,common.txt,md5 http://testphp.vulnweb.com/FUZZ

一次指定多個encoders,可以使用一個-號分隔的列表來指定,如:
wfuzz -z list,1-2-3,md5-sha1-none http://testphp.vulnweb.com/FUZZ

同時按順序使用多個encoders,可以使用一個@號分隔的列表來指定,如:
wfuzz -z list,1-2-3,sha1-sha1@none http://testphp.vulnweb.com/FUZZ

上面參數中的 sha1@none,會將 payload 先進行 sha1,然后傳給 none 這個encoder。
4.2 wfpayload
wfpayload是payload生成工具:
python wfpayload.py -z range,0-10

wfuzz中可用payloads列表如下:
Available payloads:
Name | Summary
------------------------------------------------------------------------------------------------------
guitab | 從可視化的標簽欄中讀取請求
dirwalk | 遞歸獲得本地某個文件夾中的文件名
file | 獲取一個文件當中的每個詞
autorize | 獲取autorize的測試結果Returns fuzz results' from autororize.
wfuzzp | 從之前保存的wfuzz會話中獲取測試結果的URL
ipnet | 獲得一個指定網絡的IP地址列表
bing | 獲得一個使用bing API搜索的URL列表 (需要 api key).
stdin | 獲得從標准輸入中的條目
list | 獲得一個列表中的每一個元素,列表用以 - 符號分格
hexrand | 從一個指定的范圍中隨機獲取一個hex值
range | 獲得指定范圍內的每一個數值
names | 從一個以 - 分隔的列表中,獲取以組合方式生成的所有usernames值
burplog | 從BurpSuite的記錄中獲得測試結果
permutation | 獲得一個在指定charset和length時的字符組合
buffer_overflow | 獲得一個包含指定個數個A的字符串.
hexrange | 獲得指定范圍內的每一個hex值
iprange | 獲得指定IP范圍內的IP地址列表
burpstate | 從BurpSuite的狀態下獲得測試結果
0x05 wfuzz命令中文幫助
python wfuzz.py --help
********************************************************
* Wfuzz 2.4.2 - The Web Fuzzer *
* *
* Version up to 1.4c coded by: *
* Christian Martorella (cmartorella@edge-security.com) *
* Carlos del ojo (deepbit@gmail.com) *
* *
* Version 1.4d to 2.4.2 coded by: *
* Xavier Mendez (xmendez@edge-security.com) *
********************************************************
Usage: wfuzz [options] -z payload,params <url>
FUZZ, ..., FUZnZ payload占位符,wfuzz會用指定的payload代替相應的占位符,n代表數字.
FUZZ{baseline_value} FUZZ 會被 baseline_value替換,並將此作為測試過程中第一個請求來測試,可用來作為過濾的一個基礎。
Options:
-h/--help : 幫助文檔
--help : 高級幫助文檔
--version : Wfuzz詳細版本信息
-e <type> : 顯示可用的encoders/payloads/iterators/printers/scripts列表
--recipe <filename> : 從文件中讀取參數
--dump-recipe <filename> : 打印當前的參數並保存成文檔
--oF <filename> : 將測試結果保存到文件,這些結果可被wfuzz payload 處理
-c : 彩色化輸出
-v : 詳細輸出
-f filename,printer : 將結果以printer的方式保存到filename (默認為raw printer).
-o printer : 輸出特定printer的輸出結果
--interact : (測試功能) 如果啟用,所有的按鍵將會被捕獲,這使得你能夠與程序交互
--dry-run : 打印測試結果,而並不發送HTTP請求
--prev : 打印之前的HTTP請求(僅當使用payloads來生成測試結果時使用)
-p addr : 使用代理,格式 ip:port:type. 可設置多個代理,type可取的值為SOCKS4,SOCKS5 or HTTP(默認)
-t N : 指定連接的並發數,默認為10
-s N : 指定請求的間隔時間,默認為0
-R depth : 遞歸路徑探測,depth指定最大遞歸數量
-L,--follow : 跟隨HTTP重定向
-Z : 掃描模式 (連接錯誤將被忽視).
--req-delay N : 設置發送請求允許的最大時間,默認為 90,單位為秒.
--conn-delay N : 設置連接等待的最大時間,默認為 90,單位為秒.
-A : 是 --script=default -v -c 的簡寫
--script= : 與 --script=default 等價
--script=<plugins> : 進行腳本掃描, <plugins> 是一個以逗號分開的插件或插件分類列表
--script-help=<plugins> : 顯示腳本的幫助
--script-args n1=v1,... : 給腳本傳遞參數. ie. --script-args grep.regex="<A href=\"(.*?)\">"
-u url : 指定請求的URL
-m iterator : 指定一個處理payloads的迭代器 (默認為product)
-z payload : 為每一個占位符指定一個payload,格式為 name[,parameter][,encoder].
編碼可以是一個列表, 如 md5-sha1. 還可以串聯起來, 如. md5@sha1.
還可使用編碼各類名,如 url
使用help作為payload來顯示payload的詳細幫助信息,還可使用--slice進行過濾
--zP <params> : 給指定的payload設置參數。必須跟在 -z 或-w 參數后面
--slice <filter> : 以指定的表達式過濾payload的信息,必須跟在-z 參數后面
-w wordlist : 指定一個wordlist文件,等同於 -z file,wordlist
-V alltype : 暴力測試所有GET/POST參數,無需指定占位符
-X method : 指定一個發送請求的HTTP方法,如HEAD或FUZZ
-b cookie : 指定請求的cookie參數,可指定多個cookie
-d postdata : 設置用於測試的POST data (ex: "id=FUZZ&catalogue=1")
-H header : 設置用於測試請求的HEADER (ex:"Cookie:id=1312321&user=FUZZ"). 可指定多個HEADER.
--basic/ntlm/digest auth : 格式為 "user:pass" or "FUZZ:FUZZ" or "domain\FUZ2Z:FUZZ"
--hc/hl/hw/hh N[,N]+ : 以指定的返回碼/行數/字數/字符數作為判斷條件隱藏返回結果 (用 BBB 來接收 baseline)
--sc/sl/sw/sh N[,N]+ : 以指定的返回碼/行數/字數/字符數作為判斷條件顯示返回結果 (用 BBB 來接收 baseline)
--ss/hs regex : 顯示或隱藏返回結果中符合指定正則表達式的返回結果
--filter <filter> : 顯示或隱藏符合指定filter表達式的返回結果 (用 BBB 來接收 baseline)
--prefilter <filter> : 用指定的filter表達式在測試之前過濾某些測試條目
0x06 Wfuzz常用指令
6.1 URL中的參數
通過在URL中在?后面設置FUZZ占位符,我們就可以使用wfuzz來測試URL傳入的參數:
wfuzz -z range,0-10 --hl 97 http://testphp.vulnweb.com/listproducts.php?cat=FUZZ
6.2 POST請求
如果想使用wfuzz測試form-encoded的數據,比如 HTML表單那樣的,只需要傳入-d參數即可:
wfuzz -w wordlist -d "uname=FUZZ&pass=FUZZ" --hc 302 http://testphp.vulnweb.com/userinfo.php
6.3 Cookies
在測試請求中加入自己設置的cookies,可以使用-b參數指定,多個cookies使用多次。
wfuzz -w wordlist -b cookie=value1 -b cookie2=value2 http://testphp.vulnweb.com/FUZZ
以上命令可生成如下的HTTP請求:
GET /attach HTTP/1.1
Host: testphp.vulnweb.com
Accept: */*
Content-Type: application/x-www-form-urlencoded
Cookie: cookie=value1; cookie2=value2
User-Agent: Wfuzz/2.2
Connection: close
探測cookie字段的話,可以使用下面的命令:
wfuzz -w wordlist -b cookie=FUZZ http://testphp.vulnweb.com/
6.4 自定義請求頭
使用-H參數來指定HTTP請求的請求頭,多次指定多次使用。
wfuzz -w wordlist -H "myheader: headervalue" -H "myheader2: headervalue2" http://testphp.vulnweb.com/FUZZ
生成的HTTP請求如下:
GET /agent HTTP/1.1
Host: testphp.vulnweb.com
Accept: */*
Myheader2: headervalue2
Myheader: headervalue
Content-Type: application/x-www-form-urlencoded
User-Agent: Wfuzz/2.2
Connection: close
我們還可以修改存在的請求頭,比如修改User-Agent頭:
wfuzz -w wordlist -H "myheader: headervalue" -H "User-Agent: Googlebot-News" http://testphp.vulnweb.com/FUZZ
生成的HTTP請求如下:
GET /asp HTTP/1.1
Host: testphp.vulnweb.com
Accept: */*
Myheader: headervalue
Content-Type: application/x-www-form-urlencoded
User-Agent: Googlebot-News
Connection: close
Headers也可以被測試:
wfuzz -w wordlist -H "User-Agent: FUZZ" http://testphp.vulnweb.com/
6.5 探測HTTP請求方法
HTTP請求方法的測試可通過指定-X參數指定:
wfuzz -z list,GET-HEAD-POST-TRACE-OPTIONS -X FUZZ http://testphp.vulnweb.com/

6.6 使用代理
如果在測試時想要使用代理的話,只需要傳入-p參數即可:
wfuzz -w common.txt -p localhost:8080 http://testphp.vulnweb.com/FUZZ
默認情況下,指定的代理是HTTP Basic類型的,如果想用其他類型的代理,可通過指定類型來使用:
wfuzz -w common.txt -p localhost:2222:SOCKS5 http://testphp.vulnweb.com/FUZZ
多個代理可使用多個-p參數同時指定:
wfuzz -w common.txt -p localhost:8080 -p localhost:9090 http://testphp.vulnweb.com/FUZZ
這樣每次請求都會選取不同的代理進行。
6.7 遞歸測試
使用-R參數可以指定一個payload被遞歸的深度。例如,暴破目錄時,我們想使用相同的payload對已發現的目錄進行測試,可以使用如下命令:
wfuzz -z list,"web\-sec-admin-CVS-cgi\-bin" -R 2 https://m0nst3r.me/FUZZ
倘若目錄中存在-的話,注意要用/進行轉義哦~

6.8 測試速度與效率
根據對目標的影響和自身的承受能力及帶寬,wfuzz提供了一些參數可以用來調節HTTP請求引擎。
- 使用-t參數可以增加或減少同時發送HTTP請求的數量。
- 使用-s參數可以調節每次發送HTTP的時間間隔。
6.9 輸出到文件
wfuzz通過printers插件來將結果以不同格式保存到文檔中,printers一共有如下幾種格式:
raw | `Raw` output format
json | Results in `json` format
csv | `CSV` printer ftw
magictree | Prints results in `magictree` format
html | Prints results in `html` format
使用-f參數,指定值的格式為輸出文件位置,輸出格式。
舉個栗子:將結果以 html 格式輸出到 test2.html 中:
wfuzz -f test2.html,html -w ../wordlist/general/test.txt https://m0nst3r.me/FUZZ

直接使用不同格式在命令行輸出的話,可使用下面的命令:
wfuzz -o json -w ../wordlist/general/test.txt https://m0nst3r.me/FUZZ
0x07 wfuzz的配置文件
wfuzz的全局配置文件位於~/.wfuzz/wfuzz.ini
[kbase]
#這里配置忽略的后綴,用 - 號分隔
discovery.blacklist = .svg-.css-.js-.jpg-.gif-.png-.jpeg-.mov-.avi-.flv-.ico
[connection]
concurrent = 50 #並發數
conn_delay = 90 #連接間隔
req_delay = 90 #請求間隔
retries = 3 #重試次數
user-agent = Mozilla/5.0 (X11; Linux x86_64; rv:58.0) Gecko/20100101 Firefox/58.0 #UA,默認為Wfuzz/版本
[general]
default_printer = raw #默認輸出格式
cancel_on_plugin_except = 1 #插件出錯則退出
concurrent_plugins = 3 #最多同時指定的插件數量
lookup_dirs = /usr/share/wfuzz/wordlist,. #查找字典的目錄,若讓wfuzz自動查找字典,則在命令行中只指定字典名字即可
encode_space = 1 #編碼空格
[plugins]
bing_apikey = #設置bing API在key
