Skip to content

Commit

Permalink
Merge branch 'pr/usamaazad/166'
Browse files Browse the repository at this point in the history
  • Loading branch information
jdearmas committed Mar 7, 2023
2 parents 50ce257 + 6731cce commit f91a0a0
Show file tree
Hide file tree
Showing 20 changed files with 1,723 additions and 0 deletions.
47 changes: 47 additions & 0 deletions scenarios/vulnerable_cognito/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@

# Scenario: vulnerable_cognito

**Size:** Small
**Difficulty:** Moderate

**Command:** `$ ./cloudgoat.py create vulnerable_cognito`

## Scenario Resources

1 S3 bucket
1 Cognito Userpool
1 Cognito IdentityPool
1 API Gateway REST API
1 Lambda
1 IAM role

## Scenario Start(s)

1. API Gateway URL

## Scenario Goal(s)

Get Cognito IdentityPool credentials

## Summary

In this scenario, you are presented with a Signup and login page with AWS Cognito in the backend.
You need to bypass restrictions and exploit misconfigurations in Amazon Cognito in order to
elevate your privileges and get Cognito Identity Pool credentials.

## Exploitation Route

![Lucidchart Diagram](exploitation_route.png "Exploitation Route")


## Walkthrough - Vulnerable Cognito

1. Starting with a Login and Signup form, the attacker tries to signup using an email but receives an email validation error.
2. The attacker opens source code of webpage to get Cognito Userpool client ID.
3. The attacker then users AWS CLI to signs up and confirms email manually to bypass client side validation check for the email.
4. Attacker logs in and gets redirected to "reader.html" webpage which does not contain any useful information. In Burp Suite, attacker finds a custom user attributes added after email confirmation.
5. The attacker then updates the custom attribute value using AWS CLI to escalate privileges.
6. Attacker logs in again and finds an Identity Pool session being established in Burp Suite which containsAWS Access keys in response.
7. Attacker collects the credentials and runs enumerate-iam script to check privileges.

A cheat sheet for this route is available [here](./cheat_sheet.md).
69 changes: 69 additions & 0 deletions scenarios/vulnerable_cognito/assets/app/admin.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<!DOCTYPE html>

<head>
<title>Admin</title>
</head>

<body>

<script src="./amazon-cognito-identity.min.js"></script>
<script src="./aws-sdk.js"></script>

<script>


var poolData = {
UserPoolId: '${cognito_userpool_id}',
ClientId: '${cognito_client_id}',
};

var userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);
var cognitoUser = userPool.getCurrentUser();


if (cognitoUser != null) {
cognitoUser.getSession(function(err, result) {
if (result) {
console.log('You are now logged in.');

//POTENTIAL: Region needs to be set if not already set previously elsewhere.
AWS.config.region = '${region_html}';

// Add the User's Id Token to the Cognito credentials login map.
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: '${cognito_identity_id}',
Logins: {
'${cognito_userpool_uri}': result
.getIdToken()
.getJwtToken(),
},
});
}
});
}
//call refresh method in order to authenticate user and get new temp credentials
AWS.config.credentials.refresh(error => {
if (error) {
console.error(error);
} else {
console.log('Successfully logged!');
}
});




</script>



<h1 align="center">You're an Admin!!</h1>





<body>


</html>
120 changes: 120 additions & 0 deletions scenarios/vulnerable_cognito/assets/app/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>Vulnerable Cognito</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
<link rel="stylesheet" type="text/css" href="./style.css">

</head>
<body>

<script src="./amazon-cognito-identity.min.js"></script>


<script>

function Redirect(){



}



function Login(){

var email = document.getElementById('email').value;
var password = document.getElementById('password').value;

var CognitoUserPool = AmazonCognitoIdentity.CognitoUserPool;
var poolData = {
UserPoolId: '${cognito_userpool_id}',
ClientId: '${cognito_client_id}',
};
var authenticationData = {
Username: email,
Password: password,
};
var authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails(
authenticationData
);

var userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);
var userData = {
Username: email,
Pool: userPool,
};
var cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData);

// cognitoUser.setAuthenticationFlowType('USER_PASSWORD_AUTH');

cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: function(result) {
var accessToken = result.getAccessToken().getJwtToken();

cognitoUser.getUserAttributes(function(err, result) {
if (err) {
alert(err.message || JSON.stringify(err));
return;
}

var access = result[0].getValue()

console.log(access)

if(access == 'admin'){
window.location = "./admin.html";
}
else{
window.location = "./reader.html"
}

for (i = 0; i < result.length; i++) {
console.log(
'attribute ' + result[i].getName() + ' has value ' + result[i].getValue()
);

}
});
//Login Redirect here

},

onFailure: function(err) {
alert(err.message || JSON.stringify(err));
},
});
}
</script>

<!-- partial:index.partial.html -->
<div class="route" id="welcome"></div>
<div id="app">
<div class="app-view">
<header class="app-header">
<h1>Vuln Cognito</h1>
Welcome back,<br/>
<span class="app-subheading">
sign in to continue<br/>
</span>
</header>
<input id="email" type="email" required pattern=".*\.\w{2,}" placeholder="Username / Email Address" />
<input id="password" type="password" required placeholder="Password" />
<a class="app-button" onclick="Login()">Login</a>
<div class="app-register">
Don't have an account? <a href="./signup.html">Sign Up</a>
</div>
</div>

</div>

<!-- partial -->






</body>
</html>
20 changes: 20 additions & 0 deletions scenarios/vulnerable_cognito/assets/app/reader.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!DOCTYPE html>

<head>
<title>Reader</title>
</head>



<body>

<h1 align="center">You're a Reader!!</h1>





<body>


</html>
119 changes: 119 additions & 0 deletions scenarios/vulnerable_cognito/assets/app/signup.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>Vulnerable Cognito</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
<link rel="stylesheet" type="text/css" href="./style.css">

</head>
<body>



<script src="./amazon-cognito-identity.min.js"></script>


<script>


function Signup(){

// var letters = /[a-zA-Z0-9]{1,40}@ecorp.com/;

var email = document.getElementById('email').value;
var Regex = email.search('@ecorp.com');
// alert(Regex);


if(Regex == -1) {

alert("Only Emails from ecorp.com are accepted");
return false;

}

var first = document.getElementById('first').value;
var last = document.getElementById('last').value;
var password = document.getElementById('password').value;



var poolData = {
UserPoolId: '${cognito_userpool_id}',
ClientId: '${cognito_client_id}',
};


var userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);

var attributeList = [];

var dataEmail = {
Name: 'email',
Value: email,
};

var dataFirstName = {
Name: 'given_name',
Value: first,
};

var dataLastName = {
Name: 'family_name',
Value: last,
};

var attributeEmail = new AmazonCognitoIdentity.CognitoUserAttribute(dataEmail);
var attributeFirstName = new AmazonCognitoIdentity.CognitoUserAttribute(dataFirstName);
var attributeLastName = new AmazonCognitoIdentity.CognitoUserAttribute(dataLastName);

attributeList.push(attributeEmail);
attributeList.push(attributeFirstName);
attributeList.push(attributeLastName);

userPool.signUp(email, password, attributeList, null, function(
err,
result
) {
if (err) {
alert(err.message || JSON.stringify(err));
return;
}
var cognitoUser = result.user;
console.log('user name is ' + cognitoUser.getUsername());
});

}
</script>



<!-- partial:index.partial.html -->
<div class="route" id="welcome"></div>
<div id="app">
<div class="app-view">
<header class="app-header">
<h1>Vuln Cognito</h1>
Welcome,<br/>
<span class="app-subheading">
Signup to continue<br/>
</span>
</header>
<input type="text" id="first" placeholder="First Name" />
<input type="text" id="last" placeholder="Last Name" />
<input type="email" id="email" required placeholder="Email ([email protected])" />
<!--pattern="[a-zA-Z0-9]{1,40}@ecorp.com"-->
<input type="password" id="password" required placeholder="Password" />
<a class="app-button" onclick="Signup()">Signup</a>
<div class="app-register">
Don't have an account? <a href="./index.html">Login</a>
</div>
</div>

</div>

<!-- partial -->

</body>
</html>

Large diffs are not rendered by default.

69 changes: 69 additions & 0 deletions scenarios/vulnerable_cognito/assets/app/static/aws-sdk.js

Large diffs are not rendered by default.

Loading

0 comments on commit f91a0a0

Please sign in to comment.