CredMaster
CredMaster copied to clipboard
[O365Enum] Users with passwordless auth return not found
Calling via credmaster, we get
(Note: I added a
print(response.json())
at line 59 to get the json.)
{
"Username": "[email protected]",
"Display": "[email protected]",
"IfExistsResult": 1,
"IsUnmanaged": false,
"ThrottleStatus": 0,
"Credentials": {
"PrefCredential": 1,
"HasPassword": true,
"RemoteNgcParams": null,
"FidoParams": null,
"SasParams": null,
"CertAuthParams": null,
"GoogleParams": null,
"FacebookParams": null,
"CaptchaParams": null
},
"EstsProperties": {
"UserTenantBranding": null,
"DomainType": 3
},
"IsSignupDisallowed": true,
"apiCanary": "asdfmovie4"
}
Going to log in manually, we see this
Note that here the value of IfExistsResult
from /common/GetCredentialType
is 5
.
From the response:
{
"Username": "[email protected]",
"Display": "[email protected]",
"IfExistsResult": 5,
"IsUnmanaged": false,
"ThrottleStatus": 0,
"Credentials": {
"PrefCredential": 1,
"HasPassword": true,
"RemoteNgcParams": null,
"FidoParams": null,
"SasParams": null,
"CertAuthParams": null,
"GoogleParams": null,
"FacebookParams": null,
"CaptchaParams": null
},
"EstsProperties": {
"UserTenantBranding": null,
"DomainType": 3
},
"FlowToken": "gowiththeflowman",
"IsSignupDisallowed": true,
"apiCanary": "some_garbage"
}
(Looks like this code is "Different IDP", not sure if that's used elsewhere, of just for passwordless auth.)
The only other difference I'm seeing is the FlowToken
being set in the second.
Sending garbage in as a flow token doesn't seem to fix it. The actual token is generated client site in JS.
Rare for me to see an issue from you without a PR, do you have any idea how to differentiate?
I'm a little confused by the two JSON objects, it seems like the first one is what you're saying needs to change (ifexistsresult 1) so we would need to figure out what the difference would be elsewise?
Sorry man, I'm only human. I'll send some other PR (maybe add pet credmaster
functionality?) to make up for it 😉
The issue seems to be that calling as credmaster does (without the other variables that are computed via clientside JS), you get "user not found" vs "user exists, but don't use a password". I haven't been able to figure out how to get that value correctly as of yet.
The second JSON object where the correct result is retuned is from burp-proxying the request through the normal web flow
Hahah, pet credmaster
would be creepy but an invaluable contribution to the tool.
So are you saying that the clientside JS determines different request variables, which then impacts the response itself?
Just as an input, not sure if it helps anything...
I used the tool with the o365 module against a list of test users with a valid password. All of them returned "FAILURE".
The response code 401 was returned for all requests (even though MFA excluded, correct password).
Using the module msol however worked and identified the correct credentials.
Maybe Microsoft changed something in the autodiscover
url / endpoint so that this does not work anymore? If I have time for further debugging, I'll let you know.
Yeah I just opened ann issue on that I belive it is because of AADSTS53003 or the CAP policy
Just as an input, not sure if it helps anything... I used the tool with the o365 module against a list of test users with a valid password. All of them returned "FAILURE". The response code 401 was returned for all requests (even though MFA excluded, correct password). Using the module msol however worked and identified the correct credentials. Maybe Microsoft changed something in the
autodiscover
url / endpoint so that this does not work anymore? If I have time for further debugging, I'll let you know.
Microsoft disabled BasicAuth for all tenant, which the o365 plugin rely on.