예제 #1
0
    def sendSentinel(self):
        """
        State 1:  Send sentinel

           Cookie :  SESSSIONID=HandshakeID; ID=Tunnel_Tag

        HandshakeID = Sentinel+Nonce_Client
        """
        self.rc4_handshake_c2d = RC4.RC4(self.session_key)
        self.rc4_handshake_d2c = RC4.RC4(self.session_key)
        self.rc4_tunnel = RC4.RC4(self.session_key)

        # Filler text
        #
        plain_text = const.HTTPU_CLIENTHELLO

        auth_plain_text = '%s%s%s' % (self.encoder.digest(plain_text),
                                      const.HTTPU_HASHSEP, plain_text)

        cipher_text = self.rc4_handshake_c2d.update(auth_plain_text)

        # HTTP Request
        #
        req = http_util.create_http_req(self, cipher_text, self.handshake_ID,
                                        self.tunnel_tag.encode("hex"),
                                        self.host_name)

        self.transport.write(req)

        # New state
        #
        self.state = const.STATE_3_UNI
예제 #2
0
    def __rsa_key_exchange(self, data, metadata):
        if self.check_sid(self.s_sid):
            # XXX: The fact that the server session ID is in
            # the dictionary already is a really bad thing.
            # There should be no client key exchange message
            # if the client and server agree to resume.
            raise sslimBadValue("SID found with client key exchange")

        # XXX: The size of this is dependent upon the cipher suite chosen!
        # Section 7.4.7.1 of RFC5246 details what these bytes mean for
        # RSA authentication!
        if self.ver == self.SSLv3_0:
            if self.cipher_suite['key_exch'] != 'RSA':
                raise sslimUnknownCipher("SSLv3 not RSA key exchange")
            pms = data
        else:
            # The first two bytes are the length of the key.
            pms_len = int(struct.unpack('>H', data[:self.hs_pms_len_size])[0])
            data = data[self.hs_pms_len_size:]
            pms = struct.unpack('%ss' % pms_len, data[:pms_len])[0]

        metadata['pre_master_secret'] = pms

        if self.keypair:
            try:
                cpms = self.keypair.private_decrypt(pms, RSA.sslv23_padding)
            except Exception as e:
                raise sslimCryptoError(str(e))

            seed = self.c_rnd + self.s_rnd
            self.ms = self.__PRF(cpms, "master secret", seed, 48)[:48]

            metadata['master_secret'] = self.ms

            # Store the master secret in the sids dictionary
            self.store_ms(self.s_sid, self.ms)

            # From the master secret you generate the key material
            seed = self.s_rnd + self.c_rnd
            km = self.__key_material(self.cipher_suite['km_len'],
                                     self.s_rnd + self.c_rnd, self.ms)
            keys = self.__split_key_material(km)
            metadata['keys'] = keys
            self.cipher_suite['keys'] = keys
            if self.cipher_suite['cipher'] == 'stream':
                self.c_cryptobj = RC4.RC4(keys['client_enc_key'])
                self.s_cryptobj = RC4.RC4(keys['server_enc_key'])
            elif self.cipher_suite['cipher'] == 'block':
                self.c_cryptobj = EVP.Cipher(self.cipher_suite['algo'],
                                             keys['client_enc_key'],
                                             keys['client_iv'],
                                             0,
                                             padding=0)
                self.s_cryptobj = EVP.Cipher(self.cipher_suite['algo'],
                                             keys['server_enc_key'],
                                             keys['server_iv'],
                                             0,
                                             padding=0)
예제 #3
0
 def set_skey(self, SKEY):
     if not self.block3b:
         self.block3b = self._gen_block3b(SKEY)
     crypta = RC4.RC4(sha('keyA' + self.S + SKEY).digest())
     cryptb = RC4.RC4(sha('keyB' + self.S + SKEY).digest())
     if self.initiator:
         self.encrypt = crypta.update
         self.decrypt = cryptb.update
     else:
         self.encrypt = cryptb.update
         self.decrypt = crypta.update
     self.encrypt('x' * 1024)  # discard first 1024 bytes
     self.decrypt('x' * 1024)
