-
Notifications
You must be signed in to change notification settings - Fork 28
cloudap
The cloud authentication package (AP) supports logons with Azure, AD FS, and Microsoft accounts. It is also the security package (SP) for OAuth 2.0 authentication with Microsoft’s cloud services.
- Key Terms
-
Functions
- CallPluginGeneric
- DisableOptimizedLogon
- GenARSOPwd
- GetAccountInfo
- GetAuthenticatingProvider
- GetDpApiCredKeyDecryptStatus
- GetPublicCachedInfo
- GetPwdExpiryInfo
- GetTokenBlob
- GetUnlockKeyType
- IsCloudToOnPremTgtPresentInCache
- ProfileDeleted
- ProvisionNGCNode
- RefreshTokenBlob
- ReinitPlugin
- RenameAccount
- SetTestParas
- TransferCreds
- Plugins
- Key Structures
Some terms appear a lot when analyzing cloudap which are provided here:
-
Package: Structure of information about a cloudap plugin, which will be either AzureAD or MicrosoftAccount
-
TokenBlob: A PRT, also referred to as a "Cloud TGT"
The protocol messages that cloudap or its plugins support are not documented by Microsoft. Microsoft provides a small example of calling one plugin function with little context. The remainder of the available functions and their usage were reverse engineered and documented here. It is not known on which version of NT these functions were originally introduced or if new functions have been introduced since this writting.
Id | Message Type | CLI Support |
---|---|---|
|
|
✔️ |
|
|
✔️ |
|
|
✔️ |
|
|
Planned |
|
|
✔️ |
|
|
|
|
|
Planned |
|
|
✔️ |
|
|
✔️ |
|
|
✔️ |
|
|
✔️ |
|
|
✔️ |
|
|
✔️ |
|
|
✔️ |
|
|
Planned |
|
|
Planned |
|
|
✔️ |
|
|
✔️ |
✏️
|
Function CallPluginGeneric will be called if you use a plugin function.
|
Call a CloudAP plugin function. You may not call this function directly with the tool, but it will be implicitly called when running a cloudap plugin command.
Loads a user’s CacheData from their CloudAPCache folder, updates the "cache node flags" to disable optimized logons, then saves the CacheData back to the user’s folder. Any user logon session may be specified. If no logon session is specified then optimized logons will be disabled for the logon session.
cloudap DisableOptimizedLogon [--luid {session id}]
Generate a Winlogon Automatic Restart Sign-On (ASRO) password and store it as a pair of LSA secrets. The LSA secrets will have the following names:
-
M$CLOUDAP_TBAL{4416F0BD-3A59-4590-9579-DA6E08AF19B3}_HASH
-
M$CLOUDAP_TBAL{8283D8D4-55B6-466F-B7D7-17A1352D9CAB}_HASH
The value of HASH should be the sha256 hash the plugin GUID string for your logon session combined with your user’s identity name.
The first secret will be the output of ext-ms-win-cloudap-tbal-l1-1-0!TbalSealBuffer
.
The second secret will be the value you provide which must be at least 4 bytes long.
cloudap GenARSOPwd --luid {session id} --arso-data {data}
The _LOGON_SESSION
structure has a GUID entry to identify which cloudap plugin was used (e.g., AzureAD or MicrosoftAccount)
This function returns that GUID entry for a specified logon session.
cloudap GetAuthenticatingProvider --luid {session id}
Return if the DPAPI cred key for user logon session has been decrypted.
cloudap GetDpApiCredKeyDecryptStatus --luid {session id}
Retrieve PublicCacheData from disk, deserialize, and return it. Needs further auditing.
Get a string and time with information about when password will expire for a logon session. A client must have`SeTcbPrivilege` to specify another logon session. Otherwise, the specified session will be ignored and the current session will be used instead.
cloudap GetPwdExpiryInfo [--luid {session id}]
The _USER_CACHE_ENTRY
structure has a DPAPI protected entry named TokenBlob, also referred to as the CloudTGT.
This function unprotects and returns the TokenBlob entry for a specified logon session.
You may specify a specific logon session, otherwise the current logon session will be used.
LSA Whisperer’s implementation of GetTokenBlob
is believed to be correct, but only the following errors have been observed during testing:
-
0xc0000022
- Access is denied. -
0xc000005f
- A specified logon session does not exist. It may already have been terminated.
It is still unknown what setup and access is needed for the command to return successfully.
cloudap GetTokenBlob [--luid {session id}]
Returns the UnlockKeyType
entry of the the _USER_CACHE_ENTRY
structure for a logon session.
The value will between 1 and 6 inclusively.
Internally, GetUnlockKeyType
remaps value 5 to 2, value 6 to 5, and value 7 to 6.
The meaning of each of these values is currently unknown.
A client must have`SeTcbPrivilege` to specify another logon session. Otherwise, the specified session will be ignored and the current session will be used instead.
cloudap GetUnlockKeyType [--luid {session id}]
Inspects the TicketCache
inside the _USER_CACHE_ENTRY
structure for a logon session to see if it contains a "cloud to on-prem TGT."
A client must have`SeTcbPrivilege` to specify another logon session.
Otherwise, the specified session will be ignored and the current session will be used instead.
cloudap IsCloudToOnPremTgtPresentInCache [--luid {session id}]
Adds a provided SID as a subkey under HKLM\Software\Microsoft\IdentityStore\DeferredCacheCleanup
.
Provision an NGC node in the CloudAPCache for the current logon session. Needs further auditing.
cloudap ProvisionNGCNode
Refresh a logon session’s TokenBlob using the RefreshToken
cloudap function plugin.
Will update the account name in the Security Accounts Manager (SAM). Needs further auditing.
Sets an internal TestFlags value used by cloudap. The following is the value for each currently used TestFlags bit:
TestFlags |
Description |
1 |
Disable the internal |
2 |
Disable the use of the internal |
cloudap SetTestParas --flags {value}
Transfer data between two cloudap logon sessions. The specific data that is transferred and privileges that may be required are still being determined. Will generate a new logon session for dst if needed. The function does not take any flags.
cloudap TransferCreds --sluid {session id} --dluid {session id}
Cloudap currently only supports 2 plugins to facilitate user logons with Azure AD (AAD) and Microsoft Accounts (MSA). The AAD plugin also facilitates logins with AD FS. The internal names and IDs for interacting with these plugins may be found in the registry and are provided here for convenience.
Plugin Name | GUID | File |
---|---|---|
AadGlobalId (AAD) |
|
aadcloudap.dll |
Windows Live ID (MSA) |
|
MicrosoftAccountCloudAP.dll |
Cloudap allows each plugin to implement a number of functions for cloudap to call. The full list of functions, their call ID, and the plugins that support them are listed here.
Id | Message Type | Plugins |
---|---|---|
|
|
AAD, MSA |
|
|
AAD, MSA |
|
|
AAD, MSA |
|
Reserved |
|
|
|
MSA |
|
|
MSA |
|
|
AAD, MSA |
|
|
AAD |
|
|
AAD |
|
|
AAD, MSA |
|
|
AAD |
|
|
AAD, MSA |
|
|
AAD |
|
|
AAD |
|
|
MSA |
|
|
MSA |
|
|
MSA |
|
|
MSA |
|
|
AAD |
|
|
AAD, MSA |
|
|
AAD |
✏️
|
Functions 0x00-0x08 are available offline and functions 0x09-0x14 require online connectivity.
|
The Azure AD (AAD) plugin supports additional calls through the GenericCallPkg
plugin function.
The full list and their call IDs are listed here.
The version numbers are anecdotal and will not account for all NT builds for which a function may be present.
Id | Message Type | NT Build | CLI Support |
---|---|---|---|
|
|
|
Planned |
|
|
|
✔️ |
|
|
|
✔️ |
|
|
|
✔️ |
|
|
|
Planned |
|
|
|
✔️ |
|
|
|
✔️ |
|
|
|
✔️ |
|
|
|
✔️ |
|
|
|
✔️ |
|
|
|
✔️ |
|
|
|
❌ |
|
|
|
❌ |
|
Reserved |
❌ |
|
|
|
|
✔️ |
✏️
|
Reserved fields are likely for functions that are only present in debug builds. |
Will perform the following actions:
-
Attempt to acquire the private key for the enterprise Device Registration Service (DRS) certificate in the current user’s certificate store
-
Attempt to acquire the NGC symmetric PoP key transport key
-
Check if either action returned an error code matching a predefined list of error codes
-
Set the
RunRecovery
value in theHKLMSOFTWARE\Microsoft\IdentityStore\LoadParameters{B16898C6-A148-4967-9171-64D755DA8520}
to true if an error code does match the list -
Return the error codes for the first two actions
Create a signed JWT for the current device which may be specified in web requests using the x-ms-DeviceCredential
header.
The JWT is used to authenticate the client device and its contents are described here.
The host must be cloud domain joined for the call to succeed.
The CreateEnterpriseSSOCookie
command has not been fully tested, but should provide an
Enterprise PRT cookie for the current logon session to use for single sign on (SSO) with AD FS.
The host device must be authenticated with AD FS for the call to succeed.
Create a Server Nonce PDU as defined in the RDS AAD Auth Connection Sequence section of the MS-RDPBCGR documentation.
The call is also listed as a protocol example in the section "Generating a Server Nonce."
The caller must be System and the host must be cloud domain joined for the call to succeed.
If the call succeeds the returned nonce may be used when creating an Authentication Request PDU to use with the ValidateRdpAssertion
command.
Create a proof of possession (PoP) cookie for the current logon session to use for single sign on (SSO) with Azure AD.
The command requires a nonce value which may be acquired with the .nonce
command or with roadrecon
and it’s auth --prt-init
command.
The returned assertion (e.g., the cookie) may be used with several roadrecon
and roadtx
commands by specifying the assertion with the --prt-cookie
argument.
Issues a device token request to Azure AD and validates that a bearer token was successfully recieved. An empty json dictionary is returned on success and an error on failure. Although the API does not return the bearer token it may be viewed with the assistance of an HTTPS proxy such as mitmproxy.
Get information about any PRT authorities the current device may be registered with.
The current device may be registered with Azure AD (use --authority 1
), an AD FS instance (e.g., "Enterprise" [use --authority 2
]), or both.
cloudap GetPrtAuthority --authority 1 ## Authority values: AzureAd (1), Enterprise (2)
Updates the workplace CA certificate for the current user, if any, in the same way as the RefreshP2PCACert
command.
Also updates the current device’s P2P certificate if the current user is an administrator.
Validate an Authentication Request PDU as defined in the RDS AAD Auth Connection Sequence section of the MS-RDPBCGR.
The call is also listed as a protocol example in the section "Validating an Authentication Request."
The Authentication Request PDU will contain an RDP Assertion (e.g., a JWT) which functions as a user credential.
The caller must be System and the host must be cloud domain joined for the call to succeed.
If the call succeeds the returned Base64 URL string may be used as a credential blob with LsaLogonUser
to create a new logon session.
The Microsoft Account (MSA) plugin supports additional functionality through the GenericCallPkg
plugin function.
This functionality has not been fully analyzed.
If you make an MSA request from an AppContainer, it must have the liveIdService
capability.
Input data is a WlidPropertyBag
.
Reverse engineering some structures were key in understanding the internal message protocol functions that cloudap provides. A description and partial definition for each of these structures is provided here for others to use and research further. These may not be completely accurate and contributions are appreciated.
Cloudap may store the DPAPI "Cred Key" for a user profile on the file system.
If it does, information about the CredKey will be stored under C:\Windows\System32\config\systemprofile\AppData\Local\Microsoft\Windows\CloudAPCache
under a subfolder (AzureAD
or MicrosoftAccount
) in a file named [User Profile Id]\Keys\CredKeyInfo
in the _CLOUDAP_CREDKEY_INFO
format.
Offset (x64) | Definition | NT Build | Remarks |
---|---|---|---|
|
|
19041 |
Currently, should always be 1 |
|
|
19041 |
The CredKey Id |
|
|
19041 |
|
|
|
19041 |
Cloudap maintains a linked list of _LOGON_SESSION
structures for each cloudap provided user logon session.
New entries have been appended to this structure over time, but the current list of known entries and their offsets are as follows.
Offset (x64) | Definition | NT Build | Remarks |
---|---|---|---|
|
|
19041 |
|
|
|
19041 |
The ID of the logon session |
|
|
19041 |
Microsoft’s synonym for a CloudAP plugin |
|
|
19041 |
|
|
|
19041 |
The format of _SCARD_PIN was not researched |
Cloudap maintains a _USER_CACHE_ENTRY
structure for each cloudap user logon session to maintain user specific information about the session.
Offset (x64) | Definition | NT Build | Remarks |
---|---|---|---|
|
|
19041 |
|
|
|
19041 |
|
|
|
19041 |
A counter for how many times the cloudap updated this structure |
|
|
19041 |
A synchronization primitive for accessing the structure |
|
|
19041 |
|
|
|
19041 |
|
|
|
19041 |
|
|
|
19041 |
DPAPI masterkey for the user, protected by LSA’s DPAPI masterkey |
|
|
19041 |
The data’s purpose is unknown |
|
|
19041 |
|
|
|
19041 |
The TokenBlob or "CloudTGT" |
|
|
19041 |
AP_BLOB is the same as LSA_STRING with 4 byte length fields |
|
|
19041 |
|
|
|
19041 |
|
|
|
19041 |
|
|
|
19041 |
|
|
|
19041 |
|
|
|
19041 |