示例#1
0
    def extract_secret_key(self, key_data, global_salt, master_password,
                           entry_salt):

        if unhexlify('f8000000000000000000000000000001') not in key_data:
            return None

        priv_key_entry = key_data[unhexlify(
            'f8000000000000000000000000000001')]
        salt_len = char_to_int(priv_key_entry[1])
        name_len = char_to_int(priv_key_entry[2])
        priv_key_entry_asn1 = decoder.decode(priv_key_entry[3 + salt_len +
                                                            name_len:])
        data = priv_key_entry[3 + salt_len + name_len:]
        # self.print_asn1(data, len(data), 0)

        # See https://github.com/philsmd/pswRecovery4Moz/blob/master/pswRecovery4Moz.txt
        entry_salt = priv_key_entry_asn1[0][0][1][0].asOctets()
        priv_key_data = priv_key_entry_asn1[0][1].asOctets()
        priv_key = self.decrypt_3des(global_salt, master_password, entry_salt,
                                     priv_key_data)
        # self.print_asn1(priv_key, len(priv_key), 0)
        priv_key_asn1 = decoder.decode(priv_key)
        pr_key = priv_key_asn1[0][2].asOctets()
        # self.print_asn1(pr_key, len(pr_key), 0)
        pr_key_asn1 = decoder.decode(pr_key)
        # id = pr_key_asn1[0][1]
        key = long_to_bytes(pr_key_asn1[0][3])
        return key
示例#2
0
def pbkdf2(passphrase, salt, keylen, iterations, digest='sha1'):
    """
    Implementation of PBKDF2 that allows specifying digest algorithm.
    Returns the corresponding expanded key which is keylen long.
    """
    buff = b""
    i = 1
    while len(buff) < keylen:
        U = salt + struct.pack("!L", i)
        i += 1
        derived = hmac.new(passphrase,
                           U,
                           digestmod=lambda: hashlib.new(digest)).digest()
        for r in xrange(iterations - 1):
            actual = hmac.new(passphrase,
                              derived,
                              digestmod=lambda: hashlib.new(digest)).digest()
            tmp = b''
            for x, y in zip(derived, actual):
                if sys.version_info > (3, 0):
                    tmp += struct.pack(">B", x ^ y)
                else:
                    tmp += chr(char_to_int(x) ^ char_to_int(y))
            derived = tmp
        buff += derived
    return buff[:int(keylen)]
示例#3
0
    def print_asn1(self, d, l, rl):
        """
        Used for debug
        """
        type_ = char_to_int(d[0])
        length = char_to_int(d[1])
        if length & 0x80 > 0:  # http://luca.ntop.org/Teaching/Appunti/asn1.html,
            # nByteLength = length & 0x7f
            length = char_to_int(d[2])
            # Long form. Two to 127 octets. Bit 8 of first octet has value "1" and
            # bits 7-1 give the number of additional length octets.
            skip = 1
        else:
            skip = 0

        if type_ == 0x30:
            seq_len = length
            read_len = 0
            while seq_len > 0:
                len2 = self.print_asn1(d[2 + skip + read_len:], seq_len,
                                       rl + 1)
                seq_len = seq_len - len2
                read_len = read_len + len2
            return length + 2
        elif type_ in (0x6, 0x5, 0x4, 0x2):  # OID, OCTETSTRING, NULL, INTEGER
            return length + 2
        elif length == l - 2:
            self.print_asn1(d[2:], length, rl + 1)
            return length
示例#4
0
    def encrypt_bytes(self, data):
        assert type(data) == str, 'data must be byte string'
        assert self._lastChunk64, 'previous chunk not multiple of 64 bytes'
        lendata = len(data)
        munged = array('c', '\x00' * lendata)
        for i in xrange(0, lendata, 64):
            h = salsa20_wordtobyte(self.ctx, self.rounds, check_rounds=False)
            self.set_counter((self.get_counter() + 1) % 2**64)
            # Stopping at 2^70 bytes per nonce is user's responsibility.
            for j in xrange(min(64, lendata - i)):
                munged[i +
                       j] = chr(char_to_int(data[i + j]) ^ char_to_int(h[j]))

        self._lastChunk64 = not lendata % 64
        return munged.tostring()