예제 #4
0
    def __init__(self):

        global allocated_sentinel, use_crypto, ccp_port, addr

        self.src_factory = Factory()
        self.src_factory.protocol = SrcProtocol
        self.src_factory.dst_p = self

        self.buf = ''
        self.sentinel_hex = allocated_sentinel
        self.session_key = self.sentinel_hex[const.SENTINEL_HEX_LEN:]
        self.rc4_handshake_c2d = RC4.RC4(self.session_key)
        self.rc4_handshake_d2c = RC4.RC4(self.session_key)
        self.rc4_tunnel = RC4.RC4(self.session_key)

        self.isFirst = True
        self.gotFillerDataCount = 0
        self.send_chaff = LoopingCall(self.sendChaffReq)
        self.total_len = 0
        self.start_time = time.clock()

        self.chaff_recv = 0
        self.chaff_bytes = 0
        self.cov_recv = 0
        self.cov_bytes = 0

        # Note that this is the host name if available,
        # otherwise the ip address
        #
        self.host_name = addr[0]

        self.state = const.STATE_0_UNI

        self.src_p = None
        self.handshake_ID = None
        self.tunnel_tag = None
        self.tunnel_type = const.HTTP_UNI_TUNNEL

        # We don't use the host or session_key parameters because the
        # only thing we use this encoder for is its digest method, which
        # does not depend on anything except the text.
        #
        self.encoder = HttpMoleCryptoEncoder('fakehost', 'fakekey')

        self.sent_count = 0
예제 #5
0
    def dataReceived(self, data):

        if self.isFirst == True:
            self.mole = self.factory.ct_dp.getMole()
            self.session_key = self.mole.get_session_key()
            self.rc4 = RC4.RC4(self.session_key[const.SENTINEL_HEX_LEN:])
            self.isFirst = False

        self.data_buf += data

        while len(self.data_buf) > 0:
            (status, self.data_buf) = self.tunnelIsReady(self.data_buf)
            if not status:
                break
예제 #6
0
    def test_vectors(self):
        """
        Test with test vectors from Wikipedia: http://en.wikipedia.org/wiki/Rc4
        """
        vectors = (('Key', 'Plaintext', 'BBF316E8D940AF0AD3'),
                   ('Wiki', 'pedia', '1021BF0420'),
                   ('Secret', 'Attack at dawn', '45A01F645FC35B383552544B9BF5'))
        
        rc4 = RC4.RC4()
        for key, plaintext, ciphertext in vectors:
            rc4.set_key(key)
            self.assertEqual(hexlify(rc4.update(plaintext)).upper(), ciphertext)

        self.assertEqual(rc4.final(), '')
def xor_encrypt(data, key):
    chunk_size = 16384
    pos = 0
    l = len(data)
    is_str = isinstance(data, str)
    res = ''
    while pos < l:
        rc4 = RC4.RC4(key)
        chunk = data[pos:pos + chunk_size]
        if is_str:
            res += rc4.update(chunk)
        else:
            data.update(rc4.update(chunk), pos)
        pos += chunk_size
        del rc4

    return res
def M2Crypto_RC4():
    global encryptionavg
    global decryptionavg
    from M2Crypto import RC4
    startTime = time.time()
    rc4 = RC4.RC4()
    rc4.set_key(key)
    c = rc4.update(plainContent)
    totalTime = time.time() - startTime
    encryptionavg += totalTime
    #print totalTime
    print('RC4 Encryption: Total time: %.5f seconds' % totalTime)
    startTime = time.time()
    rc4.update(c)
    totalTime = time.time() - startTime
    decryptionavg += totalTime
    #print totalTime
    print('RC4 Decryption: Total time: %.5f seconds' % totalTime)
예제 #9
0
    def __init__(self, host, session_key):

        if type(host) != str:
            raise TypeError('host must be a str (not %s)' % str(type(host)))

        if not host:
            raise ValueError('host must not be the empty string')

        self.host = host
        self.session_key = session_key
        self.offset = 0
        self.seqno = 0

        # TODO: check that the first 3000+ characters are thrown out.
        # The first part of an RC4 ciphertext are known to be weak.
        #
        self.rc4 = RC4.RC4(self.session_key)

        # Used to check that each instance is either used for encryption
        # or decryption, but never a mix
        #
        self.prev_crypto_op = None
예제 #10
0
        o = opt[1]
        if o == '-':
            outf = sys.stdout
        else:
            outf = open(o, 'wb')
if cmd < 0:
    raise argerr, "either -d or -e"
if cmd > 1:
    raise argerr, "either -d or -e, not both"

