Пример #1
0
def main(sVaultFolder, sMasterkey, sSystem, sSecurity, sSoftware = None, boolOutput = True):
    ## Step 1: prepare DPAPI data (System MK pool)
    mkp = masterkey.MasterKeyPool()
    mkp.loadDirectory(sMasterkey)
    
    reg = registry.Regedit()
    secrets = reg.get_lsa_secrets(sSecurity, sSystem)
    dpapi_system = secrets.get('DPAPI_SYSTEM')['CurrVal']
    mkp.addSystemCredential(dpapi_system)
    mkp.try_credential_hash(None, None)
    
    ## Step 2: Parse and DPAPI decrypt Policy.vpol
    vpol_filename = os.path.join(sVaultFolder, 'Policy.vpol')
    with open(vpol_filename, 'rb') as f: vpol_blob = parsePolicy(f.read())
    vpol_cleartext = decrypt_blob(mkp, vpol_blob)
    if not vpol_cleartext:
        exit('[-] Unable to decrypt Policy.vpol')
    bKeyAES128, bKeyAES256 = parsePolicyEntries(vpol_cleartext)
    
    ## Step 3: Parse and AES decrypt VCRD
    sUsername = ''
    arrResult = []
    for xfile in os.listdir(sVaultFolder):
        if xfile.lower().endswith('.vcrd'):
            filepath = os.path.join(sVaultFolder, xfile)
            if boolOutput: print('---- Working on ' + xfile + ' ----')
            with open(filepath, 'rb') as vcrdfile:
                bIV, bData, sSchemaType = parseVCRD(vcrdfile.read()) ## parseVCRD verifies the vault type (GUIDs at the top of this file)
                if bKeyAES256 and bData:
                    cipher = AES.new(bKeyAES256, AES.MODE_CBC, iv = bIV)
                    bDecrypted = cipher.decrypt(bData)
                    dicContainers = parseDecryptedAttribute(bDecrypted) ## dicContainers[ContainerID] = bData
                    if dicContainers[1].decode(errors='ignore').startswith('N\x00G\x00C\x00'): ## Should be "NGC Local Accoount Logon Vault Resource" in utf-16le
                        if boolOutput:
                            print('[+] Schema Type : ' + sSchemaType)
                            print('[+] User SID    : ' + parseSID(dicContainers[2]))
                        if sSoftware: 
                            sUsername = getUsername(sSoftware, parseSID(dicContainers[2]))
                            if boolOutput: print('[+] Username    : '******'[+] Schema Type        : ' + sSchemaType)
                            print('[+] HEX decrypted data : ' + dicContainers[3].hex())
                            try: print('[+] Decoded value      : ' + dicContainers[3].decode('utf-16le',errors='ignore'))
                            except: pass
            if boolOutput: print('#'*50)
    if arrResult == []: print('[-] No vaults found')
    return (sUsername, arrResult)
Пример #2
0
    parser.add_option('--usermasterkey', metavar='DIRECTORY', dest='usermasterkeydir')
    parser.add_option('--sid', metavar='SID', dest='sid', help=r'Carved from the User Masterkey folder, if possible')
    parser.add_option('--password', metavar='PASSWORD', dest='password', help='Optional: Will use empty password when not provided')
    parser.add_option('--pwdhash', metavar='HASH', dest='pwdhash')
    parser.add_option('--credhist', metavar='FILE', dest='credhist')

    (options, args) = parser.parse_args()

    check_parameters(options, args)

    reg = registry.Regedit()
    secrets = reg.get_lsa_secrets(options.security, options.system)
    dpapi_system = secrets.get('DPAPI_SYSTEM')['CurrVal']
    #print('[+] SYSTEM DPAPI key: {}'.format(dpapi_system.hex()))

    mkp1 = masterkey.MasterKeyPool()
    mkp1.loadDirectory(options.systemmasterkeydir)
    mkp1.addSystemCredential(dpapi_system)
    mkp1.try_credential_hash(None, None)

    mkp2 = masterkey.MasterKeyPool()
    mkp2.loadDirectory(options.usermasterkeydir)
    if options.credhist:
        mkp2.addCredhistFile(options.sid, options.credhist)
    if options.password:
        mkp2.try_credential(options.sid, options.password)
    if options.pwdhash:
        mkp2.try_credential_hash(options.sid, bytes.fromhex(options.pwdhash))

    for root, _, files in os.walk(options.wifi_dir):
        for file in files:
Пример #3
0
    parser.add_option('--sid', metavar='SID', dest='sid')
    parser.add_option('--credhist', metavar='FILE', dest='credhist')
    parser.add_option('--password', metavar='PASSWORD', dest='password')
    parser.add_option(
        '--pwdhash',
        metavar='HASH',
        dest='pwdhash',
        help='Example for empth hash: da39a3ee5e6b4b0d3255bfef95601890afd80709'
    )
    parser.add_option('--entropy_hex', metavar='HIVE', dest='entropy_hex')

    (options, args) = parser.parse_args()

    check_parameters(options, args)

    mkp = masterkey.MasterKeyPool()
    mkp.loadDirectory(options.masterkeydir)

    if options.sid:
        if options.credhist:
            mkp.addCredhistFile(options.sid, options.credhist)
        if options.password:
            mkp.try_credential(options.sid, options.password)
        elif options.pwdhash:
            mkp.try_credential_hash(options.sid,
                                    bytes.fromhex(options.pwdhash))
    else:
        reg = registry.Regedit()
        secrets = reg.get_lsa_secrets(options.security, options.system)
        dpapi_system = secrets.get('DPAPI_SYSTEM')['CurrVal']
Пример #4
0
    bKey = bDerivedKey = bContext = b''
    oFileData = base64.urlsafe_b64decode(args[0])
    iVersion = int(reverseByte(oFileData[:4]).hex(), 16)
    if not iVersion == 1: sys.exit('[-] Error: Key is encrypted using TPM. For now, please run mimikatz on the victim.')
    print('[+] Key in software, good to go')
    oBlob = blob.DPAPIBlob(oFileData[8:])
    print('[+] MK required: {}'.format(oBlob.mkguid))
    if not options.mkhex and not (options.system or options.security or options.masterkeydir):
        exit('[-] Please provide decryption details.')

    if not options.mkhex:
        reg = registry.Regedit()
        secrets = reg.get_lsa_secrets(options.security, options.system)
        dpapi_system = secrets.get('DPAPI_SYSTEM')['CurrVal']
        oMKP = masterkey.MasterKeyPool()
        oMKP.loadDirectory(options.masterkeydir)
        oMKP.addSystemCredential(dpapi_system)
        oMKP.try_credential_hash(None, None)
        oMKS = oMKP.getMasterKeys(oBlob.mkguid.encode())
        for oMK in oMKS:
            if oMK.decrypted:
                oBlob.decrypt(oMK.get_key())                
    else: 
        oBlob.decrypt(bytes.fromhex(options.mkhex))

    if oBlob.decrypted: bKey = oBlob.cleartext
    
    if bKey: 
        print('[+] Decryption succes!')
        print('    Clear Key:   {}'.format(bKey.hex()))