示例#5
0
def CryptSessionKeyXP(masterkey,
                      nonce,
                      hashAlgo,
                      entropy=None,
                      strongPassword=None,
                      verifBlob=None):
    """
    Computes the decryption key for XP DPAPI blob, given the masterkey and optional information.

    This implementation relies on a faulty implementation from Microsoft that does not respect the HMAC RFC.
    Instead of updating the inner pad, we update the outer pad...
    This algorithm is also used when checking the HMAC for integrity after decryption

    :param masterkey: decrypted masterkey (should be 64 bytes long)
    :param nonce: this is the nonce contained in the blob or the HMAC in the blob (integrity check)
    :param entropy: this is the optional entropy from CryptProtectData() API
    :param strongPassword: optional password used for decryption or the blob itself
    :param verifBlob: optional encrypted blob used for integrity check
    :returns: decryption key
    :rtype : str
    """
    if len(masterkey) > 20:
        masterkey = hashlib.sha1(masterkey).digest()

    masterkey += b"\x00" * int(hashAlgo.blockSize)
    ipad = b"".join(
        chr_or_byte(char_to_int(masterkey[i]) ^ 0x36)
        for i in range(int(hashAlgo.blockSize)))
    opad = b"".join(
        chr_or_byte(char_to_int(masterkey[i]) ^ 0x5c)
        for i in range(int(hashAlgo.blockSize)))
    digest = hashlib.new(hashAlgo.name)
    digest.update(ipad)
    digest.update(nonce)
    tmp = digest.digest()
    digest = hashlib.new(hashAlgo.name)
    digest.update(opad)
    digest.update(tmp)
    if entropy is not None:
        digest.update(entropy)
    if strongPassword is not None:
        strongPassword = hashlib.sha1(
            strongPassword.rstrip("\x00").encode("UTF-16LE")).digest()
        digest.update(strongPassword)
    elif verifBlob is not None:
        digest.update(verifBlob)
    return digest.digest()
示例#6
0
文件: psi.py 项目: viencokhi/NeoRAT
    def decode_password(self, password, jid):
        result = ''
        jid = cycle(jid)
        for n1 in range(0, len(password), 4):
            x = int(password[n1:n1 + 4], 16)
            result += chr(x ^ char_to_int(next(jid)))

        return result
示例#7
0
文件: rc4.py 项目: viencokhi/NeoRAT
    def text_to_bytes(self, text):
        byte_list = []

        # on Windows, default coding for Chinese is GBK
        # s = s.decode('gbk').encode('utf-8')
        for byte in text:
            byte_list.append(char_to_int(byte))

        return byte_list
示例#8
0
 def print_hex(self, src, length=8):
     N = 0
     result = b''
     while src:
         s, src = src[:length], src[length:]
         hexa = b' '.join([b"%02X" % char_to_int(x) for x in s])
         s = s.translate(self.FILTER)
         result += b"%04X   %-*s   %s\n" % (N, length * 3, hexa, s)
         N += length
     return result
示例#9
0
def CryptDeriveKey(h, cipherAlgo, hashAlgo):
    """
    Internal use. Mimics the corresponding native Microsoft function
    """
    if len(h) > hashAlgo.blockSize:
        h = hashlib.new(hashAlgo.name, h).digest()
    if len(h) >= cipherAlgo.keyLength:
        return h
    h += b"\x00" * int(hashAlgo.blockSize)
    ipad = b"".join(
        chr_or_byte(char_to_int(h[i]) ^ 0x36)
        for i in range(int(hashAlgo.blockSize)))
    opad = b"".join(
        chr_or_byte(char_to_int(h[i]) ^ 0x5c)
        for i in range(int(hashAlgo.blockSize)))
    k = hashlib.new(hashAlgo.name, ipad).digest() + hashlib.new(
        hashAlgo.name, opad).digest()
    k = k[:cipherAlgo.keyLength]
    k = cipherAlgo.do_fixup_key(k)
    return k