if cmd == 0:
    iv = inf.read(10)
    pp = getpass.getpass('Enter decryption passphrase: ')
else:
    iv = Rand.rand_bytes(10)
    outf.write(iv)
    pp = getpass.getpass('Enter encryption passphrase: ')
    pp2 = getpass.getpass('Enter passphrase again: ')
    if pp != pp2:
        raise SystemExit, 'passphrase mismatch, I\'m outta here...'

ci = RC4.RC4(pp + iv)
del pp, iv

while 1:
    buf = inf.read()
    if not buf:
        break
    outf.write(ci.update(buf))
outf.write(ci.final())
예제 #11
0
 def arcfour_encrypt(key, data):
     c = RC4.RC4(key)
     return c.update(data)
예제 #12
0
 def test_bad(self):
     if fips_mode:
         return
     rc4 = RC4.RC4(b'foo')
     self.assertNotEqual(hexlify(rc4.update(b'bar')).upper(), b'45678')
예제 #13
0
 def reset_session_key(self):
     self.rc4 = RC4.RC4(self.session_key)
     self.seqno = 0
예제 #14
0
 def test_bad(self):
     rc4 = RC4.RC4('foo')
     self.assertNotEqual(hexlify(rc4.update('bar')).upper(), '45678')
예제 #15
0
    def __server_hello(self, data, metadata):
        # SERVER HELLO records have an inner version.
        version = struct.unpack('>H', data[:self.version_size])[0]
        metadata['handshake_version'] = version
        data = data[self.version_size:]
        (self.s_rnd, self.s_sid, sid_len) = self.__parse_rnd_and_sid(data)

        metadata['server_random'] = self.s_rnd
        metadata['server_sid'] = self.s_sid

        # Move past the random (32), sid_len (1) and SID (sid_len).
        data = data[32 + 1 + sid_len:]

        self.cipher_suite = struct.unpack('>H',
                                          data[:self.cipher_suite_size])[0]
        metadata['cipher_suite'] = self.cipher_suite
        data = data[self.cipher_suite_size:]

        if (self.cipher_suite not in self.decryptable_cipher_suites
                and self.keypair != None):
            raise sslimUnknownCipher("Can't decrypt cipher suite",
                                     self.cipher_suite)

        # Get details of the chosen cipher suite. Each cipher suite is
        # available as a method of the sslim_cipher_suites class. The method
        # names are all the 2 bytes for the cipher suite value preceeded by an
        # underscore (_0035, _002F, etc).
        #
        # See sslim_ciphers for details.
        cs = "_%04X" % self.cipher_suite
        if not hasattr(sslim_cipher_suites, cs):
            message = """Unknown cipher suite. This is likely just missing an entry in
sslim_ciphers.py, please drop me a mail ([email protected]) with
this message. Cipher suite"""
            raise sslimUnknownCipher(message, self.cipher_suite)

        method = getattr(sslim_cipher_suites, cs)
        cs = method()
        self.cipher_suite = cs.details
        metadata['cipher_suite_details'] = self.cipher_suite

        self.compression = struct.unpack('>B', data[:self.compression_size])[0]
        metadata['compression'] = self.compression
        data = data[self.compression_size:]
        if (self.compression not in self.compressions
                and self.keypair != None):
            raise sslimUnknownCompression("Unknown compression",
                                          self.compression)

        # The only compression allowed in the RFCs is deflate. If that
        # ever changes we need to pay attention to the value here.
        if (self.compression != self.NULL_COMPRESSION
                and self.keypair != None):
            self.c_zobj = zlib.decompressobj()
            self.s_zobj = zlib.decompressobj()

        if self.ver != self.SSLv3_0:
            # Go looking for extensions.
            extl = struct.unpack('>H', data[:self.extension_size])[0]
            self.__extensions(
                data[self.extension_size:self.extension_size + extl],
                'server_extensions')
            # See if there is a client ticket extension.
            metadata['extensions'] = self.extensions['server_extensions']
            data = data[self.extension_size:self.extension_size + extl]
            # Specifically for Session Tickets (RFC 5077).
            self.server_ticket = self.__find_extension(
                self.EXT_SESSIONTICKET_TYPE, 'server_extensions')

        # Only care about resuming if we have a keypair.
        if self.keypair != None:
            if ((self.s_sid != 0 and self.c_sid == self.s_sid)
                    or self.client_ticket):
                # Session resuming.
                # First check the sid, then check the ticket.
                self.ms = self.check_sid(self.s_sid)
                if not self.ms:
                    self.ms = self.check_sid(self.client_ticket)
                    if not self.ms:
                        raise sslimBadValue("Bad resume value")

                km = self.__key_material(self.cipher_suite['km_len'],
                                         self.s_rnd + self.c_rnd, self.ms)
                keys = self.__split_key_material(km)
                self.cipher_suite['keys'] = keys
                if self.cipher_suite['cipher'] == 'stream':
                    self.c_cryptobj = RC4.RC4(keys['client_enc_key'])
                    self.s_cryptobj = RC4.RC4(keys['server_enc_key'])
                elif self.cipher_suite['cipher'] == 'block':
                    self.c_cryptobj = EVP.Cipher(self.cipher_suite['algo'],
                                                 keys['client_enc_key'],
                                                 keys['client_iv'],
                                                 0,
                                                 padding=0)
                    self.s_cryptobj = EVP.Cipher(self.cipher_suite['algo'],
                                                 keys['server_enc_key'],
                                                 keys['server_iv'],
                                                 0,
                                                 padding=0)

        self.__callback('server_hello', metadata)
