wfuzz不仅仅是一个web扫描器:
wfuzz能够通过发现并利用网站弱点/漏洞的方式帮助你使网站更加安全。wfuzz的漏洞扫描功能由插件支持。
wfuzz是一个完全模块化的框架,这使得即使是Python初学者也能够进行开发和贡献代码。开发一个wfuzz插件是一件非常简单的事,通常只需几分钟。
wfuzz提供了简洁的编程语言接口来处理wfuzz或Burpsuite获取到的HTTP请求和响应。这使得你能够在一个良好的上下文环境中进行手工测试或半自动化的测试,而不需要依赖web形式的扫描器。
wfuzz是用python开发的针对web的模糊测试工具,该工具实现功能相当于burp的爆破模块,可以自定义指定参数进行爆破测试。
该工具在kali中已经安装并直接使用 也可以用pip安装wfuzz
pip install wfuzz
github地址:https://github.com/xmendez/wfuzz
wfuzz是一个模块化的框架,有5类内置的模块
payloads,encoders,interators,printers和script
每类有很多不同的模块,可以通过-e
参数查看
wfuzz -e payloads
payloads | 为wfuzz生成的用于测试的特定字符串 |
---|---|
encoders | 的作用是将payload进行编码或加密 |
iterators | 提供了针对多个payload的处理方式 |
printers | 用于控制输出打印 |
wfuzz的参数指令就不多介绍了,使用-h
或者--help
自行查看,在这只介绍几种渗透测试常用的参数指令
wfuzz -w dict/test.txt 192.168.1.1/test/FUZZ
wfuzz -w dict/filename.txt 192.168.1.1/test/FUZZ.php
wfuzz -w dict/params.txt 192.168.1.1/test/test.php?name=FUZZ
wfuzz -w dict/params.txt -w dict/123.txt 192.168.1.1/test/test.php?FUZZ=FUZ2Z
-w是指定字典的路径 FUZZ是指定要模糊测试的位置,相当于一个指示器,想测哪里,就把FUZZ放在哪(记住全大写) FUZZ,FUZ2Z,FUZ3Z是表示多个测试位置,放在哪里就测试哪里。
wfuzz有多种过滤显示操作--hc,--hl,--hw,--hh
是四种隐藏过滤的内容参数--sc,--sl,--sw,--sh
是四种显示过滤的内容
wfuzz -w list.txt --hc 302 https://www.baidu.com/FUZZ #隐藏302的请求
wfuzz -w list.txt --hl 17 https://www.baidu.com/FUZZ #隐藏返回长度为17的请求
wfuzz -w list.txt --sc 200 https://www.baidu.com/FUZZ #显示200的请求
wfuzz -w user.txt -w pwd.txt -d "username=FUZZ&password=FUZ2Z" http://192.168.1.1/login.php
-d参数后面为post请求的内容
wfuzz -z range,00-99 -b cookie=cookie -b session=session http://192.168.1.1/user.php?id=FUZZ
-b参数指定Cookie,当有多个Cookie需要指定多次
wfuzz -w wordlist -R 2 http://192.168.1.1/FUZZ
当扫到一个目录时,将在此目录下在进行模糊测试,-R表示深入扫描多少层
一个典型的wfuzz命令只需要指定一个字典和一个要测试的URL即可,如下:
┌─[[email protected]]─[/usr/share/wfuzz/src/wfuzz]
└──╼$wfuzz-w/usr/share/wfuzz/wordlist/general/common.txt http://testphp.vulnweb.com/FUZZ
********************************************************
* Wfuzz 2.2.9 - The Web Fuzzer *
********************************************************Target:http://testphp.vulnweb.com/FUZZ
Total requests: 950
==================================================================
ID Response Lines Word Chars Payload
==================================================================
000223:C=404 7L12W168 Ch "constants"
000224:C=404 7L12W168 Ch "contact"
000225:C=404 7L12W168 Ch "contacts"
000230:C=404 7L12W168 Ch "controlpanel"
000226:C=404 7L12W168 Ch "content"
000227:C=404 7L12W168 Ch "contents"
000228:C=404 7L12W168 Ch "control"
...
000008:C=404 7L12W168 Ch "100"
Total time: 5.193345
Processed Requests: 950
Filtered Requests: 0
Requests/sec.: 182.9264
wfuzz的输出使我们能够分析web server的响应,还可根据获得的HTTP响应信息过滤出我们想要的结果,比如过滤响应码/响应长度等等。
每一行输出给我们提供了以下信息:
使用 -h 和 –help 参数来获取基本帮助信息和详细帮助信息。
wfuzz是一个完全模块化的模式,你可以使用 -e <> 参数查看其中可用的模块,例如:
┌─[[email protected]]─[/usr/share/wfuzz/src/wfuzz]
└──╼$wfuzz-e iteratorsAvailable iterators:
Name | Summary
----------------------------------------------------------------------------------------------
product| Returns an iterator cartesian product of input iterables.
zip| Returns an iterator that aggregates elements from each of the iterables.
chain| Returns an iterator returns elements from the first iterable until it is exhaust
|ed, then proceeds to the next iterable, until all of the iterables are exhausted
| .
可用的categories包括:payloads , encoders , iterators , printers 和 scripts
wfuzz基于一个非常简单的概念:它用一个给定的payload来替换相应的FUZZ关键词的值,我们称FUZZ这样的关键词为 占位符 ,这样更容易理解。一个wfuzz中的payload就是一个输入的源。
要想得到所有可用的payload列表,可以执行如下命令:
$ wfuzz -e payloads
关于payloads的更详细的信息可以通过以下命令获取:
$ wfuzz -z help
上面这个命令还可以使用 –slice 参数来对输出结果进行过滤:
┌─[[email protected]]─[/usr/share/wfuzz/src/wfuzz]
└──╼ $wfuzz -z help --slice "dirwalk"
Name: dirwalk 0.1
Categories: default
Summary: Returns filename's recursively from a local directory.
Author: Xavi Mendez (@xmendez)
Description:
Returns all the file paths found in the specified directory.
Handy if you want to check a directory structure against a webserver,
for example, because you have previously downloaded a specific version
of what is supposed to be on-line.
Parameters:
+ dir: Directory path to walk and generate payload from.
每个FUZZ占位符都必须为它指定相应的payload。指定一个payload时有几种方法:
命令比较长的方式是显式的定义payload的参数:
$ wfuzz -z file --zP fn=/usr/share/wfuzz/wordlist/general/common.txt http://testphp.vulnweb.com/FUZZ
另一个不太长的方式是只提供payload所需的默认参数:
$ wfuzz -z file,/usr/share/wfuzz/wordlist/general/common.txt http://testphp.vulnweb.com/FUZZ
最后,短的方式是使用别名:
$ wfuzz -w /usr/share/wfuzz/wordlist/general/common.txt http://testphp.vulnweb.com/FUZZ
stdin 这个payload可以在使用一些外部字典生成工具时很方便:
┌─[[email protected]]─[/usr/share/wfuzz/src/wfuzz]
└──╼$crunch2 2ab|wfuzz-z stdin http://testphp.vulnweb.com/FUZZ
Crunch will now generate the following amount of data: 12bytes
0MB
0GB
0TB
0PB
Crunch will now generate the following number of lines: 4
********************************************************
* Wfuzz 2.2.9 - The Web Fuzzer *
********************************************************Target:http://testphp.vulnweb.com/FUZZ
Total requests: <<unknown>>
==================================================================
ID Response Lines Word Chars Payload
==================================================================
000002:C=404 7L12W168 Ch "ab"
000001:C=404 7L12W168 Ch "aa"
000003:C=404 7L12W168 Ch "ba"
000004:C=404 7L12W168 Ch "bb"
Total time: 3.827355
Processed Requests: 4
Filtered Requests: 0
Requests/sec.: 1.045107
使用 -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
对wfuzz的结果时行过滤是非常重要的:
非常大的字典文件可以生成非常庞大的输出,并且把我们想要的结果淹没 对HTTP响应的一些分类在实际攻击时是非常重要的,例如,为了查检一个SQLi的漏洞是否存在,我们必须能够将合理的响应和错误/不同的响应区分开。wfuzz可根据HTTP响应码和收到的响应的长度(字数,字符数或行数)来过滤。还可以用正则表达式。
过滤的方法有两种:隐藏或显示符合过滤条件的结果。
隐藏响应结果
通过 –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。
下面是一个例子:
┌─[[email protected]]─[~]
└──╼$wfuzz-w/usr/share/wfuzz/wordlist/general/common.txt--hc404http://datalayer.io/FUZZ
********************************************************
* Wfuzz 2.2.9 - The Web Fuzzer *
********************************************************Target:http://datalayer.io/FUZZ
Total requests: 950
==================================================================
ID Response Lines Word Chars Payload
==================================================================
000083:C=200 51L138W962 Ch "apache"
000008:C=200 51L138W962 Ch "100"
000009:C=200 51L138W962 Ch "1000"
000011:C=200 51L138W962 Ch "2"
000012:C=200 51L138W962 Ch "20"
000013:C=200 51L138W962 Ch "200"
...
仔细观察上面的结果,我们很容易推断出所有”not found”的返回信息中都有 51个行,138个字,962个字符。因此,我们需要改进一下我们的过滤条件(增加多个过滤条件):
┌─[[email protected]]─[~]
└──╼$wfuzz-w/usr/share/wfuzz/wordlist/general/common.txt--hc404 --hh962http://datalayer.io/FUZZ
********************************************************
* Wfuzz 2.2.9 - The Web Fuzzer *
********************************************************Target:http://datalayer.io/FUZZ
Total requests: 950
==================================================================
ID Response Lines Word Chars Payload
==================================================================
000430:C=302 0L0W0 Ch "img"
000689:C=500 2L1W9 Ch "register"
000135:C=302 0L0W0 Ch "blog"
000438:C=200 1677L5416W90077 Ch "index"
Total time: 8.323663
Processed Requests: 950
Filtered Requests: 946
Requests/sec.: 114.1324
显示响应结果
显示响应结果的使用方法跟隐藏时的原理一样,只不过参数变为了:–sc , –sl , –sw , –sh 。
使用Baseline
习惯上称Baseline为”基准线“。过滤器可以是某个HTTP响应的引用,这样的引用我们称为Baseline。
之前的使用 –hh 进行过滤的例子中,还可以使用下面的命令代替:
┌─[[email protected]]─[~]
└──╼$wfuzz-w/usr/share/wfuzz/wordlist/general/common.txt--hh BBB http://datalayer.io/FUZZ{notthere}
********************************************************
* Wfuzz 2.2.9 - The Web Fuzzer *
********************************************************Target:http://datalayer.io/FUZZ
Total requests: 951
==================================================================
ID Response Lines Word Chars Payload
==================================================================
000002:C=200 51L138W962 Ch "notthere"
000432:C=302 0L0W0 Ch "img"
000086:C=404 0L0W0 Ch "api"
000691:C=500 2L1W9 Ch "register"
000137:C=302 0L0W0 Ch "blog"
000045:C=404 0L0W0 Ch "WEB-INF"
000440:C=200 1677L5416W90077 Ch "index"
Total time: 21.76636
Processed Requests: 951
Filtered Requests: 944
Requests/sec.: 43.69125
这里, { } 来指定 第一次 HTTP请求时用来替换 FUZZ占位符 的值,其响应将被标记为 BBB ,并用于过滤条件中。
使用正则表达式过滤
在命令行中,参数 –ss 和 –hs 可以接受正则表达式来对返回的结果时行过滤。
$ wfuzz -H "User-Agent: () { :;}; echo; echo vulnerable" --ss vulnerable -w cgis.txt http://localhost:8000/FUZZ
payload为wfuzz生成的用于测试的特定字符串,一般情况下,会替代被测试URL中的FUZZ占位符。
当前版本中的wfuzz中可用payloads列表如下:
┌─[[email protected]]─[~]
└──╼$wfuzz-e payloadsAvailable 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的状态下获得测试结果
encoder的作用是将payload进行编码或加密。
wfuzz的encoder列表如下:
┌─[[email protected]]─[~]
└──╼$wfuzz-e encodersAvailable 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)`形式
wfuzz的iterator提供了针对多个payload的处理方式。
itorators的列表如下:
┌─[[email protected]]─[~]
└──╼$wfuzz-e iteratorsAvailable iterators:
Name | Summary
----------------------------------------------------------------------------------------------
product| 返回输入条目的笛卡尔积
zip| Retns an iterator that aggregates elements from each of the iterables.(翻译不好,请自行理解)
chain| Returns an iterator returns elements from the first iterable until it is exhaust
|ed, then proceeds to the next iterable, until all of the iterables are exhausted
| (翻译不好,请自行理解)
printer
wfuzz的printers用于控制输出打印。
printers列表如下:
┌─[[email protected]]─[~]
└──╼$wfuzz-e printers
Available printers:
Name | Summary
--------------------------------------------------
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
(比较好懂,不再翻译)
这是wfuzz自带的一个加密/解密(编码/反编码)工具,目前支持内建的encoders的加/解密。
┌─[[email protected]]─[~/.wfuzz]
└──╼ $wfencode -e base64 123456
MTIzNDU2┌─[[email protected]]─[~/.wfuzz]
└──╼ $wfencode -d base64 MTIzNDU2
123456
wfuzz的功能不只这一点点,还有很多参数可以深入探索,达到意向不到的目的。
由于FUZZ指示器可以随意指定,可以让我们进行多种多样的模糊测试
在url前面可以测试子域名,放在参数名处可以测试存在的参数,也可以修改head头部信息进行模糊测试,只要可以模糊测试的地方基本都可以实现。