示例#10
0
    def decrypt(self, masterkey, entropy=None, strongPassword=None):
        """Try to decrypt the blob. Returns True/False
        :rtype : bool
        :param masterkey: decrypted masterkey value
        :param entropy: optional entropy for decrypting the blob
        :param strongPassword: optional password for decrypting the blob
        """
        for algo in [crypto.CryptSessionKeyXP, crypto.CryptSessionKeyWin7]:
            try:
                sessionkey = algo(masterkey,
                                  self.salt,
                                  self.hashAlgo,
                                  entropy=entropy,
                                  strongPassword=strongPassword)
                key = crypto.CryptDeriveKey(sessionkey, self.cipherAlgo,
                                            self.hashAlgo)

                if "AES" in self.cipherAlgo.name:
                    cipher = AESModeOfOperationCBC(
                        key[:int(self.cipherAlgo.keyLength)],
                        iv="\x00" * int(self.cipherAlgo.ivLength))
                    self.cleartext = b"".join([
                        cipher.decrypt(self.cipherText[i:i + AES_BLOCK_SIZE])
                        for i in range(0, len(self.cipherText), AES_BLOCK_SIZE)
                    ])
                else:
                    cipher = self.cipherAlgo.module(
                        key, CBC, "\x00" * self.cipherAlgo.ivLength)
                    self.cleartext = cipher.decrypt(self.cipherText)

                padding = char_to_int(self.cleartext[-1])
                if padding <= self.cipherAlgo.blockSize:
                    self.cleartext = self.cleartext[:-padding]

                # check against provided HMAC
                self.signComputed = algo(masterkey,
                                         self.hmac,
                                         self.hashAlgo,
                                         entropy=entropy,
                                         verifBlob=self.blob)
                self.decrypted = self.signComputed == self.sign

                if self.decrypted:
                    return True
            except Exception:
                print_debug('DEBUG', traceback.format_exc())

        self.decrypted = False
        return self.decrypted
示例#11
0
 def parse(self, data):
     self.id = data.eat("L")
     self.attr_unknown_1 = data.eat("L")
     self.attr_unknown_2 = data.eat("L")
     self.attr_unknown_3 = data.eat("L")
     # self.padding = data.eat("6s")
     if self.id >= 100:
         self.attr_unknown_4 = data.eat("L")
     self.size = data.eat("L")
     if self.size > 0:
         self.has_iv = char_to_int(
             data.eat("1s"))  # To change for Python 3 compatibility
         if self.has_iv == 1:
             self.iv_size = data.eat("L")
             self.iv = data.eat(str(self.iv_size) + "s")
             self.data = data.eat(
                 str(self.size - 1 - 4 - self.iv_size) + "s")
         else:
             self.data = data.eat(str(self.size - 1) + "s")
示例#12
0
    def is_master_password_correct(self,
                                   key_data,
                                   master_password='',
                                   new_version=True):
        try:
            if not new_version:
                # See http://www.drh-consultancy.demon.co.uk/key3.html
                pwd_check = key_data.get(b'password-check')
                if not pwd_check:
                    return '', '', ''
                entry_salt_len = char_to_int(pwd_check[1])
                entry_salt = pwd_check[3:3 + entry_salt_len]
                encrypted_passwd = pwd_check[-16:]
                global_salt = key_data[b'global-salt']

            else:
                global_salt = key_data[0]  # Item1
                item2 = key_data[1]
                # self.print_asn1(item2, len(item2), 0)
                # SEQUENCE {
                # 	SEQUENCE {
                # 		OBJECTIDENTIFIER 1.2.840.113549.1.12.5.1.3
                # 		SEQUENCE {
                # 			OCTETSTRING entry_salt_for_passwd_check
                # 			INTEGER 01
                # 		}
                # 	}
                # 	OCTETSTRING encrypted_password_check
                # }
                decoded_item2 = decoder.decode(item2)
                entry_salt = decoded_item2[0][0][1][0].asOctets()
                encrypted_passwd = decoded_item2[0][1].asOctets()

            cleartext_data = self.decrypt_3des(global_salt, master_password,
                                               entry_salt, encrypted_passwd)
            if cleartext_data != convert_to_byte('password-check\x02\x02'):
                return '', '', ''

            return global_salt, master_password, entry_salt
        except Exception:
            self.debug(traceback.format_exc())
            return '', '', ''