예제 #16
0
 def encode(password):
     rc4 = RC4.RC4()
     rc4.set_key("#u82fyi8S5\017pPemw")
     return hexlify(rc4.update(password))
예제 #17
0
    def __handshake(self, data):
        # The first byte is the hand-shake type.
        hst = struct.unpack('>B', data[:self.hs_type_size])[0]
        data = data[self.hs_type_size:]

        if hst not in self.HANDSHAKE_TYPES:
            raise sslimBadValue("Bad hst value", hst)

        # Client Hello (0x01) and Server Hello (0x02) have the 32 bytes
        # of random data in the same spot.
        if hst == self.CLIENT_HELLO:
            data = data[self.hs_hello_size:]
            (self.c_rnd, self.c_sid, sid_len) = self.__parse_rnd_and_sid(data)

            if self.ver != self.SSLv3_0:
                # Go looking for extensions.
                # Specifically for Session Tickets (RFC 5077).
                # Move past the random (32), sid_len (1) and SID (sid_len).
                data = data[32 + 1 + sid_len:]

                # We don't care what cipher suites or what compression method
                # the client supports.
                csl = struct.unpack('>H', data[:self.cipher_suite_size])[0]
                data = data[2 + csl:]
                cmpl = struct.unpack('>B', data[:self.compression_size])[0]
                data = data[1 + cmpl:]
                self.client_ticket = self.__find_extension(
                    data, self.EXT_SESSIONTICKET_TYPE)
        elif hst == self.SERVER_HELLO:
            data = data[self.hs_hello_size:]
            (self.s_rnd, self.s_sid, sid_len) = self.__parse_rnd_and_sid(data)

            # Move past the random (32), sid_len (1) and SID (sid_len).
            data = data[32 + 1 + sid_len:]
            self.cipher_suite = struct.unpack('>H',
                                              data[:self.cipher_suite_size])[0]
            data = data[self.cipher_suite_size:]
            if self.cipher_suite not in self.cipher_suites:
                raise sslimUnknownCipher("Unknown cipher suite",
                                         self.cipher_suite)
            self.cipher_suite = self.cipher_suites[self.cipher_suite]

            self.compression = struct.unpack('>B',
                                             data[:self.compression_size])[0]
            data = data[self.compression_size:]
            if self.compression not in self.compressions:
                raise sslimUnknownCompression("Unknown compression",
                                              self.compression)

            # The only compression allowed in the RFCs is deflate. If that
            # ever changes we need to pay attention to the value here.
            if self.compression != self.NULL_COMPRESSION:
                self.c_zobj = zlib.decompressobj()
                self.s_zobj = zlib.decompressobj()

            if self.ver != self.SSLv3_0:
                # Go looking for extensions.
                # Specifically for Session Tickets (RFC 5077).
                self.server_ticket = self.__find_extension(
                    data, self.EXT_SESSIONTICKET_TYPE)

            if (self.s_sid != 0
                    and self.c_sid == self.s_sid) or (self.client_ticket):
                # Session resuming.
                # First check the sid, then check the ticket.
                self.ms = self.check_sid(self.s_sid)
                if not self.ms:
                    self.ms = self.check_sid(self.client_ticket)
                    if not self.ms:
                        raise sslimBadValue("Bad resume value")

                km = self.__key_material(self.cipher_suite['km_len'],
                                         self.s_rnd + self.c_rnd, self.ms)
                keys = self.__split_key_material(km)
                self.cipher_suite['keys'] = keys
                if self.cipher_suite['cipher'] == 'stream':
                    self.c_cryptobj = RC4.RC4(keys['client_enc_key'])
                    self.s_cryptobj = RC4.RC4(keys['server_enc_key'])
                elif self.cipher_suite['cipher'] == 'block':
                    self.c_cryptobj = EVP.Cipher(self.cipher_suite['algo'],
                                                 keys['client_enc_key'],
                                                 keys['client_iv'],
                                                 0,
                                                 padding=0)
                    self.s_cryptobj = EVP.Cipher(self.cipher_suite['algo'],
                                                 keys['server_enc_key'],
                                                 keys['server_iv'],
                                                 0,
                                                 padding=0)

        elif hst == self.EXT_SESSIONTICKET:
            # The first three bytes are the length, which we can skip
            # because we already have the entire handshake message.
            # We can also skip the next 4 bytes which are the lifetime hint.
            data = data[7:]
            # The next two bytes are the length of the session ticket.
            ticket_len = struct.unpack('>H', data[:2])[0]
            data = data[2:]
            if ticket_len != len(data):
                raise sslimBadValue("Bad ticket length", ticket_len)
            ticket = struct.unpack('%ss' % ticket_len, data[:ticket_len])[0]
            self.store_ms(ticket, self.ms)
        elif hst == self.CLIENT_KEY_EXCHANGE:
            if self.check_sid(self.s_sid):
                # XXX: The fact that the server session ID is in
                # the dictionary already is a really bad thing.
                # There should be no client key exchange message
                # if the client and server agree to resume.
                raise sslimBadValue("SID found with client key exchange")

            data = data[self.hs_key_exch_size:]
            # Client Hello (0x01) and Server Hello (0x02) have a version field
            # here while Client Key Exchange (0x10) puts the length here.  We
            # are skipping the length. Older SSL implementations may not put
            # the length here (see section 7.4.7.1 of RFC5246) though. We
            # should check these two bytes and compare them with the modulus of
            # the private key.

            # XXX: The size of this is dependent upon the cipher suite chosen!
            # Section 7.4.7.1 of RFC5246 details what these bytes mean for
            # RSA authentication!
            if self.ver == self.SSLv3_0:
                if self.cipher_suite['key_exch'] != 'RSA':
                    raise sslimUnknownCipher("SSLv3 not RSA key exchange")
                pms = data
            else:
                # The first two bytes are the length of the key.
                pms_len = int(
                    struct.unpack('>H', data[:self.hs_pms_len_size])[0])
                data = data[self.hs_pms_len_size:]
                pms = struct.unpack('%ss' % pms_len, data[:pms_len])[0]

            try:
                cpms = self.keypair.private_decrypt(pms, RSA.sslv23_padding)
            except:
                raise sslimCryptoError()

            seed = self.c_rnd + self.s_rnd
            self.ms = self.__PRF(cpms, "master secret", seed, 48)[:48]

            # Store the master secret in the sids dictionary
            self.store_ms(self.s_sid, self.ms)

            # From the master secret you generate the key material
            seed = self.s_rnd + self.c_rnd
            km = self.__key_material(self.cipher_suite['km_len'],
                                     self.s_rnd + self.c_rnd, self.ms)
            keys = self.__split_key_material(km)
            self.cipher_suite['keys'] = keys
            if self.cipher_suite['cipher'] == 'stream':
                self.c_cryptobj = RC4.RC4(keys['client_enc_key'])
                self.s_cryptobj = RC4.RC4(keys['server_enc_key'])
            elif self.cipher_suite['cipher'] == 'block':
                self.c_cryptobj = EVP.Cipher(self.cipher_suite['algo'],
                                             keys['client_enc_key'],
                                             keys['client_iv'],
                                             0,
                                             padding=0)
                self.s_cryptobj = EVP.Cipher(self.cipher_suite['algo'],
                                             keys['server_enc_key'],
                                             keys['server_iv'],
                                             0,
                                             padding=0)