Beispiel #1
0
 def add_record(self, is_sslv2=None, is_tls13=None):
     """
     Add a new TLS or SSLv2 or TLS 1.3 record to the packets buffered out.
     """
     if is_sslv2 is None and is_tls13 is None:
         v = (self.cur_session.tls_version
              or self.cur_session.advertised_tls_version)
         if v in [0x0200, 0x0002]:
             is_sslv2 = True
         elif v >= 0x0304:
             is_tls13 = True
     if is_sslv2:
         self.buffer_out.append(SSLv2(tls_session=self.cur_session))
     elif is_tls13:
         self.buffer_out.append(TLS13(tls_session=self.cur_session))
     else:
         self.buffer_out.append(TLS(tls_session=self.cur_session))
Beispiel #2
0
    def get_next_msg(self, socket_timeout=2, retry=2):
        """
        The purpose of the function is to make next message(s) available in
        self.buffer_in. If the list is not empty, nothing is done. If not, in
        order to fill it, the function uses the data already available in
        self.remain_in from a previous call and waits till there are enough to
        dissect a TLS packet. Once dissected, the content of the TLS packet
        (carried messages, or 'fragments') is appended to self.buffer_in.

        We have to grab enough data to dissect a TLS packet. We start by
        reading the first 2 bytes. Unless we get anything different from
        \\x14\\x03, \\x15\\x03, \\x16\\x03 or \\x17\\x03 (which might indicate
        an SSLv2 record, whose first 2 bytes encode the length), we retrieve
        3 more bytes in order to get the length of the TLS record, and
        finally we can retrieve the remaining of the record.
        """
        if self.buffer_in:
            # A message is already available.
            return

        self.socket.settimeout(socket_timeout)
        is_sslv2_msg = False
        still_getting_len = True
        grablen = 2
        while retry and (still_getting_len or len(self.remain_in) < grablen):
            if not is_sslv2_msg and grablen == 5 and len(self.remain_in) >= 5:
                grablen = struct.unpack('!H', self.remain_in[3:5])[0] + 5
                still_getting_len = False
            elif grablen == 2 and len(self.remain_in) >= 2:
                byte0, byte1 = struct.unpack("BB", self.remain_in[:2])
                if (byte0 in _tls_type) and (byte1 == 3):
                    # Retry following TLS scheme. This will cause failure
                    # for SSLv2 packets with length 0x1{4-7}03.
                    grablen = 5
                else:
                    # Extract the SSLv2 length.
                    is_sslv2_msg = True
                    still_getting_len = False
                    if byte0 & 0x80:
                        grablen = 2 + 0 + ((byte0 & 0x7f) << 8) + byte1
                    else:
                        grablen = 2 + 1 + ((byte0 & 0x3f) << 8) + byte1
            elif not is_sslv2_msg and grablen == 5 and len(
                    self.remain_in) >= 5:  # noqa: E501
                grablen = struct.unpack('!H', self.remain_in[3:5])[0] + 5

            if grablen == len(self.remain_in):
                break

            try:
                tmp = self.socket.recv(grablen - len(self.remain_in))
                if not tmp:
                    retry -= 1
                else:
                    self.remain_in += tmp
            except Exception:
                self.vprint("Could not join host ! Retrying...")
                retry -= 1

        if len(self.remain_in) < 2 or len(self.remain_in) != grablen:
            # Remote peer is not willing to respond
            return

        if (byte0 == 0x17
                and (self.cur_session.advertised_tls_version >= 0x0304
                     or self.cur_session.tls_version >= 0x0304)):
            p = TLS13(self.remain_in, tls_session=self.cur_session)
            self.remain_in = b""
            self.buffer_in += p.inner.msg
        else:
            p = TLS(self.remain_in, tls_session=self.cur_session)
            self.cur_session = p.tls_session
            self.remain_in = b""
            if isinstance(p, SSLv2) and not p.msg:
                p.msg = Raw("")
            if self.cur_session.tls_version is None or \
               self.cur_session.tls_version < 0x0304:
                self.buffer_in += p.msg
            else:
                if isinstance(p, TLS13):
                    self.buffer_in += p.inner.msg
                else:
                    # should be TLS13ServerHello only
                    self.buffer_in += p.msg

        while p.payload:
            if isinstance(p.payload, Raw):
                self.remain_in += p.payload.load
                p = p.payload
            elif isinstance(p.payload, TLS):
                p = p.payload
                if self.cur_session.tls_version is None or \
                   self.cur_session.tls_version < 0x0304:
                    self.buffer_in += p.msg
                else:
                    self.buffer_in += p.inner.msg