예제 #1
0
    def build(self, *args, **kargs):
        """
        We overload build() method in order to provide a valid default value
        for params based on TLS session if not provided. This cannot be done by
        overriding i2m() because the method is called on a copy of the packet.

        The 'params' field is built according to key_exchange.server_kx_msg_cls
        which should have been set after receiving a cipher suite in a
        previous ServerHello. Usual cases are:
        - None: for RSA encryption or fixed FF/ECDH. This should never happen,
          as no ServerKeyExchange should be generated in the first place.
        - ServerDHParams: for ephemeral FFDH. In that case, the parameter to
          server_kx_msg_cls does not matter.
        - ServerECDH*Params: for ephemeral ECDH. There are actually three
          classes, which are dispatched by _tls_server_ecdh_cls_guess on
          the first byte retrieved. The default here is b"\03", which
          corresponds to ServerECDHNamedCurveParams (implicit curves).

        When the Server*DHParams are built via .fill_missing(), the session
        server_kx_privkey will be updated accordingly.
        """
        fval = self.getfieldval("params")
        if fval is None:
            s = self.tls_session
            if s.pwcs:
                if s.pwcs.key_exchange.export:
                    cls = ServerRSAParams(tls_session=s)
                else:
                    cls = s.pwcs.key_exchange.server_kx_msg_cls(b"\x03")
                    cls = cls(tls_session=s)
                try:
                    cls.fill_missing()
                except:
                    pass
            else:
                cls = Raw()
            self.params = cls

        fval = self.getfieldval("sig")
        if fval is None:
            s = self.tls_session
            if s.pwcs:
                if not s.pwcs.key_exchange.anonymous:
                    p = self.params
                    if p is None:
                        p = ""
                    m = s.client_random + s.server_random + str(p)
                    cls = _TLSSignature(tls_session=s)
                    cls._update_sig(m, s.server_key)
                else:
                    cls = Raw()
            else:
                cls = Raw()
            self.sig = cls

        return _TLSHandshake.build(self, *args, **kargs)
예제 #2
0
파일: handshake.py 프로젝트: mcpat/scapy
    def build(self, *args, **kargs):
        """
        We overload build() method in order to provide a valid default value
        for params based on TLS session if not provided. This cannot be done by
        overriding i2m() because the method is called on a copy of the packet.

        The 'params' field is built according to key_exchange.server_kx_msg_cls
        which should have been set after receiving a cipher suite in a
        previous ServerHello. Usual cases are:
        - None: for RSA encryption or fixed FF/ECDH. This should never happen,
          as no ServerKeyExchange should be generated in the first place.
        - ServerDHParams: for ephemeral FFDH. In that case, the parameter to
          server_kx_msg_cls does not matter.
        - ServerECDH*Params: for ephemeral ECDH. There are actually three
          classes, which are dispatched by _tls_server_ecdh_cls_guess on
          the first byte retrieved. The default here is b"\03", which
          corresponds to ServerECDHNamedCurveParams (implicit curves).

        When the Server*DHParams are built via .fill_missing(), the session
        server_kx_privkey will be updated accordingly.
        """
        fval = self.getfieldval("params")
        if fval is None:
            s = self.tls_session
            if s.pwcs:
                if s.pwcs.key_exchange.export:
                    cls = ServerRSAParams(tls_session=s)
                else:
                    cls = s.pwcs.key_exchange.server_kx_msg_cls(b"\x03")
                    cls = cls(tls_session=s)
                try:
                    cls.fill_missing()
                except:
                    pass
            else:
                cls = Raw()
            self.params = cls

        fval = self.getfieldval("sig")
        if fval is None:
            s = self.tls_session
            if s.pwcs:
                if not s.pwcs.key_exchange.anonymous:
                    p = self.params
                    if p is None:
                        p = ""
                    m = s.client_random + s.server_random + str(p)
                    cls = _TLSSignature(tls_session=s)
                    cls._update_sig(m, s.server_key)
                else:
                    cls = Raw()
            else:
                cls = Raw()
            self.sig = cls

        return _TLSHandshake.build(self, *args, **kargs)
예제 #3
0
 def tls_sign(self, bytes):
     # sig_alg 0x0401 = sha256+rsa as per our certificate
     # STUDENT TODO
     """
     1. Create a TLSSignature object. set sig_alg to 0x0401
     2. use this object to sign the bytes
     """
     sig = _TLSSignature(sig_alg=0x0401)
     sig._update_sig(bytes, self.server_rsa_privkey)
     return sig
