Exemplo n.º 1
0
    def payload(self):
        payload = bytearray()

        # write padding length
        padding_length = encode_unsigned_integer(
            PushPromiseFrame.__default_padding_length, PushPromiseFrame.__padding_length_length)
        payload.extend(padding_length)

        # write promised stream id
        promised_stream_id = encode_unsigned_integer(
            self.promised_stream_id, PushPromiseFrame.__promised_stream_id_length)
        payload.extend(promised_stream_id)

        # write header block fragment
        header_block = self.encoded_headers()
        payload.extend(header_block)

        # write padding
        # TODO: should it use different padding length?
        if PushPromiseFrame.__default_padding_length > 0:
            padding = [0x0] * PushPromiseFrame.__default_padding_length
            payload.extend(padding)
        else:
            padding = bytearray()

        self.verbose('write a push promise frame:',
                       'padding length:     {0}'.format(helper.bytes2hex(padding_length)),
                       'promised stream id: {0}'.format(helper.bytes2hex(promised_stream_id)),
                       'header block:          ',
                       helper.bytes2hex(header_block),
                       'padding:               ',
                       helper.bytes2hex(padding))

        return payload
Exemplo n.º 2
0
    def payload(self):
        payload = bytearray()

        # write padding length
        padding_length = encode_unsigned_integer(
            DataFrame.__default_padding_length, DataFrame.__padding_length_length)
        payload.extend(padding_length)

        # write data
        payload.extend(self.data)

        # write padding
        if DataFrame.__default_padding_length > 0:
            padding = [0x0] * DataFrame.__default_padding_length
            payload.extend(padding)
        else:
            padding = bytearray()

        self.verbose('write a data frame:',
                       'padding length:    {0}'.format(helper.bytes2hex(padding_length)),
                       'data:              ',
                       helper.bytes2hex(self.data),
                       'padding:           ',
                       helper.bytes2hex(padding))

        return payload
Exemplo n.º 3
0
    def encode(self, payload):
        data = bytearray()

        # write 24 bits of payload length
        length = len(payload)
        encoded_length = encode_unsigned_integer(length, self.length_length)
        self.verbose('create a frame: write a length ({0:d}): {1:s}'
                       .format(length, helper.bytes2hex(encoded_length)))
        data.extend(encoded_length)

        # write a frame type (8 bits)
        data.extend(encode_unsigned_integer(self.frame_type, self.type_length))

        # write flags (8 bits)
        data.extend(encode_unsigned_integer(self.flags, self.flags_length))

        # write a stream id expressed as an unsigned 32-bit integer
        # the spec defines a stream id field at an unsigned 31-bit integer,
        # and 1 bit is reserved and must be set to 0
        data.extend(encode_unsigned_integer(self.stream_id, self.stream_id_length))

        # write payload
        data.extend(payload)

        return data
Exemplo n.º 4
0
    def payload(self):
        payload = bytearray()
        payload.extend(self.data)
        self.verbose('write a ping frame:',
                       'data:           {0}'.format(helper.bytes2hex(self.data)))

        return payload
Exemplo n.º 5
0
    def payload(self):
        payload = bytearray()

        # write padding length
        padding_length = encode_unsigned_integer(
            HeadersFrame.__default_padding_length, HeadersFrame.__padding_length_length)
        payload.extend(padding_length)

        # write no exclusive flag, and no stream dependency
        stream_dependency = encode_unsigned_integer(
            HeadersFrame.__default_dependency, HeadersFrame.__dependency_length)
        payload.extend(stream_dependency)

        # write weight
        weight = encode_unsigned_integer(
            HeadersFrame.__default_weight, HeadersFrame.__weight_length)
        payload.extend(weight)

        # write header block fragment
        header_block = self.encoded_headers()
        payload.extend(header_block)

        # write padding
        #
        # according to the spec
        #
        # Padding:  Padding octets that contain no application semantic value.
        # Padding octets MUST be set to zero when sending.  A receiver is
        # not obligated to verify padding but MAY treat non-zero padding as
        # a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
        if HeadersFrame.__default_padding_length > 0:
            padding = [0x0] * HeadersFrame.__default_padding_length
            payload.extend(padding)
        else:
            padding = bytearray()

        self.verbose('write a header frame:',
                       'padding length:    {0}'.format(helper.bytes2hex(padding_length)),
                       'stream dependency: {0}'.format(helper.bytes2hex(stream_dependency)),
                       'weight:            {0}'.format(helper.bytes2hex(weight)),
                       'header block:      ',
                       helper.bytes2hex(header_block),
                       'padding:           ',
                       helper.bytes2hex(padding))

        return payload
Exemplo n.º 6
0
 def next(self, stream_id = 0x0):
     self.info('generate a ping frame, stream id = {0:d}'.format(stream_id))
     self.random.seed(self.seed * self.test)
     data = bytearray()
     for i in range(PingFrame.opaque_data_length):
         data.append(self.random.randint(0, 255))
     self.verbose('fuzzed data:', helper.bytes2hex(data))
     return PingFrame(data).encode()
