Exemple #1
0
    def __init__(self, value, num_bytes=1, fuzzable=True, name=None):
        '''
        :type value: str or bytes
        :param value: value to mutate
        :param num_bytes: number of consequtive bytes to flip (invert)
        :param fuzzable: is field fuzzable (default: True)
        :param name: name of the object (default: None)

        :raises: ``KittyException`` if num_bytes is bigger than the value length
        :raises: ``KittyException`` if num_bytes is not positive
        '''
        kassert.is_of_types(value, (bytes, bytearray, str))
        value = strToBytes(value)
        if len(value) < num_bytes:
            raise KittyException('len(value) <= num_bytes',
                                 (len(value), num_bytes))
        if num_bytes <= 0:
            raise KittyException('num_bytes(%d) <= 0' % (num_bytes))
        super(ByteFlip, self).__init__(value=value,
                                       encoder=ENC_STR_DEFAULT,
                                       fuzzable=fuzzable,
                                       name=name)
        self._data_len = len(value)
        self._num_bytes = num_bytes
        self._num_mutations = self._data_len - (num_bytes - 1)
Exemple #2
0
    def __init__(self, field, comp_type, comp_value):
        '''
        :param field: (name of) field that should meet the condition
        :param comp_type: how to compare the values. One of ('>', '<', '>=', '<=', '==', '!=')
        :param comp_value: value to compare the field to

        :example:

            Render the content of the `If` container only if the value
            in the field called "name" is not 'kitty'

            ::

                Template([
                    String('kitty', name='name'),
                    If(Compare('name', '!=', 'kitty'), [
                        String('current name is not kitty')
                    ])
                ])
        '''
        super(Compare, self).__init__(field=field)
        self._comp_type = comp_type
        if comp_type in Compare._comparison_types:
            if comp_type not in ['==', '!='] and isinstance(comp_value, str):
                raise KittyException('can\'t use comparison type "%s" with comparison value of type str' % comp_type)
            self._comp_fn = Compare._comparison_types[comp_type]
        else:
            raise KittyException('unknown comparison type (%s)' % (comp_type))
        if isinstance(comp_value, six.string_types):
            comp_value = strToBytes(comp_value)
        self._comp_value = comp_value
Exemple #3
0
    def __init__(self, field, comp_type, comp_value):
        '''
        :param field: (name of) field that should meet the condition
        :param comp_type: how to compare the values. One of ('>', '<', '>=', '<=', '==', '!=')
        :param comp_value: value to compare the field to

        :example:

            Render the content of the `If` container only if the value
            in the field called "name" is not 'kitty'

            ::

                Template([
                    String('kitty', name='name'),
                    If(Compare('name', '!=', 'kitty'), [
                        String('current name is not kitty')
                    ])
                ])
        '''
        super(Compare, self).__init__(field=field)
        self._comp_type = comp_type
        if comp_type in Compare._comparison_types:
            if comp_type not in ['==', '!='] and isinstance(comp_value, str):
                raise KittyException(
                    'can\'t use comparison type "%s" with comparison value of type str'
                    % comp_type)
            self._comp_fn = Compare._comparison_types[comp_type]
        else:
            raise KittyException('unknown comparison type (%s)' % (comp_type))
        if isinstance(comp_value, six.string_types):
            comp_value = strToBytes(comp_value)
        self._comp_value = comp_value