예제 #4
0
 def build(self, *args, **kargs):
     s = self.tls_session
     sig = self.getfieldval("responsedata")
     test = (sig is None and s.sslv2_key_material is not None
             and s.sslv2_challenge_clientcert is not None
             and len(s.server_certs) > 0)
     if test:
         s = self.tls_session
         m = (s.sslv2_key_material + s.sslv2_challenge_clientcert +
              s.server_certs[0].der)
         self.responsedata = _TLSSignature(tls_session=s)
         self.responsedata._update_sig(m, s.client_key)
     else:
         self.responsedata = b""
     return super(SSLv2ClientCertificate, self).build(*args, **kargs)
예제 #5
0
 def build(self, *args, **kargs):
     s = self.tls_session
     sig = self.getfieldval("responsedata")
     test = (sig is None and
             s.sslv2_key_material is not None and
             s.sslv2_challenge_clientcert is not None and
             len(s.server_certs) > 0)
     if test:
         s = self.tls_session
         m = (s.sslv2_key_material +
              s.sslv2_challenge_clientcert +
              s.server_certs[0].der)
         self.responsedata = _TLSSignature(tls_session=s)
         self.responsedata._update_sig(m, s.client_key)
     else:
         self.responsedata = ""
     return super(SSLv2ClientCertificate, self).build(*args, **kargs)
예제 #6
0
파일: handshake.py 프로젝트: mcpat/scapy
 def build(self, *args, **kargs):
     sig = self.getfieldval("sig")
     if sig is None:
         s = self.tls_session
         m = "".join(s.handshake_messages)
         if s.tls_version >= 0x0304:
             if s.connection_end == "client":
                 context_string = "TLS 1.3, client CertificateVerify"
             elif s.connection_end == "server":
                 context_string = "TLS 1.3, server CertificateVerify"
             m = b"\x20"*64 + context_string + b"\x00" + s.wcs.hash.digest(m)
         self.sig = _TLSSignature(tls_session=s)
         if s.connection_end == "client":
             self.sig._update_sig(m, s.client_key)
         elif s.connection_end == "server":
             # should be TLS 1.3 only
             self.sig._update_sig(m, s.server_key)
     return _TLSHandshake.build(self, *args, **kargs)
예제 #7
0
 def build(self, *args, **kargs):
     sig = self.getfieldval("sig")
     if sig is None:
         s = self.tls_session
         m = "".join(s.handshake_messages)
         if s.tls_version >= 0x0304:
             if s.connection_end == "client":
                 context_string = "TLS 1.3, client CertificateVerify"
             elif s.connection_end == "server":
                 context_string = "TLS 1.3, server CertificateVerify"
             m = b"\x20" * 64 + context_string + b"\x00" + s.wcs.hash.digest(
                 m)
         self.sig = _TLSSignature(tls_session=s)
         if s.connection_end == "client":
             self.sig._update_sig(m, s.client_key)
         elif s.connection_end == "server":
             # should be TLS 1.3 only
             self.sig._update_sig(m, s.server_key)
     return _TLSHandshake.build(self, *args, **kargs)