Пример #5
0
def main(sCryptoFolder, sMasterkey, sSystem, sSecurity, sPIN, sPINGUID, boolOutput = True, pemexport="", sid=None, password=None):
    ## if sPIN == '', do brute force
    if sSystem:
        reg = registry.Regedit()
        secrets = reg.get_lsa_secrets(sSecurity, sSystem)
        dpapi_system = secrets.get('DPAPI_SYSTEM')['CurrVal']
        
    mkp = masterkey.MasterKeyPool()
    if sMasterkey:
        mkp.loadDirectory(sMasterkey)
        mkp.addSystemCredential(dpapi_system)
        decrn=mkp.try_credential_hash(None, None)
        #print("Decrypted keys %d" % decrn)

    if sid and password:
            mkp.try_credential(options.sid, options.password)

    for root, _, files in os.walk(sCryptoFolder):
        for sFile in files:
            filepath = os.path.join(root, sFile)
            with open(filepath, 'rb') as f:
                file_data = f.read()
                sInfo, arrFieldData = parseFile(file_data)
                if boolOutput:
                    print('-' * 10 + ' ' + sFile + ' ' + '-' * 10)
                    print('[+] KEY GUID             : ' + sInfo)
                ### Field 2 and 3 are DPAPI Blob
                parseField1(arrFieldData[0], boolOutput)
                ## Private Key Properties should work with static Entropy '6jnkd5J3ZdQDtrsu'
                blobPrivateKeyProperties = arrFieldData[1]
                pkpBlob = blob.DPAPIBlob(blobPrivateKeyProperties)
                mks = mkp.getMasterKeys(pkpBlob.mkguid.encode())
                for mk in mks:
                    if mk.decrypted:
                        pkpBlob.decrypt(mk.get_key(), entropy = b'6jnkd5J3ZdQDtrsu\x00')
                        if pkpBlob.decrypted:
                            if boolOutput: print('[+] Private Key Properties decrypted!')
                            arrPrivateKeyProperties = parsePrivateKeyProperties(pkpBlob.cleartext.hex(), boolOutput)
                
                ## Private Key, we can try, but the entropy is either unknown static or variable (some are 'xT5rZW5qVVbrvpuA')
                blobPrivateKey = arrFieldData[2]
                pkBlob = blob.DPAPIBlob(blobPrivateKey)
                mks = mkp.getMasterKeys(pkBlob.mkguid.encode())
                for mk in mks:
                    if mk.decrypted:
                        pkBlob.decrypt(mk.get_key(), entropy = b'xT5rZW5qVVbrvpuA\x00', strongPassword=None)
                        if pkBlob.decrypted and boolOutput:
                            print('[+] Private Key decrypted : ')
                            print('    ' + pkBlob.cleartext.hex())
                            if pemexport:
                                savePEM(pkBlob.cleartext.hex(), pem_path=pemexport, pemname=sInfo)
                        else:
                            if sPINGUID and sPINGUID in sInfo and arrPrivateKeyProperties:
                                for sProperty in arrPrivateKeyProperties:
                                    if sProperty['Name'].decode('UTF-16LE',errors='ignore') == 'NgcSoftwareKeyPbkdf2Salt': sSalt = sProperty['Value'].hex()
                                    elif sProperty['Name'].decode('UTF-16LE',errors='ignore') == 'NgcSoftwareKeyPbkdf2Round': iRounds = int(reverseByte(sProperty['Value']).hex(),16)
                                if sPIN and not sPIN == '':
                                    pkResult = decryptWithPIN(mk, pkBlob, sSalt, iRounds, sPIN)
                                elif options.pinbrute:
                                    if boolOutput: print('[!] Trying PIN brute force 0000 through {}, this will take some time '.format(iMaxPIN))
                                    (pkResult, sPIN) = brutePIN(mk, pkBlob, sSalt, iRounds)
                                elif options.pinexport:
                                    exportHASH(mk, pkBlob, sSalt, iRounds, sPINGUID)
                                    pkResult = None
                                if pkResult and pkResult.decrypted:
                                    if boolOutput:
                                        print('[+] Private Key decrypted with PIN (' + sPIN + ') :')
                                        print('    ' + pkBlob.cleartext.hex())
                                    else: ## no bool output means: called by other script that is only interested in this cleartext data
                                        return pkBlob.cleartext
                                else:
                                    if sPIN and boolOutput: print('[-] Decryption with PIN tried but failed')
                            else:
                                if boolOutput: print('[-] Entropy unknown for ' + pkBlob.description.decode())
                            
            if boolOutput: print('')
