diff --git a/katnip/legos/http.py b/katnip/legos/http.py index c1fbdc9a3..514b79d0d 100644 --- a/katnip/legos/http.py +++ b/katnip/legos/http.py @@ -12,43 +12,68 @@ def _keyname(txt): return '%s_key' % txt +def bit_length(num): + for x in range(1, 100): + if num.bit_length() > (2 << x): + continue + else: + return 2 << x + + class CustomHeaderField(Container): - def __init__(self, key, value, end=False, fuzzable_key=False, fuzzable_value=True): + def __init__(self, key, value, params={}, end=False, fuzzable_key=False, fuzzable_value=True, name=None): fields = [ String(name=_keyname(key), value=key, fuzzable=fuzzable_key), Static(': '), Container(name=_valuename(key), fields=value, fuzzable=fuzzable_value), - Static('\r\n') ] + # Append Field value params, splitted by '; ' + for k, v in params.items(): + fields += [ + Static('; '), + String(value=k, name='%s_param_%s' % (_valuename(key), k)), + Static('="'), + String(value=v, name='%s_param_%s' % (_valuename(key), v)), + Static('"') + ] + # Append end of line for current Field + fields.append(Static('\r\n')) if end: fields.append(Static('\r\n')) - super(CustomHeaderField, self).__init__(name=key, fields=fields, fuzzable=fuzzable_value) + name = key if name is None else name + super(CustomHeaderField, self).__init__(name=name, fields=fields, fuzzable=fuzzable_value) class TextField(CustomHeaderField): - def __init__(self, key, value, end=False, fuzzable_key=False, fuzzable_value=True): + def __init__(self, key, value, params={}, end=False, fuzzable_key=False, fuzzable_value=True, name=None): value_field = String(name="value", value=value) - super(TextField, self).__init__(key, value_field, end, fuzzable_key, fuzzable_value) + super(TextField, self).__init__(key=key, value=value_field, params=params, + end=end, fuzzable_key=fuzzable_key, + fuzzable_value=fuzzable_value, name=name) class IntField(CustomHeaderField): - def __init__(self, key, value, end=False, fuzzable_key=False, fuzzable_value=True): + def __init__(self, key, value, params={}, end=False, fuzzable_key=False, fuzzable_value=True, name=None): value_field = DecimalNumber( name="value", value=value, - num_bits=32, + num_bits=bit_length(value), signed=True ) - super(IntField, self).__init__(key, value_field, end, fuzzable_key, fuzzable_value) + super(IntField, self).__init__(key=key, value=value_field, params=params, + end=end, fuzzable_key=fuzzable_key, + fuzzable_value=fuzzable_value, name=name) class ContentLengthField(CustomHeaderField): def __init__(self, value, sized_field, end=False, fuzzable_key=False, fuzzable_value=True): value_field = OneOf(fields=[ - Size(sized_field=sized_field, length=32, encoder=ENC_INT_DEC), - DecimalNumber(name="value", value=value, num_bits=32, signed=True), + Size(sized_field=sized_field, length=bit_length(value), encoder=ENC_INT_DEC), + DecimalNumber(name="value", value=value, num_bits=bit_length(value), signed=True), ]) - super(ContentLengthField, self).__init__('Content-Length', value_field, end, fuzzable_key, fuzzable_value) + super(ContentLengthField, self).__init__(key='Content-Length', value=value_field, + end=end, fuzzable_key=fuzzable_key, + fuzzable_value=fuzzable_value) class AuthorizationField(CustomHeaderField): @@ -61,11 +86,13 @@ def __init__(self, key, username, password, end=False, delim=':', fuzz_username= String(name='password', value=password, fuzzable=fuzz_password), ], encoder=ENC_BITS_BASE64) ] - super(AuthorizationField, self).__init__(key, value_field, end, fuzzable_key, fuzzable) + super(AuthorizationField, self).__init__(key=key, value=value_field, params={}, + end=end, fuzzable_key=fuzzable_key, + fuzzable_value=fuzzable) class HttpRequestLine(Container): - def __init__(self, name='http_request_line', method='GET', uri='/', protocol='HTTP', version=1.0, fuzzable_method=False, fuzzable_uri=False, fuzzable=True): + def __init__(self, name='http_request_line', method='GET', uri='/', protocol='HTTP', version=1.0, fuzzable_method=False, fuzzable_uri=True, fuzzable=True): method_value = [method] if isinstance(method, str) else method parsed = urlparse(uri) uri_value = [Path(path=parsed.path, name='path', fuzz_delims=False)] diff --git a/katnip/legos/url.py b/katnip/legos/url.py index 8cc46f3c0..a70525819 100644 --- a/katnip/legos/url.py +++ b/katnip/legos/url.py @@ -254,9 +254,11 @@ def __init__(self, search='', fuzz_delims=False, fuzz_param=False, fuzz_value=Tr ] for i, part in enumerate(search.split('&')): part = part.split('=') + if len(part) != 2: + continue if len(fields) >= 2: fields.append(Delimiter(name='search_delim_%d' % i, value='&', fuzzable=fuzz_delims)) - fields.append(Container(name='param_%s' % part[0], fields=[ + fields.append(Container(name='param_%d_%s' % (i, part[0]), fields=[ String(name='search_%d_key' % i, value=part[0], fuzzable=fuzz_param), Delimiter(value='=', fuzzable=fuzz_delims), String(name='search_%d_value' % i, value=part[1], fuzzable=fuzz_value)