Exemplo n.º 7
0
 def next(self, stream_id=0x0):
     self.info('generate a ping frame, stream id = {0:d}'.format(stream_id))
     self.random.seed(self.seed * self.test)
     data = bytearray()
     for i in range(PingFrame.opaque_data_length):
         data.append(self.random.randint(0, 255))
     self.verbose('fuzzed data:', helper.bytes2hex(data))
     return PingFrame(data).encode()
Exemplo n.º 8
0
    def payload(self):
        payload = bytearray()

        # write no exclusive flag, and no stream dependency
        stream_dependency = encode_unsigned_integer(
            PriorityFrame.__default_dependency, PriorityFrame.__dependency_length)
        payload.extend(stream_dependency)

        # write weight
        weight = encode_unsigned_integer(
            PriorityFrame.__default_weight, PriorityFrame.__weight_length)
        payload.extend(weight)

        self.verbose('write a priority frame:',
                       'stream dependency: {0}'.format(helper.bytes2hex(stream_dependency)),
                       'weight:            {0}'.format(helper.bytes2hex(weight)))

        return payload
Exemplo n.º 9
0
    def payload(self):
        payload = bytearray()

        # write header block fragment
        header_block = self.encoded_headers()
        payload.extend(header_block)

        self.verbose('write a continuation frame:',
                       'header block:          ',
                       helper.bytes2hex(header_block))

        return payload
Exemplo n.º 10
0
    def __init__(self, data = None, seed = 1, min_ratio = 0.01, max_ratio = 0.05,
                 start_test = 0, ignored_symbols = ()):

        AbstractDumbFuzzer.__init__(self, seed, min_ratio, max_ratio, start_test)

        if data is None:
            self.data = bytearray()
            random_byte = random.Random()
            random_byte.seed(seed)
            for i in range(256):
                self.data.append(random_byte.randint(0, 255))
        else:
            self.data = data

        self.verbose('original data:', helper.bytes2hex(self.data))
        self.set_fuzzer(DumbByteArrayFuzzer(
            self.data, seed, min_ratio, max_ratio, start_test, ignored_symbols))
Exemplo n.º 11
0
    def run(self):
        self.client = connection.Client(self.host, self.port, self.is_tls)

        self.info('started, test range {0}:{1}'.format(self.start_test,
                                                       self.end_test))
        test = self.start_test
        successfully_sent = True
        while test <= self.end_test:
            if self.client.isconnected() is False:
                self.client.connect()
                self.info('send a client connection preface')
                self.client.send(http2core.getclientpreface())
                self.info('send a valid settings frame')

                # TODO: it can be created once
                settings = SettingsFrame()
                self.client.send(settings.encode())
                data = self.client.receive()

            try:
                self.info('test {0:d}: start'.format(test))
                if successfully_sent:
                    fuzzed_data = self.next()
                    successfully_sent = False
                self.client.send(fuzzed_data)
                successfully_sent = True
            except socket.error as msg:
                # move on to next test only if current one was successfully sent out
                # TODO: delay?
                self.info(
                    'test {0:d}: a error occured while sending data: {1}'.
                    format(test, msg))
                self.info('test {0:d}: re-connect'.format(test))
                continue

            try:
                data = self.client.receive()
                self.info('test {0:d}: received data:'.format(test),
                          helper.bytes2hex(data))
            except socket.error as msg:
                self.info(
                    'test {0:d}: a error occured while receiving data, ignore it: {1}'
                    .format(test, msg))

            test += 1
Exemplo n.º 12
0
    def run(self):
        self.client = connection.Client(self.host, self.port, self.is_tls)

        self.info('started, test range {0}:{1}'
                    .format(self.start_test, self.end_test))
        test = self.start_test
        successfully_sent = True
        while test <= self.end_test:
            if self.client.isconnected() is False:
                self.client.connect()
                self.info('send a client connection preface')
                self.client.send(http2core.getclientpreface())
                self.info('send a valid settings frame')

                # TODO: it can be created once
                settings = SettingsFrame()
                self.client.send(settings.encode())
                data = self.client.receive()

            try:
                self.info('test {0:d}: start'.format(test))
                if successfully_sent:
                    fuzzed_data = self.next()
                    successfully_sent = False
                self.client.send(fuzzed_data)
                successfully_sent = True
            except socket.error as msg:
                # move on to next test only if current one was successfully sent out
                # TODO: delay?
                self.info('test {0:d}: a error occured while sending data: {1}'
                            .format(test, msg))
                self.info('test {0:d}: re-connect'.format(test))
                continue

            try:
                data = self.client.receive()
                self.info('test {0:d}: received data:'.format(test), helper.bytes2hex(data))
            except socket.error as msg:
                self.info('test {0:d}: a error occured while receiving data, ignore it: {1}'
                            .format(test, msg))

            test += 1
