wfuzz web安全扫描器

wfuzz 基本原理: 使用给定的负载替换FUZZ关键词,进行扫描。

基础用法

wfuzz -w common.txt --hc 404 http://testphp.vulnweb.com/FUZZ
wfuzz -z file --zP fn=common.txt --hc 404 http://testphp.vulnweb.com/FUZZ
wfuzz -z file --zD common.txt --hc 404 http://testphp.vulnweb.com/FUZZ
wfuzz -z file,common.txt --hc 404 http://testphp.vulnweb.com/FUZZ
wfuzz -w common.txt -w common.txt -w common2.txt --hc 404 http://testphp.vulnweb.com/FUZZ/FUZ2ZFUZ3Z
选项:
-h/--help:帮助
--help:高级帮助
--filter-help:筛选器帮助
--version:Wfuzz版本详细信息
-e<type>:可选 encoders/payloads/iterators/printers/scripts
--recipe<filename>:从配方中读取选项。对各种食谱重复上述步骤。
--dump recipe<filename>:将当前选项打印为配方
--oF<filename>:将模糊结果保存到文件中。这些可以稍后使用wfuzz有效负载来使用。
-c:带颜色的输出
-v:详细信息。
-f filename,printer:使用指定的打印机(如果省略了原始打印机)将结果存储在输出文件中。
-o printer:使用指定的打印机显示结果。
--interact:(beta)如果选中,则捕获所有按键。这允许您与程序交互。
--dry-run:打印应用请求的结果,而不实际发出任何HTTP请求。
--prev:打印以前的HTTP请求(仅当使用生成模糊结果的有效负载时)
--efield<expr>:显示指定的语言表达式以及当前负载。对各个字段重复上述操作。
--field<expr>:不显示有效负载,只显示指定的语言表达式。对各个字段重复上述操作。
-p addr:使用ip:port:type格式的代理。重复使用各种代理的选项。如果省略,类型可以是SOCKS4、SOCKS5或HTTP。
-t N:指定并发连接数(默认值为10
-s N:指定请求之间的时间延迟(默认值为0
-R depth:递归路径发现深度是最大递归级别。
-D depth:最大链接深度级别。
-L, --follow:遵循HTTP重定向
--ip-host:port:以ip:port格式指定要连接的ip,而不是URL的主机
-Z:扫描模式(将忽略连接错误)。
--req delay N:设置请求允许的最长时间(以秒为单位)(CURLOPT_TIMEOUT)。默认值90
--conn-delay N:设置服务器连接阶段要花费的最长时间(以秒为单位)(CURLOPT_CONNECTTIMEOUT)。默认值90
-A, --AA, --AAA: --script=default,verbose,discovery-v-c的别名
--no-cache:禁用插件缓存。将扫描每个请求。
--script=:相当于--script=默认值
--script=:运行脚本的扫描是以逗号分隔的插件文件或插件类别列表
--script help=:显示有关脚本的帮助。
--script-args n1=v1,…:为脚本提供参数。即--script args grep.regex=“”
-u url:指定请求的url。
-m iterator:指定用于组合有效载荷的迭代器(默认为product)
-z payload:以名称[,参数][,编码器]的形式为每个FUZZ关键字指定有效负载。可以使用编码器列表,即md5-sha1。编码器可以是链式的,即。md5@sha1.可以使用编码器类别。即url
使用帮助作为有效负载来显示有效负载插件的详细信息(您可以使用--slice进行过滤)
--zP<params>:指定有效负载的参数(必须以-z或-w开头)。
--zD:指定有效负载的默认参数(必须以-z或-w开头)。
--zE<encoder>:指定有效负载的编码器(它必须以-z或-w开头)。
--slice<filter>:使用指定的表达式过滤有效负载的元素。它必须以-z开头。
-w wordlist:指定wordlist文件(-z文件的别名,wordlist)。
-V alltype:所有参数brutforming(allvars和allpost)。不需要FUZZ关键字。
-X method:指定请求的HTTP方法,即HEAD或FUZZ
-b cookie:为请求指定cookie。对各种cookie重复选项。
-d postdata:使用postdata(例如:“id=FUZZ&catalog=1”)
-H header:使用header(例如:“Cookie:id=1312321&user=FUZZ”)。对各种标题重复选项。
--basic/ntlm/digest auth:格式为“user:pass”或“FUZZ:FUZZ”或
--hc/hl/hw/hh N[,N]+:隐藏具有指定代码/行/字/字符的响应(使用BBB从基线获取值)
--sc/sl/sw/sh N[,N]+:显示具有指定代码/行/字/字符的响应(使用BBB获取基线值)
--ss/hs正则表达式:显示/隐藏内容中具有指定正则表达式的响应
--filter<filter>:使用指定的筛选器表达式显示/隐藏响应(使用BBB从基线获取值)
--prefilter<filter>:使用指定的表达式在模糊化之前过滤项目。对串联过滤器重复上述步骤。

进阶

# 过滤403响应码, 以及以this_is_404为基线过滤
wfuzz -w common.txt --hc 403,404 --hh BBB http://42.194.197.96/FUZZ{this_is_404}
# 按文本内容过滤
wfuzz -w common.txt --hs "页面不存在" http://42.194.197.96/FUZZ
# 按字符数量过滤
wfuzz -w common.txt --hc 404 --hh 167 http://datalayer.io/FUZZ
# 指定payload和encoder
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
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 # 按顺序使用多个encoders
# url中参数
wfuzz -z range,0-10 --hl 97 http://testphp.vulnweb.com/listproducts.php?cat=FUZZ
# post 请求
wfuzz -w common.txt -d "uname=FUZZ&pass=FUZZ" --hc 302 http://testphp.vulnweb.com/userinfo.php
# cookie
wfuzz -w common.txt -b cookie=value1 -b cookie2=value2 http://testphp.vulnweb.com/FUZZ
# 探测cookie字段
wfuzz -w common.txt -b cookie=FUZZ http://testphp.vulnweb.com/
# 自定义请求头
wfuzz -w common.txt -H "myheader: headervalue" -H "myheader2: headervalue2" http://testphp.vulnweb.com/FUZZ
# 探测header
wfuzz -w common.txt -H "User-Agent: FUZZ" http://testphp.vulnweb.com/
# 探测http请求方法
wfuzz -z list,GET-HEAD-POST-TRACE-OPTIONS -X FUZZ http://testphp.vulnweb.com/
# 使用代理
wfuzz -w common.txt -p localhost:8080 http://testphp.vulnweb.com/FUZZ
# 指定代理类型
wfuzz -w common.txt -p localhost:2222:SOCKS5 http://testphp.vulnweb.com/FUZZ
# 多个代理
wfuzz -w common.txt -p localhost:8080 -p localhost:9090 http://testphp.vulnweb.com/FUZZ
# 递归测试
wfuzz -z list,"web\-sec-admin-CVS-cgi\-bin" -R 2 https://m0nst3r.me/FUZZ
# 指定输出类型
wfuzz -f test2.html,html -w common.txt https://m0nst3r.me/FUZZ
# 输出到stdout
wfuzz -o json -w common.txt https://m0nst3r.me/FUZZ
# 全局配置文件 ~/.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

crunch 工具

sudo apt install crunch/focal # ubuntu
brew install crunch # mac
crunch [options] # 生成字典,在最小和最大长度之间, options为关键词
crunch 2 2 ab | wfuzz -z stdin --hc 404 http://testphp.vulnweb.com/FUZZ # 通过管道输出给wfuzz

python库

import wfuzz
for r in wfuzz.get_payload(range(100)).fuzz(hl=[97], url="http://testphp.vulnweb.com/listproducts.php?cat=FUZZ%22):
print(r)
# fuzz session
s = wfuzz.FuzzSession(url="http://testphp.vulnweb.com/FUZZ")
for r in s.fuzz(hc=[404], payloads=[("file",dict(fn="wordlist/general/common.txt"))]):
print(r)
# 上下文管理器
with wfuzz.FuzzSession(url="http://testphp.vulnweb.com/FUZZ", hc=[404], payloads=[("file",dict(fn="wordlist/general/common.txt"))]) as s:
for r in s.fuzz():
print(r)
# payload
s = wfuzz.get_payload(range(5))
for r in s.fuzz(url="http://testphp.vulnweb.com/FUZZ"):
print(r)
# 多个payload
s = wfuzz.get_payloads([range(5), ["a","b"]])
for r in s.fuzz(url="http://testphp.vulnweb.com/FUZZ/FUZ2Z"):
print(r)
# get session
s = wfuzz.get_session("-z range,0-10 http://testphp.vulnweb.com/FUZZ")
for r in s.fuzz():
print(r)
# 结果交互
with wfuzz.get_session("-z list --zD test -u http://testphp.vulnweb.com/userinfo.php -d uname=FUZZ&pass=FUZZ") as s:
for r in s.fuzz():
print(r.history.cookies.response)
print(r.history.params.all)
print(r.history.params.post)
print(r.history.params.post.uname)
print(r.history.params.post['pass'])
print(r.eval("r.cookies.response"))

wfpayload

wfpayload -z range --zD 0-10
wfpayload -z range --zD 0-10 --filter "FUZZ<3"
# 从保存的session中提取参数
wfpayload -z burplog,a_burp_log.log --slice "params.get~'authtoken'"
wfpayload -z burplog --zD burp_log_05032020.log --prefilter "r.headers.response.Access-Control-Allow-Origin='*'"
wfpayload -z wfuzzp --zD /tmp/session --field r.params.get
artist=5
wfpayload -z wfuzzp --zD /tmp/session --efield r.params.get
# 在保存的session上调用插件
wfpayload -z burplog --zD ./burp_log_05032020.log --script=headers --filter "plugins~'akamai'"
# 重写保存的session
wfpayload -z burplog --zD ./burp_log_05032020.log --hc 404 --oF /tmp/no404
wfpayload -z wfuzzp --zD /tmp/no404
wfencode -e md5 test # 编码
wfencode -d base64 MTIzNDU2 # 解码

高级用法

wfuzz -z help # 列出所有可用的payload详情
# -ss -hs, 支持正则过滤返回内容
wfuzz -H "User-Agent: () { :;}; echo; echo vulnerable" --ss vulnerable -w cgis.txt http://localhost:8000/FUZZ
# payload是0-10,过滤少于97行的响应
wfuzz -z range,0-10 --hl 97 http://testphp.vulnweb.com/listproducts.php?cat=FUZZ
# fuzz post参数
wfuzz -z file,common_pass.txt -d "uname=FUZZ&pass=FUZZ" --hc 302 http://testphp.vulnweb.com/userinfo.php
# fuzz http原语
wfuzz -z list,GET-HEAD-POST-TRACE-OPTIONS -X FUZZ http://testphp.vulnweb.com/
# 认证
wfuzz -z list,nonvalid-httpwatch --basic FUZZ:FUZZ https://www.httpwatch.com/httpgallery/authentication/authenticatedimage/default.aspx
# 递归
wfuzz -z list,"admin-CVS-cgi\-bin" -R1 http://testphp.vulnweb.com/FUZZ
# 写日志文件
wfuzz -f /tmp/outfile.json -w common.txt http://testphp.vulnweb.com/FUZZ
# 输出日志
wfuzz -o json -w common.txt http://testphp.vulnweb.com/FUZZ
# --efield 设定可选的字段输出
wfuzz -z range --zD 0-1 -u http://testphp.vulnweb.com/artists.php?artist=FUZZ --efield r
# --field 完全替换默认字段输出
wfuzz -z range --zD 0-1 -u http://testphp.vulnweb.com/artists.php?artist=FUZZ --field url
# --efield --field 可设定多个
wfuzz -z range --zD 0-1 -u http://testphp.vulnweb.com/artists.php?artist=FUZZ --efield url --efield h
# filed输出和--efield或--field搭配, 输出特定内容
wfuzz -z list --zD https://www.airbnb.com/ --script=links --script-args=links.regex=.*js$,links.enqueue=False -u FUZZ -o field --field plugins.links.link | head -n3
# 迭代器,连接payload
wfuzz -z list,a-b-c -z list,1-2-3 -m zip http://google.com/FUZZ/FUZ2Z
wfuzz -z list,a-b-c -z list,1-2-3 -m chain http://google.com/FUZZ
wfuzz -z list,a-b-c -z list,1-2-3 http://mysite.com/FUZZ/FUZ2Z
# 指定encoder
wfuzz -z file --zP fn=common.txt,encoder=md5 http://testphp.vulnweb.com/FUZZ
wfuzz -z file --zD common.txt --zE md5 http://testphp.vulnweb.com/FUZZ
wfuzz -z file,common.txt,md5 http://testphp.vulnweb.com/FUZZ
# 多个encoder, 用-连接
wfuzz -z list,1-2-3,md5-sha1-none http://webscantest.com/FUZZ
# 用@链接多个encoder, 顺序进行
wfuzz -z list,1-2-3,sha1-sha1@none http://webscantest.com/FUZZ
# encoder用栏目分组
wfuzz -z list,1-2-3,hashes http://webscantest.com/FUZZ
# 查看默认组件信息
wfuzz --script-help=default
# 扫描robots.txt
wfuzz --script=robots -z list,robots.txt http://www.webscantest.com/FUZZ
# --no-cache 不缓存
wfuzz -z range --zD 0-3 -z list --zD "'" -u http://testphp.vulnweb.com/artists.php?artist=FUZZFUZ2Z -A
wfuzz -z range --zD 0-3 -z list --zD "'" -u http://testphp.vulnweb.com/artists.php?artist=FUZZFUZ2Z -A --no-cache
# recipe 存档
wfuzz --script=robots -z list,robots.txt --dump-recipe /tmp/recipe http://www.webscantest.com/FUZZ
# 使用存档
wfuzz --recipe /tmp/recipe
wfuzz --recipe /tmp/recipe -b cookie1=value
wfuzz --recipe /tmp/recipe --recipe /tmp/recipe2 # 多个连接
# 指定ip/host
wfuzz -z range,1-1 --ip 127.0.0.1 http://www.google.com/anything/FUZZ
# -Z 扫描模式, 忽略错误和异常
wfuzz -z list,support-web-none http://FUZZ.google.com/
wfuzz -z list,support-web-none -Z http://FUZZ.google.com/
wfuzz -z list,support-web-none -Z --hc XXX http://FUZZ.google.com/
# 过滤器
wfuzz --filter-help
wfuzz -z range,0-10 --filter "c=200 and l>97" http://testphp.vulnweb.com/listproducts.php?cat=FUZZ
wfuzz -z list,echoedback -d searchFor=FUZZ --filter "content~FUZZ" http://testphp.vulnweb.com/search.php?test=query
wfuzz -z list,echoedback -d searchFor=FUZZ --ss "echoedback" http://testphp.vulnweb.com/search.php?test=query
wfuzz -w fuzzdb/attack/xss/xss-rsnake.txt -d searchFor=FUZZ --filter "content~FUZZ" http://testphp.vulnweb.com/search.php?test=query
wfuzz -z range --zD 0-1 -u http://testphp.vulnweb.com/artists.php?artist=FUZZ --filter 'r.params.all'
wfuzz -z list --zD index -u http://testphp.vulnweb.com/FUZZ.php --script headers --filter "plugins~'nginx'"
# --slice 切片, unique 操作符
wfuzz -z list --zD one-two-one-one --slice "FUZZ|u()" http://localhost:9000/FUZZ
# 保存后wfpayload查看
wfuzz -z range --zD 0-0 -u http://www.google.com/FUZZ --oF /tmp/test1
wfpayload -z wfuzzp --zD /tmp/test1 --slice "c=404"
wfpayload -z wfuzzp --zD /tmp/test1 --slice "c!=404"
wfuzz -z wfuzzp --zD /tmp/test1 -u FUZZ --oF /tmp/test2
wfpayload -z wfuzzp --zD /tmp/test2 --efield r.headers.response.date --efield FUZZ[r.headers.response.date]
# 重写payload
wfuzz -z list --zD one-two-three --slice "FUZZ|upper()" -u https://www.wfuzz.io/FUZZ
# 保存wfuzz 结果
wfuzz --oF /tmp/session -z range,0-10 http://www.google.com/dir/test.php?id=FUZZ
# 读取burpstate 和 burplog 负载
wfuzz -z burpstate,a_burp_state.burp FUZZ
wfuzz -z burplog,a_burp_log.burp FUZZ
wfuzz -z wfuzzp,/tmp/session FUZZ
# 读取,修改
wfuzz -z burpstate,a_burp_state.burp -H "addme: header" FUZZ
wfuzz -z burpstate,a_burp_state.burp -z list,1-2-3 -b "cookie=FUZ2Z" FUZZ
# --prev, 对比
wfuzz -z burpstate,testphp.burp --slice "cookies.request and url|u()" --filter "c!=FUZZ[c]" -b "" --prev FUZZ
# 请求新url
wfuzz -z burpstate,a_burp_state.burp -H "addme: header" -u http://www.otherhost.com FUZZ
# 使用部分属性
wfuzz -z wfuzzp,/tmp/session --zP attr=url FUZZ
wfuzz -z wfuzzp,/tmp/session FUZZ[url]
wfuzz -z wfuzzp,/tmp/session -p localhost:8080 http://testphp.vulnweb.com/FUZZ[url.path]?FUZZ[url.query]
# 请求修改
wfuzz -z range,1-5 --oF /tmp/session http://testphp.vulnweb.com/artists.php?artist=FUZZ
wfuzz -z wfuzzp,/tmp/session --prefilter "r.params.get=+'\''" -A FUZZ