예제 #8
0
    def process_tls_handshake(self, tls_pkt, tls_msg):
        if isinstance(tls_msg, TLSClientHello):
            debug.print("Got client hello")
            debug.scapy_show(tls_msg)
            self.session.set_server_rsa_privkey(self.private_key)
            # STUDENT TODO
            """ 
            Instructions:
            1. process client hello. set the session client random appropriately
            2. create the server hello. Set cipher=TLS_DHE_RSA_WITH_AES_128_CBC_SHA.val
            3. create the server cert message. Set certs=[self.cert]
            4. create server key exchange.
                params = self.session.server_dh_params
                sig = <signature you calculate>
            5. create server hello done
            6. store in the provided server_hello, server_cert, server_key_exchange,
                and server_hello_done variables
            """
            gmt_unix_time = tls_msg.gmt_unix_time
            random_bytes = tls_msg.random_bytes
            version = tls_msg.version
            cipher = TLS_DHE_RSA_WITH_AES_128_CBC_SHA.val

            # set client time and random in session
            self.session.set_client_random(gmt_unix_time, random_bytes)
            self.session.set_server_random()

            server_hello = TLSServerHello(
                gmt_unix_time=gmt_unix_time, 
                random_bytes=self.session.server_random_bytes, 
                version=version, 
                cipher=cipher
            )

            server_cert = TLSCertificate(certs=[self.cert])

            sig = _TLSSignature(sig_alg=0x0401)
            params = self.session.server_dh_params
            m = self.session.client_random + self.session.server_random + raw(params)
            sig._update_sig(m, self.session.server_rsa_privkey)
            server_key_exchange = TLSServerKeyExchange(
                params=self.session.server_dh_params, 
                sig=sig
            )

            server_hello_done = TLSServerHelloDone()

            f_session = tlsSession()
            f_session.tls_version = 0x303
            tls_response = TLS(msg=[server_hello, server_cert, server_key_exchange, server_hello_done],
                tls_session=f_session)
            tls_response_bytes = raw(tls_response)
            debug.scapy_show(tls_response)

            self.session.record_handshake_message(raw(tls_msg))
            self.session.record_handshake_message(raw(server_hello))
            self.session.record_handshake_message(raw(server_cert))
            self.session.record_handshake_message(raw(server_key_exchange))
            self.session.record_handshake_message(raw(server_hello_done))

            return tls_response_bytes

        elif isinstance(tls_msg, TLSClientKeyExchange):
            debug.print("Got key exchange")
            debug.scapy_show(tls_msg)
            # STUDENT TODO
            """
            1. process the client key exchange by extracting the "exchkeys"
            2. These can be passed directly to session.set_client_dh_params
            """
            self.session.record_handshake_message(raw(tls_msg))
            exchkeys = tls_msg.exchkeys
            self.session.set_client_dh_params(ClientDiffieHellmanPublic(exchkeys))
            
        elif isinstance(tls_msg, TLSFinished):
            debug.print("Got Client Finished")
            debug.scapy_show(tls_msg)
            # STUDENT TODO
            """
            1. process the decrypted TLS finished message. OPTIONALLY, verify the data:
                local_verify_data = session.compute_handshake_verify("read")
                local_verify_data ?= tls_msg.vdata
            2. Create the change cipher spec
            3. store in server_change_cipher_spec
            """
            local_verify_data = self.session.compute_handshake_verify("read")
            assert(local_verify_data == tls_msg.vdata)
            self.session.record_handshake_message(raw(tls_msg))

            server_change_cipher_spec = TLSChangeCipherSpec()
            msg1 = TLS(msg=[server_change_cipher_spec])
            output = raw(msg1)

            # STUDENT TODO
            """
            1. create the TLSFinished message. 
                Set v_data to session.compute_handshake_verify("write")
                because of scapy weirdness, set tls_session=f_session
            2. store in server_finished
            """
            f_session = tlsSession()
            f_session.tls_version = 0x303
            vdata = self.session.compute_handshake_verify("write")
            assert(vdata != local_verify_data)
            server_finished = TLSFinished(
                vdata=self.session.compute_handshake_verify("write"), 
                tls_session=f_session
            )
            
            msg2 = TLS(msg=[server_finished], tls_session=f_session)
            msg2.type = 22
            
            # STUDENT TODO
            """
            1. encrypt the tls finished message (msg2). You already have a method for this.
            2. store in encrypted_finished
            """
            encrypted_finished = self.session.encrypt_tls_pkt(msg2)
            
            self.session.handshake = False
            return output+encrypted_finished
        elif isinstance(tls_msg, Raw):
            # STUDENT TODO
            """
            1. This was a HANDSHAKE message scapy couldn't process. It's because it's encrypted
            2. decrypt the packet to plaintext_data. You should already have a method for this
            3. store in plaintext_data
            4. The provided code already re-creates the TLSFinished from your decrypted data
            """
            plaintext_data = self.session.decrypt_tls_pkt(tls_pkt, is_handshake=True)

            # We re-create the TLS message with the decrypted handshake
            # Then we call `process_tls_handshake` again with this new message
            f_session = tlsSession()
            f_session.tls_version = 0x303
            decrypted_msg = TLSFinished(plaintext_data, tls_session=f_session)
            return self.process_tls_handshake(None, decrypted_msg)
            
        return b""