Exemplo n.º 13
0
    def handle(self, socket):
        self.info('send a valid settings frame')

        # TODO: it can be created once
        settings = SettingsFrame()

        # TODO: hack for hghtt2, the spec recommends to enable push,
        #       but nghttp2 client doesn't work with it
        #       can it be configured in command line?
        settings.disable_push()

        socket.send(settings.encode())
        data = socket.recv(1024)

        # TODO: HTTP/2 server must include ":status" pseudo-header field in all
        #       responses; otherwise, the response is malformed

        while (self.test <= self.end_test):
            try:
                self.info('test {0:d}: start'.format(self.test))
                fuzzer = self.fuzzers[self.next_fuzzer]
                fuzzer.set_test(self.test)
                fuzzed_data = fuzzer.next()
                self.next_fuzzer = (self.next_fuzzer + 1) % len(self.fuzzers)
                socket.sendall(fuzzed_data)
            except OSError as msg:
                self.info(
                    'test {0:d}: a error occured while sending data: {1}'.
                    format(self.test, msg))
                self.info('test {0:d}: will be run again '.format(self.test))
                break

            try:
                data = socket.recv(1024)
                self.info('test {0:d}: received data:'.format(self.test),
                          helper.bytes2hex(data))
            except OSError as msg:
                self.info(
                    'test {0:d}: a error occured while receiving data, ignore it: {1}'
                    .format(self.test, msg))

            self.test += 1
Exemplo n.º 14
0
    def handle(self, socket):
        self.info('send a valid settings frame')

        # TODO: it can be created once
        settings = SettingsFrame()

        # TODO: hack for hghtt2, the spec recommends to enable push,
        #       but nghttp2 client doesn't work with it
        #       can it be configured in command line?
        settings.disable_push()

        socket.send(settings.encode())
        data = socket.recv(1024)

        # TODO: HTTP/2 server must include ":status" pseudo-header field in all
        #       responses; otherwise, the response is malformed

        while (self.test <= self.end_test):
            try:
                self.info('test {0:d}: start'.format(self.test))
                fuzzer = self.fuzzers[self.next_fuzzer]
                fuzzer.set_test(self.test)
                fuzzed_data = fuzzer.next()
                self.next_fuzzer = (self.next_fuzzer + 1) % len(self.fuzzers)
                socket.sendall(fuzzed_data)
            except OSError as msg:
                self.info('test {0:d}: a error occured while sending data: {1}'
                            .format(self.test, msg))
                self.info('test {0:d}: will be run again '.format(self.test))
                break

            try:
                data = socket.recv(1024)
                self.info('test {0:d}: received data:'
                            .format(self.test), helper.bytes2hex(data))
            except OSError as msg:
                self.info('test {0:d}: a error occured while receiving data, ignore it: {1}'
                            .format(self.test, msg))

            self.test += 1
Exemplo n.º 15
0
    def payload(self):
        payload = bytearray()

        # write last stream id
        last_stream_id = encode_unsigned_integer(
            self.last_stream_id, GoAwayFrame.__last_stream_id_length)
        payload.extend(last_stream_id)

        # write error code
        error_code = encode_unsigned_integer(
            self.error_code, GoAwayFrame.__error_code_length)
        payload.extend(error_code)

        if len(self.debug_data) > 0:
            payload.extend(self.debug_data)

        self.verbose('write a goaway frame:',
                       'last stream id: {0}'.format(self.last_stream_id),
                       'error code:     {0}'.format(self.error_code),
                       'debug data:     {0}'.format(helper.bytes2hex(self.debug_data)))

        return payload
Exemplo n.º 16
0
    def __init__(self,
                 data=None,
                 seed=1,
                 min_ratio=0.01,
                 max_ratio=0.05,
                 start_test=0,
                 ignored_symbols=()):

        AbstractDumbFuzzer.__init__(self, seed, min_ratio, max_ratio,
                                    start_test)

        if data is None:
            self.data = bytearray()
            random_byte = random.Random()
            random_byte.seed(seed)
            for i in range(256):
                self.data.append(random_byte.randint(0, 255))
        else:
            self.data = data

        self.verbose('original data:', helper.bytes2hex(self.data))
        self.set_fuzzer(
            DumbByteArrayFuzzer(self.data, seed, min_ratio, max_ratio,
                                start_test, ignored_symbols))
Exemplo n.º 17
0
 def next(self, stream_id = 1):
     self.info('generate a data frame, stream id = {0:d}'.format(stream_id))
     fuzzed_data = self.fuzzer.next()
     self.verbose('fuzzed data:', helper.bytes2hex(fuzzed_data))
     return DataFrame(stream_id, fuzzed_data).encode()
Exemplo n.º 18
0
 def next(self, stream_id=1):
     self.info('generate a data frame, stream id = {0:d}'.format(stream_id))
     fuzzed_data = self.fuzzer.next()
     self.verbose('fuzzed data:', helper.bytes2hex(fuzzed_data))
     return DataFrame(stream_id, fuzzed_data).encode()