Exemple #4
0
 def _mutate(self):
     if self._step:
         length = self._min_length + self._step * self._current_index
     else:
         length = self._random.randint(self._min_length, self._max_length)
     current_bytes = ''
     for _ in range(length // 8 + 1):
         current_bytes += chr(self._random.randint(0, 255))
     self._current_value = Bits(bytes=strToBytes(current_bytes))[:length]
Exemple #5
0
 def _mutate(self):
     start, end = self._start_end()
     pre = self._default_value[:start]
     current = self._default_value[start:end]
     if sys.version_info >= (3,):
         mutated = ''.join(chr(c ^ 0xff) for c in current)
     else:
         mutated = ''.join(chr(ord(c) ^ 0xff) for c in current)
     post = self._default_value[end:]
     self.set_current_value(pre + strToBytes(mutated) + post)
Exemple #6
0
 def _mutate(self):
     start, end = self._start_end()
     pre = self._default_value[:start]
     current = self._default_value[start:end]
     if sys.version_info >= (3, ):
         mutated = ''.join(chr(c ^ 0xff) for c in current)
     else:
         mutated = ''.join(chr(ord(c) ^ 0xff) for c in current)
     post = self._default_value[end:]
     self.set_current_value(pre + strToBytes(mutated) + post)
Exemple #7
0
    def __init__(self, value, encoder=ENC_STR_DEFAULT, name=None):
        '''
        :type value: str
        :param value: default value
        :type encoder: :class:`~kitty.model.low_level.encoder.StrEncoder`
        :param encoder: encoder for the field (default: ENC_STR_DEFAULT)
        :param name: name of the object (default: None)

        :example:

            ::

                Static('this will never change')
        '''
        value = strToBytes(value)
        super(Static, self).__init__(value=value, encoder=encoder, fuzzable=False, name=name)
Exemple #8
0
    def __init__(
            self, value, min_length, max_length, unused_bits=0,
            seed=1235, num_mutations=25, step=None, encoder=ENC_BITS_DEFAULT,
            fuzzable=True, name=None):
        '''
        :type value: str
        :param value: default value, the last *unsused_bits* will be removed from the value
        :param min_length: minimal length of the field (in bits)
        :param max_length: maximal length of the field (in bits)
        :param unused_bits: how many bits from the value are not used (default: 0)
        :param seed: seed for the random number generator, to allow consistency between runs (default: 1235)
        :param num_mutations: number of mutations to perform (if step is None) (default:25)
        :type step: int
        :param step: step between lengths of each mutation (default: None)
        :type encoder: :class:`~kitty.model.low_level.encoder.BitsEncoder`
        :param encoder: encoder for the field (default: ENC_BITS_DEFAULT)
        :param fuzzable: is field fuzzable (default: True)
        :param name: name of the object (default: None)

        :examples:

            ::

                RandomBits(value='1234', min_length=0, max_length=75, unused_bits=0, step=15)
                RandomBits(value='1234', min_length=0, max_length=75, unused_bits=3, num_mutations=80)
        '''
        if unused_bits not in range(8):
            raise KittyException('unused bits (%d) is not between 0-7' % unused_bits)
        value = Bits(bytes=strToBytes(value))
        if unused_bits:
            value = value[:-unused_bits]
        super(RandomBits, self).__init__(value=value, encoder=encoder, fuzzable=fuzzable, name=name)
        self._validate_lengths(min_length, max_length)
        self._min_length = min_length
        self._max_length = max_length
        self._num_mutations = num_mutations
        self._step = step
        self._random = Random()
        self._seed = seed
        self._random.seed(self._seed)
        if self._step:
            if self._step < 0:
                raise KittyException('step (%d) < 0' % (step))
            self._num_mutations = (self._max_length - self._min_length) // self._step
Exemple #9
0
    def __init__(self, value, max_size=None, encoder=ENC_STR_DEFAULT, fuzzable=True, name=None):
        '''
        :type value: str or bytes
        :param value: default value
        :param max_size: maximal size of the string before encoding (default: None)
        :type encoder: :class:`~kitty.model.low_level.encoder.StrEncoder`
        :param encoder: encoder for the field
        :param fuzzable: is field fuzzable (default: True)
        :param name: name of the object (default: None)

        :example:

            ::

                String('this is the default value', max_size=5)
        '''
        self._max_size = None if max_size is None else max_size
        value = strToBytes(value)
        super(String, self).__init__(value=value, encoder=encoder, fuzzable=fuzzable, name=name)
Exemple #10
0
    def __init__(self, pad_length, pad_data=b'\x00', fields=[], fuzzable=True, name=None):
        '''
        :param pad_length: length to pad up to (in bits)
        :param pad_data: data to pad with (default: b'\x00')
        :param fields: enclosed field(s) (default: [])
        :param fuzzable: is fuzzable (default: True)
        :param name: (unique) name of the template (default: None)

        :example:

            Pad a string with ' 's so it is at least 20 bytes

            ::

                Pad(fields=String('padded'), pad_data=' ', pad_length=20)
                # default result will be: 'padded              '
        '''
        super(Pad, self).__init__(fields=fields, encoder=ENC_BITS_DEFAULT, fuzzable=fuzzable, name=name)
        self._pad_length = pad_length
        self._pad_data = Bits(bytes=strToBytes(pad_data))
Exemple #11
0
    def __init__(self, value, num_bits=1, fuzzable=True, name=None):
        '''
        :param value: value to mutate (str or bytes)
        :param num_bits: number of consequtive bits to flip (invert)
        :param fuzzable: is field fuzzable (default: True)
        :param name: name of the object (default: None)

        :raises: ``KittyException`` if num_bits is bigger than the value length in bits
        :raises: ``KittyException`` if num_bits is not positive
        '''
        kassert.is_of_types(value, (bytes, bytearray, str))
        value = strToBytes(value)
        if len(value) * 8 < num_bits:
            raise KittyException('len of value in bits(%d) < num_bits(%d)' % (len(value) * 8, num_bits))
        if num_bits <= 0:
            raise KittyException('num_bits(%d) <= 0' % (num_bits))
        super(BitFlip, self).__init__(value=Bits(bytes=value), encoder=ENC_BITS_DEFAULT, fuzzable=fuzzable, name=name)
        self._data_len = len(value) * 8
        self._num_bits = num_bits
        self._num_mutations = self._data_len - (num_bits - 1)
 def _encode_func(self, s):
     return hexlify(strToBytes(s))
 def testFlipTwoBitsOnSingleByte(self):
     expected_mutations = map(lambda i: strToBytes(chr(3 << i)), range(7))
     self._testBase(b'\x00', 2, expected_mutations)
 def _encode_func(self, s):
     return strToBytes(s) + b'\x00'
 def _default_value(self, data_size):
     return strToBytes(''.join(
         map(lambda x: chr(x % 0x100), range(data_size))))
 def testFlipTwoBitsOnSingleByte(self):
     expected_mutations = map(lambda i: strToBytes(chr(3 << i)), range(7))
     self._testBase(b'\x00', 2, expected_mutations)
 def testFlipSingleBitOnSingleByte(self):
     expected_mutations = map(lambda i: strToBytes(chr(1 << i)), range(8))
     self._testBase(b'\x00', 1, expected_mutations)
 def testFlipSingleBitOnSingleByte(self):
     expected_mutations = map(lambda i: strToBytes(chr(1 << i)), range(8))
     self._testBase(b'\x00', 1, expected_mutations)
 def _encode_func(self, s):
     return strToBytes(s) + b'\x00'
 def _default_value(self, data_size):
     return strToBytes(''.join(map(lambda x: chr(x % 0x100), range(data_size))))
 def _encode_func(self, s):
     return hexlify(strToBytes(s))