def should_ADD_FINISHED(self): self.cur_pkt = TLS(tls_session=self.cur_session, msg=[]) p = TLSFinished() self.cur_pkt.msg.append(p) self.socket.send(str(self.cur_pkt)) self.cur_pkt = None raise self.ADD_FINISHED()
def should_ADD_CKE_from_ADD_CLIENT_CERT(self): self.cur_pkt = TLS(tls_session=self.cur_session, msg=[]) p = TLSClientKeyExchange() self.cur_pkt.msg.append(p) self.socket.send(str(self.cur_pkt)) self.cur_pkt = None raise self.ADD_CKE()
def PROCESS_DATA(self): """ In the beginning, we return a small page with useful information. Then, we act as an echo server. """ self.cur_pkt = self.msg_list[0] self.msg_list = self.msg_list[1:] recv_data = self.cur_pkt.data print "Received %s" % repr(recv_data) if recv_data.startswith("GET / HTTP/1."): header = "HTTP/1.1 200 OK\r\n" header += "Server: Scapy TLS Extension\r\n" header += "Content-type: text/html\r\n" header += "Content-length: %d\r\n\r\n" s = "Information on current TLS session:\n\n" s += "Local end : %s:%d\n" % (self.local_ip, self.local_port) s += "Remote end : %s:%d\n" % (self.remote_ip, self.remote_port) v = self.cur_session.advertised_tls_version v = "%s (0x%04x)" % (_tls_version[v], v) s += "TLS version : %s\n" % v s += repr(self.cur_session.wcs) body = "<html><body><pre>%s</pre></body></html>\r\n\r\n" % s page = (header + body) % len(body) else: page = recv_data p = Raw(load=page) self.cur_pkt = TLS(type=23, msg=[p], tls_session=self.cur_session) self.socket.send(str(self.cur_pkt)) raise self.FINISHED_SENT()
def build_client_hello(tls_version, cipher_suites, session_ticket=None): """ Build a ClientHello with the given TLS version, cipher suite, and optional session ticket. """ client_hello_record = None # Build TLS ClientHello if tls_version > 0x0002: extensions = None if session_ticket: extensions = [TLS_Ext_SessionTicket(ticket=session_ticket)] tls_client_hello = TLSClientHello(version=tls_version, gmt_unix_time=int(time.time()), random_bytes=randstring(28), sidlen=0, ciphers=cipher_suites, complen=1, ext=extensions) client_hello_record = TLS(msg=[tls_client_hello]) else: # SSLv2 ClientHello sslv2_client_hello = SSLv2ClientHello(version=tls_version, sidlen=0, ciphers=cipher_suites) client_hello_record = SSLv2(msg=[sslv2_client_hello]) return client_hello_record
def should_ADD_CCS_from_ADD_CKE(self): self.cur_pkt = TLS(type=20, tls_session=self.cur_session, msg=[]) p = TLSChangeCipherSpec() self.cur_pkt.msg.append(p) self.socket.send(str(self.cur_pkt)) self.cur_pkt = None raise self.ADD_CCS()
def handle(self): record_bytes = read_tls_record(self.rfile) record = TLS(record_bytes) ext_server_name = record.getlayer(TLS_Ext_ServerName) if ext_server_name == None: self.log_message("ServerName is missing from TLS record") return server_names = [ str(s.servername, "ascii") for s in ext_server_name.servernames ] self.log_message(f"Server names: {server_names}") if len(server_names) == 0: self.log_message("List of server names is empty") return host = server_names[0] s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, 443)) s.send(record_bytes) def read_client(): s.send(read_tls_record(self.rfile)) def read_remote(): self.wfile.write(read_tls_record(s)) sel = DefaultSelector() sel.register(self.rfile, EVENT_READ, read_client) sel.register(s, EVENT_READ, read_remote) got_read_error = False while not got_read_error: events = sel.select() for key, mask in events: try: key.data() except ReadError: got_read_error = True break s.close()
def NO_USABLE_CIPHERSUITE(self): """ If there is no available cipher suite, close the session with an Alert. """ print "No usable cipher suite, closing connection" self.cur_pkt = TLS(type=21, msg=[], tls_session=self.cur_session) p = TLSAlert(level=1, descr=0) self.cur_pkt.msg.append(p) self.socket.send(str(self.cur_pkt)) self.cur_pkt = None
def should_REPLY_TO_CH(self): """ XXX Several enhancements needed here. Selecting a cipher suite should be no trouble as we already caught the None case previously. However, regarding the protocol version, we might want to try resending a ClientHello when the advertised version is not deemed satisfying. Then, the sending of ServerHello, Certificate, ServerKeyExchange and ServerHelloDone should be split into multiple states, in order for the user to overload only the ones he's interested in. Also, we do not manage extensions at all. """ if isinstance(self.mykey, PrivKeyRSA): kx = "RSA" elif isinstance(self.mykey, PrivKeyECDSA): kx = "ECDSA" usable_suites = get_usable_ciphersuites(self.cur_pkt.ciphers, kx) c = usable_suites[0] if self.preferred_ciphersuite in usable_suites: c = self.preferred_ciphersuite comp = 0 if self.cur_pkt.comp and 1 in self.cur_pkt.comp: comp = 1 self.cur_session.advertised_tls_version = self.cur_pkt.version self.cur_session.tls_version = self.cur_pkt.version #XXX there should be some checks on this version from the ClientHello v = self.cur_session.tls_version print "\nVersion: " + _tls_version[v] print "Cipher suite: " + _tls_cipher_suites[c] self.cur_pkt = TLS(tls_session=self.cur_session, msg=[]) p = TLSServerHello(cipher=c, comp=[comp]) self.cur_pkt.msg.append(p) p = TLSCertificate(certs=self.cur_session.server_certs) self.cur_pkt.msg.append(p) if not _tls_cipher_suites_cls[c].kx_alg.no_ske: p = TLSServerKeyExchange() self.cur_pkt.msg.append(p) p = TLSServerHelloDone() self.cur_pkt.msg.append(p) self.socket.send(str(self.cur_pkt)) self.cur_pkt = None raise self.SENT_SH()
def get_next_msg(self): """ The purpose of the function is to make next message(s) available in self.msg_list. 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 from a previous call and waits till there are enough to dissect a TLS packet (expected length is in the 5 first bytes of the packet). Once dissected, the content of the TLS packet (carried messages) is appended to self.msg_list. We have to grab enough data to dissect a TLS packet, i.e. at least 5 bytes in order to access the expected length of the TLS packet. """ if self.msg_list: # a message is already available return self.socket.settimeout(5) retry = 5 grablen = 5 while retry and (grablen == 5 or len(self.remain) < grablen): if grablen == 5 and len(self.remain) >= 5: grablen = struct.unpack('!H', self.remain[3:5])[0] + 5 if grablen == len(self.remain): break try: tmp = self.socket.recv(grablen - len(self.remain)) if not tmp: retry -= 1 else: self.remain += tmp except: retry -= 1 if self.remain < 5 or len(self.remain) != grablen: # Remote peer is not willing to respond return # Instantiate TLS packet (record header only, at this point) p = TLS(self.remain, tls_session=self.cur_session) self.cur_session = p.tls_session self.remain = "" self.msg_list += p.msg while p.payload: if isinstance(p.payload, Raw): self.remain += p.payload.load p = p.payload elif isinstance(p.payload, TLS): p = p.payload self.msg_list += p.msg
def add_record(self, is_sslv2=None, is_tls13=None, is_tls12=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 and is_tls12 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)) # For TLS 1.3 middlebox compatibility, TLS record version must # be 0x0303 elif is_tls12: self.buffer_out.append( TLS(version="TLS 1.2", tls_session=self.cur_session)) else: self.buffer_out.append(TLS(tls_session=self.cur_session))
def WAIT_FOR_RESP2(self): self.socket.settimeout(10) s = self.socket.recv(100000) p = TLS(s, tls_session=self.cur_session) self.msg_list = p.msg while p.payload: if isinstance(p.payload, Raw): self.remain += p.payload.load p = p.payload elif isinstance(p.payload, TLS): p = p.payload self.msg_list += p.msg raise self.PREPROCESS_RESP2()
def close_session(self): """ We end the session properly after 2 seconds, with a TLS Alert (warning, close_notify). """ time.sleep(2) self.cur_pkt = TLS(type=21, msg=[], tls_session=self.cur_session) p = TLSAlert(level=1, descr=0) self.cur_pkt.msg.append(p) try: self.socket.send(str(self.cur_pkt)) except: print "Could not send termination Alert (maybe the server stopped)" self.cur_pkt = None
def do_dissect_payload(self, s): """ Try to dissect the following data as a TLS message. Note that overloading .guess_payload_class() would not be enough, as the TLS session to be used would get lost. """ if s: try: p = TLS(s, _internal=1, _underlayer=self, tls_session=self.tls_session) except KeyboardInterrupt: raise except Exception: p = conf.raw_layer(s, _internal=1, _underlayer=self) self.add_payload(p)
def banner2ja3c(banner: bytes) -> Optional[str]: # "lazy" import for scapy, as this import is slow. # TLS is assigned by the import statement, but pylint seems to miss it. global HAS_SCAPY, TLS # pylint: disable=global-variable-not-assigned if HAS_SCAPY is None: try: # noqa: E402 # pylint: disable=import-outside-toplevel from scapy.layers.tls.record import TLS # type: ignore except ImportError: HAS_SCAPY = False else: HAS_SCAPY = True if not HAS_SCAPY: utils.LOGGER.warning("Scapy not found: cannot parse TLS banners") return None data = TLS(banner) # type: ignore try: if data.type != 22: # handshake return None except AttributeError: return None output = [] for msg in data.msg: try: if msg.msgtype != 1: # TLSClientHello continue except AttributeError: utils.LOGGER.warning("Cannot parse TLS message [%r]", msg) continue output.append(str(msg.version)) output.append("-".join( str(c) for c in msg.ciphers or [] if c not in GREASE)) output.append("-".join( str(e.type) for e in msg.ext or [] if e.type not in GREASE)) ecsg: List[str] = [] ecpf: List[str] = [] for ext in msg.ext or []: if ext.type == 10: # supported_groups / elliptic_curves ecsg.extend(str(g) for g in ext.groups if g not in GREASE) elif ext.type == 11: # ec_point_formats ecpf.extend(str(p) for p in ext.ecpl if p not in GREASE) output.append("-".join(ecsg)) output.append("-".join(ecpf)) break if not output: return None return ",".join(output)
def should_ADD_CV_from_ADD_CKE(self): """ XXX Section 7.4.7.1 of RFC 5246 states that the CertificateVerify message is only sent following a client certificate that has signing capability (i.e. not those containing fixed DH params). We should verify that before adding the message. We should also handle the case when the Certificate message was empty. """ if (not self.cert_req or self.mycert is None or self.mykey is None): return self.cur_pkt = TLS(tls_session=self.cur_session, msg=[]) p = TLSCertificateVerify() self.cur_pkt.msg.append(p) self.socket.send(str(self.cur_pkt)) self.cur_pkt = None raise self.ADD_CV()
def send_recv_data(self): """ XXX No live input from the user ; one unique send for now. XXX We might want not to send any ApplicationData message. XXX We do not wait very long for server answer. """ txt = self.data or "GET /\r\n\r\n" # GET HTTP/1.1\r\n\r\n" p = TLS(type=23, tls_session=self.cur_session, msg=[Raw(load=txt)]) self.socket.send(str(p)) print "Sent to server: \n%r" % txt self.get_next_msg(1, 0) if self.msg_list: p = self.msg_list[0] self.msg_list = self.msg_list[1:] if isinstance(p, Raw): print "Received from server: \n%s" % p.load else: print "Received from server: \n%s" % p
def should_ADD_CLIENT_CERT(self): """ If the server sent a CertificateRequest, we send a Certificate message. If no certificate is available, an empty Certificate message is sent: - this is a SHOULD in RFC 4346 (Section 7.4.6) - this is a MUST in RFC 5246 (Section 7.4.6) XXX We may want to add a complete chain. """ if not self.cert_req: return certs = [] if self.mycert: certs = [self.mycert] self.cur_pkt = TLS(tls_session=self.cur_session, msg=[]) p = TLSCertificate(certs=certs) self.cur_pkt.msg.append(p) self.socket.send(str(self.cur_pkt)) self.cur_pkt = None raise self.ADD_CLIENT_CERT()
def banner2ja3c(banner: bytes) -> Optional[str]: if not HAS_SCAPY: utils.LOGGER.warning("Scapy not found: cannot parse TLS banners") return None data = TLS(banner) try: if data.type != 22: # handshake return None except AttributeError: return None output = [] for msg in data.msg: try: if msg.msgtype != 1: # TLSClientHello continue except AttributeError: utils.LOGGER.warning("Cannot parse TLS message [%r]", msg) continue output.append(str(msg.version)) output.append("-".join(str(c) for c in msg.ciphers or [] if c not in GREASE)) output.append( "-".join(str(e.type) for e in msg.ext or [] if e.type not in GREASE) ) ecsg: List[str] = [] ecpf: List[str] = [] for ext in msg.ext or []: if ext.type == 10: # supported_groups / elliptic_curves ecsg.extend(str(g) for g in ext.groups if g not in GREASE) elif ext.type == 11: # ec_point_formats ecpf.extend(str(p) for p in ext.ecpl if p not in GREASE) output.append("-".join(ecsg)) output.append("-".join(ecpf)) break if not output: return None return ",".join(output)
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 = struct.unpack("B", self.remain_in[0])[0] byte1 = struct.unpack("B", self.remain_in[1])[0] 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: 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: retry -= 1 if self.remain_in < 2 or len(self.remain_in) != grablen: # Remote peer is not willing to respond return p = TLS(self.remain_in, tls_session=self.cur_session) self.cur_session = p.tls_session self.remain_in = "" if isinstance(p, SSLv2) and not p.msg: p.msg = Raw("") if 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 < 0x0304: self.buffer_in += p.msg else: self.buffer_in += p.inner.msg
async def get_sros_certificate(address, port, timeout=3): """ Function to connect to a SROS Node, simulate the TLS handshake, and get it's server certificate on the process. :param address: Address of the node. :param port: Port of the node. :param timeout: Timeout for the connection. :return: A tuple containing the address, port and certificate if found, otherwise, a tuple containing address, port and None. """ client_hello = TLS( version='TLS 1.0', msg=TLSClientHello( ciphers=[ 49200, 49196, 49202, 49198, 49199, 49195, 49201, 49197, 165, 163, 161, 159, 164, 162, 160, 158, 49192, 49188, 49172, 49162, 49194, 49190, 49167, 49157, 107, 106, 105, 104, 57, 56, 55, 54, 49191, 49187, 49171, 49161, 49193, 49189, 49166, 49156, 103, 64, 63, 62, 51, 50, 49, 48, 136, 135, 134, 133, 69, 68, 67, 66, 49170, 49160, 49165, 49155, 22, 19, 16, 13, 157, 156, 61, 53, 60, 47, 132, 65, 10, 255 ], comp=[0], gmt_unix_time=12345566, ext=[ TLS_Ext_SupportedGroups( groups=[23, 25, 28, 27, 24, 26, 22, 14, 13, 11, 12, 9, 10 ]), TLS_Ext_SupportedPointFormat(ecpl=[0, 1, 2]), TLS_Ext_SignatureAlgorithms(sig_algs=[ 1537, 1538, 1539, 1281, 1282, 1283, 1025, 1026, 1027, 769, 770, 771, 513, 514, 515 ]), TLS_Ext_Heartbeat(heartbeat_mode=1), TLS_Ext_Padding(padding=212 * b'\x00') ])) tls_header = b'\x16\x03\x03' server_hello_done = b'\x0e\x00\x00\x00' received_data = b'' is_sros = True writer = None try: conn = asyncio.open_connection(str(address), port, loop=asyncio.get_event_loop()) reader, writer = await asyncio.wait_for(conn, timeout=timeout) writer.write(bytes(client_hello)) await writer.drain() while received_data[-4:] != server_hello_done: received_data += await asyncio.wait_for(reader.read(1024), timeout=3) if received_data[:3] != tls_header: is_sros = False break except Exception as e: logger.error('[-] Error connecting to host ' + str(address) + ': ' + str(e) + '\n\tNot a SROS host') return address, port, None else: if is_sros: server_hello = TLS(received_data) cert = server_hello.payload.msg[0].certs[0][1] logger.warning('[+] SROS host found!!!') return address, port, cert finally: if writer: writer.close() await writer.wait_closed() return address, port, None
def should_SEND_FINISHED(self): p = TLSFinished() self.cur_pkt = TLS(tls_session=self.cur_session, msg=[p]) self.socket.send(str(self.cur_pkt)) self.cur_pkt = None raise self.FINISHED_SENT()
def should_SEND_CCS(self): ccs = TLSChangeCipherSpec() self.cur_pkt = TLS(type=20, msg=[ccs], tls_session=self.cur_session) self.socket.send(str(self.cur_pkt)) self.cur_pkt = None raise self.SEND_CCS()
def decryptTLSStream(self): """ Generator function that decrypts an RDP stream that uses TLS. """ tpktParser = TPKTParser() tls = None clientRandom = None serverRandom = None currentTimeStamp = None reconstructingRecord = False savedRecord = None savedPayload = b"" tlsKeyGenerated = False for packet in self.packets: ip = packet.getlayer(IP) tcp = packet.getlayer(TCP) if len(tcp.payload) == 0 or tcp.flags & TCPFlags.PSH == 0: continue currentTimeStamp = packet.time currentSrc = ip.src currentDst = ip.dst # The first couple messages don't use TLS. Check if it's one of those messages and output it as is. if hasattr(tcp, "load") and tpktParser.isTPKTPDU(tcp.load): yield PCAPStream.output(tcp.load, currentTimeStamp, ip.src, ip.dst) continue # Create the TLS session context. if not tls: tls = tlsSession( ipsrc=ip.src, ipdst=ip.dst, sport=tcp.sport, dport=tcp.dport, connection_end="server", ) if tls.ipsrc != ip.src: tls = tls.mirror() # Pass every TLS message through our own custom session so the state is kept properly record = packet[TLS] record = TLS(bytes(record), tls_session=tls) for msg in record.msg: if isinstance(msg, TLSClientHello): clientRandom = pkcs_i2osp(msg.gmt_unix_time, 4) + msg.random_bytes elif isinstance(msg, TLSServerHello): serverRandom = pkcs_i2osp(msg.gmt_unix_time, 4) + msg.random_bytes elif isinstance(msg, TLSNewSessionTicket): # Session established, set master secret. tls.rcs.derive_keys( client_random=clientRandom, server_random=serverRandom, master_secret=self.masterSecret, ) tls.wcs.derive_keys( client_random=clientRandom, server_random=serverRandom, master_secret=self.masterSecret, ) tlsKeyGenerated = True elif isinstance(msg, TLSApplicationData): yield PCAPStream.output(msg.data, currentTimeStamp, ip.src, ip.dst)
def build_tls_record(tls_data): """ Build a TLS record using the given data. """ return TLS(tls_data)
def build_tls_record_with_message(message): """ Build a TLS record using the given message parameter. """ return TLS(msg=[message])
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 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
def PREPARE_FIRST_PKT(self): self.cur_pkt = TLS(tls_session=self.cur_session)