Skip to content

Commit

Permalink
Merge branch 'dev2.2.3'
Browse files Browse the repository at this point in the history
  • Loading branch information
xmendez committed Sep 25, 2017
2 parents 69d8bb3 + 2f7c040 commit 24effa7
Show file tree
Hide file tree
Showing 12 changed files with 100 additions and 27 deletions.
24 changes: 23 additions & 1 deletion docs/library/guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ CLI Option Library Option
<URL> url="url"
--recipe <filename> recipe="filename"
--oF <filename> save="filename"
-o filename,printer printer=("printer", "filename")
-f filename,printer printer=("filename", "printer")
--dry-run dryrun=True
-p addr proxies=[("ip","port","type")]
-t N concurrent=N
Expand Down Expand Up @@ -121,3 +121,25 @@ The get_payloads method can be used when various payloads are needed::
00019: C=404 7 L 12 W 168 Ch "0 - a"
>>>

Get session
===========

The get_session function generates a Wfuzz session object from the specified command line. It is a quick way of getting a payload programatically from a string representing CLI options::

$ python
>>> import wfuzz
>>> for r in wfuzz.get_session("-z range,0-10 http://testphp.vulnweb.com/FUZZ").fuzz():
... print r
...
00002: C=404 7 L 12 W 168 Ch "1"
00011: C=404 7 L 12 W 168 Ch "10"
00008: C=404 7 L 12 W 168 Ch "7"
00001: C=404 7 L 12 W 168 Ch "0"
00003: C=404 7 L 12 W 168 Ch "2"
00004: C=404 7 L 12 W 168 Ch "3"
00005: C=404 7 L 12 W 168 Ch "4"
00006: C=404 7 L 12 W 168 Ch "5"
00007: C=404 7 L 12 W 168 Ch "6"
00009: C=404 7 L 12 W 168 Ch "8"
00010: C=404 7 L 12 W 168 Ch "9"

14 changes: 13 additions & 1 deletion docs/user/basicusage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,18 @@ Wfuzz supports writing the results to a file in a different format. This is perf

For example, to write results to an output file in json format use the following command::

$ python wfuzz -o /tmp/outfile,json -w wordlist/general/common.txt http://testphp.vulnweb.com/FUZZ
$ python wfuzz -f /tmp/outfile,json -w wordlist/general/common.txt http://testphp.vulnweb.com/FUZZ


Different output
-----------------

Wfuzz supports showing the results in various formats. This is performed by plugins called "printers". The available printers can be listed executing::

$ python wfuzz -e printers

For example, to show results in json format use the following command::

$ python wfuzz -o json -w wordlist/general/common.txt http://testphp.vulnweb.com/FUZZ


6 changes: 5 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,8 @@
long_description = long_descr,
author = "Xavi Mendez (@x4vi_mendez)",
url = "http://wfuzz.org",
)
install_requires=[
'pycurl',
'pyparsing',
],
)
4 changes: 2 additions & 2 deletions wfuzz/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
__title__ = 'wfuzz'
__version__ = "2.2.2"
__version__ = "2.2.3"
__build__ = 0x023000
__author__ = 'Xavier Mendez'
__license__ = 'GPL 2.0'
Expand Down Expand Up @@ -28,4 +28,4 @@
sys.exit(1)

from .options import FuzzSession
from .api import fuzz, get_payload, get_payloads, encode, decode, payload
from .api import fuzz, get_payload, get_payloads, encode, decode, payload, get_session
6 changes: 5 additions & 1 deletion wfuzz/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from .core import dictionary
from .options import FuzzSession
from .facade import Facade
from .ui.console.clparser import CLParser

