diff --git a/framework/fuzzer/filter.py b/framework/fuzzer/filter.py index 96973ef0..91ea7539 100644 --- a/framework/fuzzer/filter.py +++ b/framework/fuzzer/filter.py @@ -10,15 +10,10 @@ from pyparsing import ParseException except ImportError: PYPARSING = False - -class FilterQ(FuzzQueue): - def __init__(self, ffilter, queue_out): - FuzzQueue.__init__(self, queue_out) - Thread.__init__(self) - self.setName('filter_thread') - self.queue_out = queue_out +class FuzzResFilter: + def __init__(self, ffilter): if PYPARSING: element = oneOf("c l w h") digits = "XB0123456789" @@ -41,19 +36,7 @@ def __init__(self, ffilter, queue_out): self.baseline = None - def get_name(self): - return 'filter_thread' - - def _cleanup(self): - pass - - def process(self, prio, item): - if item.is_baseline: - self.baseline = self._set_baseline_fuzz(item) - item.is_visible = self.is_visible(item) - self.send(item) - - def _set_baseline_fuzz(self, res): + def set_baseline(self, res): if "BBB" in self.hideparams['lines']: self.hideparams['lines'].append(str(res.lines)) if "BBB" in self.hideparams['codes']: @@ -63,7 +46,7 @@ def _set_baseline_fuzz(self, res): if "BBB" in self.hideparams['chars']: self.hideparams['chars'].append(str(res.chars)) - return res + self.baseline = res def __convertIntegers(self, tokens): return int(tokens[0]) @@ -157,6 +140,28 @@ def is_visible(self, res): return (cond1 and cond2) +class FilterQ(FuzzQueue): + def __init__(self, ffilter, queue_out): + FuzzQueue.__init__(self, queue_out) + Thread.__init__(self) + + self.setName('filter_thread') + + self.queue_out = queue_out + self.ffilter = FuzzResFilter(ffilter) + + def get_name(self): + return 'filter_thread' + + def _cleanup(self): + pass + + def process(self, prio, item): + if item.is_baseline: + self.ffilter.set_baseline(item) + item.is_visible = self.ffilter.is_visible(item) + self.send(item) + if __name__ == "__main__": tests = [] tests.append("(w=200 and w=200) or w=200") diff --git a/framework/plugins/api.py b/framework/plugins/api.py index 68d66344..4ec05ddd 100644 --- a/framework/plugins/api.py +++ b/framework/plugins/api.py @@ -2,6 +2,7 @@ from framework.plugins.pluginobjects import PluginRequest from framework.core.myexception import FuzzException from framework.core.facade import Facade +from framework.fuzzer.filter import FuzzResFilter import os import urlparse @@ -209,14 +210,37 @@ def __init__(self): def blacklisted_extension(self, url): return url_filename_ext(url) in self.black_list -# Payloads specializations with common methods useful for their own type +# Payloads helpers + +class PayloadTools: + @staticmethod + def filter_results(extra_params, itera): + ffilter = None + + if extra_params and extra_params.has_key("filter"): + filter_params = dict( + active = True, + regex_show = None, + codes_show = None, + codes = [], + words = [], + lines = [], + chars = [], + regex = None, + filter_string = extra_params["filter"] + ) + ffilter = FuzzResFilter(filter_params) + + return itertools.ifilter(lambda x:ffilter.is_visible(x), itera) + else: + #raise FuzzException(FuzzException.FATAL, "Missing filter parameter in payload") + return itera -class OffsetPayload: - __metaclass__ = abc.ABCMeta + @staticmethod + def range_results(extra_params, itera): + offset = None + limit = None - def __init__(self, default_param, extra_params): - offset = 0 - limit = 0 if extra_params: if extra_params.has_key("offset"): offset = int(extra_params["offset"]) @@ -224,43 +248,7 @@ def __init__(self, default_param, extra_params): if extra_params.has_key("limit"): limit = int(extra_params["limit"]) - is_sliced, self._iterator = self.my_slice_iter(default_param, offset, limit) - self._slice_it(is_sliced, offset, limit) - - #if self._count <= 0: - #raise FuzzException(FuzzException.FATAL, "Number of elements is negative.") - - def _slice_it(self, is_sliced, offset, limit): - maxc = self.my_max_count() - - if not is_sliced: - if offset > maxc and maxc > 0: offset = maxc - if limit == 0: limit = maxc - - if not limit or limit < 0: - limit = None - self._count = -1 - else: - limit = min(offset + limit, maxc) - self._count = limit - offset - - self._iterator = itertools.islice(self._iterator, offset, limit) + if offset is None and limit is None: + return itera else: - self._count = maxc - - @abc.abstractmethod - def my_max_count(self): - return - - @abc.abstractmethod - def my_slice_iter(self, param, offset, limit): - return - - def next (self): - return self._iterator.next().strip() - - def count(self): - return self._count - - def __iter__ (self): - return self + return itertools.islice(itera, offset, limit) diff --git a/plugins/payloads.py b/plugins/payloads.py index fe2a11ef..a21f96c6 100644 --- a/plugins/payloads.py +++ b/plugins/payloads.py @@ -8,11 +8,11 @@ from framework.core.myexception import FuzzException from framework.fuzzer.base import wfuzz_iterator from framework.plugins.api import BingIter -from framework.plugins.api import OffsetPayload +from framework.plugins.api import PayloadTools @wfuzz_iterator @moduleman_plugin("count", "next", "__iter__") -class file(OffsetPayload): +class file: name = "file" description = "Returns each word from a file." category = ["default"] @@ -20,22 +20,30 @@ class file(OffsetPayload): def __init__(self, default_param, extra): - OffsetPayload.__init__(self, default_param, extra) + self.__max = -1 + self.f = PayloadTools.range_results(extra, self._my_gen(default_param)) - def my_max_count(self): - return self.__max + def __iter__(self): + return self - def my_slice_iter(self, default_param, offset, limit): + def _my_gen(self, filename): maxl = 0 try: - f = open(default_param, "r") + f = open(filename, "r") self.__max = len(f.readlines()) f.seek(0) except IOError: raise FuzzException(FuzzException.FATAL, "Error opening file") - return False, f + return f + + def count(self): + return self.__max + + def next(self): + return self.f.next().strip() + @wfuzz_iterator @moduleman_plugin("count", "next", "__iter__") @@ -371,7 +379,7 @@ def xcombinations(self, items, n): @wfuzz_iterator @moduleman_plugin("count", "next", "__iter__") -class bing(OffsetPayload): +class bing: ''' Some examples of bing hacking: - http://www.elladodelmal.com/2010/02/un-poco-de-bing-hacking-i-de-iii.html @@ -381,38 +389,49 @@ class bing(OffsetPayload): category = ["default"] priority = 99 def __init__(self, default_param, extra): - OffsetPayload.__init__(self, default_param, extra) + offset = 0 + limit = 0 - def my_slice_iter(self, default_param, offset, limit): - itera = BingIter(default_param, offset, limit) - self.__max = itera.max_count + if extra: + if extra.has_key("offset"): + offset = int(extra["offset"]) - return True, itera + if extra.has_key("limit"): + limit = int(extra["limit"]) - def my_max_count(self): - return self.__max + self._it = BingIter(default_param, offset, limit) + + def __iter__(self): + return self + + def count(self): + return self._it.max_count + + def next(self): + return self._it.next() @wfuzz_iterator -@moduleman_plugin("count", "next", "__iter__") -class wfuzz(OffsetPayload): +@moduleman_plugin("count", "next", "__iter__") +class wfuzz: name = "wfuzz" description = "Returns fuzz results' URL from a previous stored wfuzz session." category = ["default"] priority = 99 - def __init__(self, default_param, extra): - OffsetPayload.__init__(self, default_param, extra) - self.__max = 0 + def __init__(self, default_param, extra_params): + self.__max = -1 + self._it = PayloadTools.range_results(extra_params, PayloadTools.filter_results(extra_params, self._gen_wfuzz(default_param))) - def my_max_count(self): - return self.__max + def __iter__(self, default_param, extra): + return self - def my_slice_iter(self, default_param, offset, limit): - self.__max = -1 + def count(self): + return self.__max - return False, self.gen_wfuzz(default_param) + def next(self): + return self._it.next().url - def gen_wfuzz(self, output_fn): + def _gen_wfuzz(self, output_fn): try: with gzip.open(output_fn, 'r+b') as output: #with open(self.output_fn, 'r+b') as output: @@ -421,5 +440,3 @@ def gen_wfuzz(self, output_fn): except EOFError: raise StopIteration - def next (self): - return self._iterator.next().url