示例#13
0
def unpad(data):
    extra = char_to_int(data[-1])
    return data[:len(data) - extra]
示例#14
0
def str_to_key(s):
    key = []
    key.append(char_to_int(s[0]) >> 1)
    key.append(((char_to_int(s[0]) & 0x01) << 6) | (char_to_int(s[1]) >> 2))
    key.append(((char_to_int(s[1]) & 0x03) << 5) | (char_to_int(s[2]) >> 3))
    key.append(((char_to_int(s[2]) & 0x07) << 4) | (char_to_int(s[3]) >> 4))
    key.append(((char_to_int(s[3]) & 0x0F) << 3) | (char_to_int(s[4]) >> 5))
    key.append(((char_to_int(s[4]) & 0x1F) << 2) | (char_to_int(s[5]) >> 6))
    key.append(((char_to_int(s[5]) & 0x3F) << 1) | (char_to_int(s[6]) >> 7))
    key.append(char_to_int(s[6]) & 0x7F)

    for i in range(8):
        key[i] = (key[i] << 1)
        key[i] = odd_parity[key[i]]

    return b"".join(chr_or_byte(k) for k in key)
示例#15
0
def SystemFunction005(secret, key):
    """
    This function is used to decrypt LSA secrets.
    Reproduces the corresponding Windows internal function.
    Taken from creddump project https://code.google.com/p/creddump/
    """
    decrypted_data = ''
    j = 0
    algo = CryptoAlgo(0x6603)
    for i in range(0, len(secret), 8):
        enc_block = secret[i:i + 8]
        block_key = key[j:j + 7]
        des_key = []
        des_key.append(char_to_int(block_key[0]) >> 1)
        des_key.append(((char_to_int(block_key[0]) & 0x01) << 6)
                       | (char_to_int(block_key[1]) >> 2))
        des_key.append(((char_to_int(block_key[1]) & 0x03) << 5)
                       | (char_to_int(block_key[2]) >> 3))
        des_key.append(((char_to_int(block_key[2]) & 0x07) << 4)
                       | (char_to_int(block_key[3]) >> 4))
        des_key.append(((char_to_int(block_key[3]) & 0x0F) << 3)
                       | (char_to_int(block_key[4]) >> 5))
        des_key.append(((char_to_int(block_key[4]) & 0x1F) << 2)
                       | (char_to_int(block_key[5]) >> 6))
        des_key.append(((char_to_int(block_key[5]) & 0x3F) << 1)
                       | (char_to_int(block_key[6]) >> 7))
        des_key.append(char_to_int(block_key[6]) & 0x7F)
        des_key = algo.do_fixup_key("".join([chr(x << 1) for x in des_key]))

        decrypted_data += des(des_key, ECB).decrypt(enc_block)
        j += 7
        if len(key[j:j + 7]) < 7:
            j = len(key[j:j + 7])
    dec_data_len = struct.unpack("<L", decrypted_data[:4])[0]
    return decrypted_data[8:8 + dec_data_len]
示例#16
0
 def xorstring(self, s, k):
     """
     xors the two strings
     """
     return b''.join(
         chr_or_byte(char_to_int(x) ^ char_to_int(y)) for x, y in zip(s, k))