'''
Wfuzz API
Expand All @@ -10,7 +11,6 @@
def fuzz(**kwargs):
return FuzzSession(**kwargs).fuzz()


def get_payloads(iterator):
fs = FuzzSession()

Expand All @@ -28,3 +28,7 @@ def decode(name, value):

def payload(**kwargs):
return FuzzSession(**kwargs).payload()

def get_session(cline):
cl = ["wfuzz"] + cline.split(" ")
return FuzzSession(**CLParser(cl).parse_cl())
10 changes: 9 additions & 1 deletion wfuzz/myqueues.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,14 @@ def run(self):
self._cleanup()

class LastFuzzQueue(FuzzQueue):
def __init__(self, options, queue_out = None, limit = 0):
FuzzQueue.__init__(self, options, queue_out, limit)

self.items_to_send = [FuzzResult.result]

if options["send_discarded"]:
self.items_to_send.append(FuzzResult.discarded)

def get_name(self):
return "LastFuzzQueue"

Expand All @@ -146,7 +154,7 @@ def _cleanup(self):
pass

def send(self, item):
if item.type == FuzzResult.result:
if item.type in self.items_to_send:
self.queue_out.put(item)

def _throw(self, e):
Expand Down
22 changes: 14 additions & 8 deletions wfuzz/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ class FuzzSession(UserDict):
def __init__(self, **kwargs):
self.data = self._defaults()

# recipe must be options
# recipe must be superseded by options
if "recipe" in kwargs and kwargs["recipe"]:
self.import_from_file(kwargs["recipe"])

self.data.update(kwargs)
self.update(kwargs)

self.cache = HttpCache()
self.http_pool = None
Expand All @@ -35,6 +35,8 @@ def __init__(self, **kwargs):
def _defaults(self):
return dict(
seed_payload = False,
send_discarded = False,
console_printer = "",
hs = None,
hc = [],
hw = [],
Expand Down Expand Up @@ -85,6 +87,9 @@ def _defaults(self):
compiled_printer = None,
)

def update(self, options):
self.data.update(options)

def validate(self):
if self.data['dictio'] and self.data['payloads']:
return "Bad usage: Dictio and payloads options are mutually exclusive. Only one could be specified."
Expand Down Expand Up @@ -174,16 +179,13 @@ def export_json(self):
wfuzz_recipe = defaultdict(dict)
)
defaults = self._defaults()
not_to_dump = ["interactive", "recipe", "seed_payload", "send_discarded", "compiled_genreq", "compiled_filter", "compiled_prefilter", "compiled_printer"]

# Only dump the non-default options
for k, v in self.data.items():
if v != defaults[k]:
if v != defaults[k] and k not in not_to_dump:
tmp['wfuzz_recipe'][k] = self.data[k]

# don't dump recipe
if "recipe" in tmp['wfuzz_recipe']:
del(tmp['wfuzz_recipe']["recipe"])

return json.dumps(tmp, sort_keys=True, indent=4, separators=(',', ': '))

def payload(self, **kwargs):
Expand Down Expand Up @@ -227,7 +229,11 @@ def compile(self):
raise FuzzExceptBadOptions(error)

# printer
filename, printer = self.data["printer"]
try:
filename, printer = self.data["printer"]
except ValueError, e:
raise FuzzExceptBadOptions("Bad options: Printer must be specified in the form of ('filename', 'printer')")

if filename:
if printer == "default" or not printer: printer = Facade().sett.get('general', 'default_printer')
self.data["compiled_printer"] = Facade().printers.get_plugin(printer)(filename)
Expand Down
12 changes: 8 additions & 4 deletions wfuzz/plugin_api/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from wfuzz.utils import find_file_in_paths

import sys
import os

# Util methods for accessing search results
Expand Down Expand Up @@ -64,10 +65,13 @@ def queue_url(self, url):
class BasePrinter:
def __init__(self, output):
self.f = None
try:
self.f = open(output,'w')
except IOError, e:
raise FuzzExceptBadFile("Error opening file. %s" % str(e))
if output:
try:
self.f = open(output,'w')
except IOError, e:
raise FuzzExceptBadFile("Error opening file. %s" % str(e))
else:
self.f = sys.stdout

self.verbose = Facade().printers.kbase["verbose"]

Expand Down
12 changes: 9 additions & 3 deletions wfuzz/ui/console/clparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def show_plugin_ext_help(self, registrant, category="$all$"):
def parse_cl(self):
# Usage and command line help
try:
opts, args = getopt.getopt(self.argv[1:], "hLAZX:vcb:e:R:d:z:r:f:t:w:V:H:m:o:s:p:w:u:",['slice=','zP=','oF=','recipe=', 'dump-recipe=', 'req-delay=','conn-delay=','sc=','sh=','sl=','sw=','ss=','hc=','hh=','hl=','hw=','hs=','ntlm=','basic=','digest=','follow','script-help=','script=','script-args=','prefilter=','filter=','interact','help','version','dry-run'])
opts, args = getopt.getopt(self.argv[1:], "hLAZX:vcb:e:R:d:z:r:f:t:w:V:H:m:f:o:s:p:w:u:",['slice=','zP=','oF=','recipe=', 'dump-recipe=', 'req-delay=','conn-delay=','sc=','sh=','sl=','sw=','ss=','hc=','hh=','hl=','hw=','hs=','ntlm=','basic=','digest=','follow','script-help=','script=','script-args=','prefilter=','filter=','interact','help','version','dry-run'])
optsd = defaultdict(list)

payload_cache = {}
Expand Down Expand Up @@ -169,6 +169,9 @@ def _parse_help_opt(self, optsd):
else:
raise FuzzExceptBadOptions("Unknown category. Valid values are: payloads, encoders, iterators, printers or scripts.")

if "-f" in optsd:
if "help" in optsd["-f"]:
self.show_plugins_help("printers")
if "-o" in optsd:
if "help" in optsd["-o"]:
self.show_plugins_help("printers")
Expand Down Expand Up @@ -411,14 +414,17 @@ def _parse_options(self, optsd, options):
options["verbose"] = True
options["colour"] = True

if "-o" in optsd:
vals = optsd['-o'][0].split(",", 1)
if "-f" in optsd:
vals = optsd['-f'][0].split(",", 1)

if len(vals) == 1:
options["printer"] = (vals[0], None)
else:
options["printer"] = vals

if "-o" in optsd:
options["console_printer"] = optsd['-o'][0]

if "--recipe" in optsd:
options["recipe"] = optsd['--recipe'][0]

Expand Down
3 changes: 2 additions & 1 deletion wfuzz/ui/console/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@
\t
\t-c : Output with colors
\t-v : Verbose information.
\t-o filename,printer : Store results in the output file using the specified printer (raw printer if omitted).
\t-f filename,printer : Store results in the output file using the specified printer (raw printer if omitted).
\t-o printer : Show results using the specified printer.
\t--interact : (beta) If selected,all key presses are captured. This allows you to interact with the program.
\t--dry-run : Print the results of applying the requests without actually making any HTTP request.
\t
Expand Down
11 changes: 7 additions & 4 deletions wfuzz/ui/console/mvc.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
from collections import defaultdict
import threading

from wfuzz.fuzzobjects import FuzzResult

from .common import exec_banner, Term
from .getch import _Getch

Expand Down Expand Up @@ -196,7 +198,7 @@ def header(self, summary):
print "==============================================================================================================================================\r\n"
else:
print "==================================================================\r"
print "ID Response Lines Word Chars Request \r"
print "ID Response Lines Word Chars Payload \r"
print "==================================================================\r\n"

def result(self, res):
Expand All @@ -207,10 +209,11 @@ def result(self, res):
else:
self._print(res)

sys.stdout.write("\n\r")
if res.type == FuzzResult.result:
sys.stdout.write("\n\r")

for i in res.plugins_res:
print " |_ %s\r" % i.issue
for i in res.plugins_res:
print " |_ %s\r" % i.issue

def footer(self, summary):
self.term.delete_line()
Expand Down
3 changes: 3 additions & 0 deletions wfuzz/wfuzz.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ def main():
try:
# parse command line
session_options = CLParser(sys.argv).parse_cl().compile()
session_options["send_discarded"] = True

# Create fuzzer's engine
fz = Fuzzer(session_options)
Expand All @@ -35,6 +36,8 @@ def main():
kb.start()

printer = View(session_options["colour"], session_options["verbose"])
if session_options["console_printer"]:
printer = Facade().printers.get_plugin(session_options["console_printer"])(None)
printer.header(fz.genReq.stats)

for res in fz:
Expand Down

0 comments on commit 24effa7

Please sign in to comment.