Пример #6
0
    def main(self):
        file_list = []
        for f in (os.listdir(self.dir_location)):
            file_list.append(os.path.join(self.dir_location, f))
        if not ((os.path.join(self.dir_location, 'Local State') in file_list)
                and
                (os.path.join(self.dir_location, 'Login Data') in file_list)):
            print("No Local State and Login Data found in that directory")
            sys.exit(2)
        else:
            print(bcolors.OKGREEN + " * " + bcolors.ENDC +
                  "Local State and Login Data files found")
        #call function to read Local State file and get an impacket Blob dpapi file
        #open dpapi blob

        key = self.local_state_file(self.dir_location)
        bl = blob.DPAPIBlob(key)

        file_list = []
        if (self.masterkey_location):
            mkp = masterkey.MasterKeyPool()
            mkp.loadDirectory(self.masterkey_location)
            mks = mkp.getMasterKeys(bl.mkguid.encode())
            if len(mks) == 0:
                sys.exit('[-] Unable to find MK for blob %s' % bl.mkguid)
            else:
                print(bcolors.OKGREEN + " * " + bcolors.ENDC +
                      "MasterKey file found")
        else:
            print("Needed masterkey(-m) directory with the location of " +
                  bl.mkguid)
            sys.exit(2)
        if not (self.sid_value):
            try:
                self.sid_value = (re.search('((S-1).*?)/',
                                            self.masterkey_location)[1])
                print(bcolors.OKGREEN + " * " + bcolors.ENDC + "SID " +
                      self.sid_value)
            except:
                print("Need to specify SID")
                sys.exit(2)
        #Check if password or nopass
        if self.nopass:
            self.user_password = ''
        elif not self.user_password:
            print("Need user password (-p)")
            sys.exit(2)

        # go for the decrypt
        #Add chredhist
        #mkp.addCredhistFile(sid, os.path.join('Protect','CREDHIST'))
        mkp.try_credential(self.sid_value, self.user_password)

        for mk in mks:
            mk.decryptWithPassword(self.sid_value, self.user_password)
            if mk.decrypted:
                print(bcolors.OKGREEN + " * " + bcolors.ENDC + "Mk decrypted")
                bl.decrypt(mk.get_key(), entropy=self.entropy)
                if bl.decrypted:
                    #if called alone
                    if __name__ == "__main__":
                        decrypted = bl.cleartext.hex()
                        print(decrypted)
                        print()
                        print("# # Success! (saved to decrypted.bin) # #")
                        print()
                        #print(decrypted.decode('utf-16-le'))
                        f = open('decrypted.bin', 'wb')
                        f.write(bl.cleartext)
                        f.close()
                    else:
                        # if called as module import
                        self.enc_key = bl.cleartext
            else:
                # Just print the data
                print(bcolors.FAIL + " * * * * * * * * * *  " + bcolors.ENDC)
                print(bcolors.FAIL + " * " + bcolors.ENDC +
                      "Error decrypting, Wrong Password?")
                print(bcolors.FAIL + " * * * * * * * * * *  " + bcolors.ENDC)
                print(bl)
Пример #7
0
                        help="DPAPI_SYSTEM string. 01000000...")
    parser.add_argument("--pkey",
                        required=False,
                        help="Private domain KEY",
                        dest="pkey")

    parser.add_argument("--debug",
                        required=False,
                        action="store_true",
                        dest="debug")
    # help="lines with base64-encoded password blobs")

    options = parser.parse_args()

    if options.masterkeydir:
        mkp = masterkey.MasterKeyPool()
        mkp.loadDirectory(options.masterkeydir)
    sysdecr = 0
    if options.sysmasterkeydir and options.sysfile and options.secfile:
        systemmkp = masterkey.MasterKeyPool()
        systemmkp.loadDirectory(options.sysmasterkeydir)
        reg = registry.Regedit()
        secrets = reg.get_lsa_secrets(options.secfile, options.sysfile)
        dpapi_system = secrets.get('DPAPI_SYSTEM')['CurrVal']
        systemmkp.addSystemCredential(dpapi_system)
        sysdecr = systemmkp.try_credential_hash(None, None)

    if options.pkey:
        decrn = mkp.try_domain(options.pkey)
        if decrn > 0:
            print("Decrypted: " + str(decrn))