┌──(root㉿SPARTAN-SERVER)-[/home/hacker/cloudgoat]└─#./cloudgoat.pycreatevulnerable_cognitoUsingdefaultprofile"default"fromconfig.yml...Loadingwhitelist.txt...Awhitelist.txtfilewasfoundthatcontainsatleastonevalidIPaddressorrange.Initializingthebackend...Initializingproviderplugins...-Findinghashicorp/awsversionsmatching"~> 4.16"...-Installinghashicorp/awsv4.67.0...-Installedhashicorp/awsv4.67.0 (signed byHashiCorp)Terraformhascreatedalockfile.terraform.lock.hcltorecordtheproviderselectionsitmadeabove.IncludethisfileinyourversioncontrolrepositorysothatTerraformcanguaranteetomakethesameselectionsbydefaultwhenyourun"terraform init"inthefuture.Terraformhasbeensuccessfullyinitialized!YoumaynowbeginworkingwithTerraform.Tryrunning"terraform plan"toseeanychangesthatarerequiredforyourinfrastructure.AllTerraformcommandsshouldnowwork.IfyoueversetorchangemodulesorbackendconfigurationforTerraform,rerunthiscommandtoreinitializeyourworkingdirectory.Ifyouforget,othercommandswilldetectitandremindyoutodosoifnecessary.[cloudgoat] terraform init completed with no error code.data.aws_caller_identity.aws-account-id:Reading...data.aws_caller_identity.aws-account-id:Readcompleteafter0s [id=583318501385]
Al finalizar el despliegue sale el siguiente mensaje:
Applycomplete!Resources:44added,0changed,0destroyed.Outputs:apigateway_url = "https://ty97c4wq6b.execute-api.us-east-1.amazonaws.com/vulncognito/cognitoctf-vulnerablecognitocgidf2vavqfesu/index.html"
cloudgoat_output_aws_account_id="583318501385"[cloudgoat] terraform apply completed with no error code.[cloudgoat] terraform output completed with no error code.apigateway_url = https://ty97c4wq6b.execute-api.us-east-1.amazonaws.com/vulncognito/cognitoctf-vulnerablecognitocgidf2vavqfesu/index.html
cloudgoat_output_aws_account_id=583318501385[cloudgoat] Output file written to:/home/hacker/cloudgoat/vulnerable_cognito_cgidf2vavqfesu/start.txt
Nuestra auditoria comienza con la revision de la URL previamente obtenida.
Análisis del Código HTML
En el codigo fuente de esta aplicacion se encuentra la siguiente informacion:
functionLogin(){var email =document.getElementById('email').value;var password =document.getElementById('password').value;var CognitoUserPool =AmazonCognitoIdentity.CognitoUserPool;var poolData = { UserPoolId:'us-east-1_geWllxg2l', ClientId:'7gis1uto72h5462s6ekvm7rkhd', };var authenticationData = { Username: email, Password: password, };var authenticationDetails =newAmazonCognitoIdentity.AuthenticationDetails( authenticationData );var userPool =newAmazonCognitoIdentity.CognitoUserPool(poolData);var userData = { Username: email, Pool: userPool, };var cognitoUser =newAmazonCognitoIdentity.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[4].getValue() // currently the 'custom:access' is at index 4// or if the index changes again,// the following code always gets it// for (const name of result) {// if (name.Name === "custom:access") {// access = name.Value;// }// }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)); }, });}
La información encontrada en el código HTML se refiere a la configuración inicial necesaria para interactuar con Amazon Cognito, un servicio que proporciona autenticación y gestión de usuarios para aplicaciones web y móviles. Vamos a analizar detalladamente la sensibilidad de esta información y su propósito.
Fragmento de Código Analizado:
var poolData = { UserPoolId:'us-east-1_geWllxg2l', ClientId:'7gis1uto72h5462s6ekvm7rkhd',};
Amazon Cognito: UserPoolId y ClientId
UserPoolId:
Definición: El UserPoolId es un identificador único para el pool de usuarios (User Pool) en Amazon Cognito. Este ID especifica el pool de usuarios con el que la aplicación interactuará.
Sensibilidad: Este identificador por sí mismo no es extremadamente sensible, pero puede proporcionar pistas sobre la infraestructura del backend a un atacante si se combina con otra información.
ClientId:
Definición: El ClientId es un identificador único para la aplicación cliente dentro del pool de usuarios. Este ID es utilizado para identificar la aplicación que solicita autenticación y autorización.
Sensibilidad: Al igual que el UserPoolId, el ClientId no es particularmente sensible en sí mismo. Sin embargo, puede ser considerado un vector de ataque si un atacante tiene información adicional.
Naturaleza Pública de los Identificadores
Es común que tanto UserPoolId como ClientId sean expuestos en el frontend (públicamente accesibles) ya que son necesarios para que las aplicaciones web y móviles interactúen con Amazon Cognito. Estos identificadores permiten a la aplicación saber a qué pool de usuarios y aplicación cliente debe dirigir las solicitudes de autenticación.
Fragmento de Código Analizado:
Es común Por otro lado, esta pieza de codigo divulga desde el frontend posibles rutas de usuarios privilegiados:
Teniendo en cuenta lo anterior, podriamos intentar ejecutar el siguiente comando:
┌──(hacker㉿SPARTAN-SERVER)-[~]└─$ aws cognito-idp sign-up --client-id 7gis1uto72h5462s6ekvm7rkhd --username spartan@9oyni96k6emaluakgulsfiypsgy7mxam.oastify.com --password Password123! --region us-east-1
An error occurred (InvalidParameterException) when calling the SignUp operation: Attributes did not conform to the schema: name.givenName: The attribute name.givenName is required, name.familyName: The attribute name.familyName is required
Amazon Cognito Identity Provider (Cognito-IDP) es un servicio de Amazon Web Services (AWS) diseñado para simplificar la autenticación, autorización y gestión de usuarios en aplicaciones web y móviles. Proporciona funcionalidades esenciales para manejar el ciclo de vida de los usuarios, incluyendo el registro, inicio de sesión y gestión de perfiles, con soporte para múltiples proveedores de identidad.
Para obtener el oastify se puede utilizar colaborator de BurpSuite:
Al intentar registrar nuestro usuario, se nos retorna un error que inidica que faltan los atributos del usuarios.
El error indica que los atributos son name.givenName y name.familyName asi que el comando seria:
La información sobre el nivel de acceso del usuario (custom:access:reader) podría ser utilizada para escalar privilegios si no se gestionan adecuadamente los controles de acceso en la aplicación.
El analisis del JWT tambien lo podemos realizar con la siguiente pagina:
Cambiando atributos personalizados del usuario
Despues de lo anterior, se procede a realizar el cambio del atributo:
Luego de iniciar sesion nuevamente nos redirige a la sesion de administrador:
El fichero admin.html tiene la siguiente informacion:
<!DOCTYPEhtml><head> <title>Admin</title></head><body><scriptsrc="./amazon-cognito-identity.min.js"></script><scriptsrc="./aws-sdk.js"></script><script>var poolData = { UserPoolId:'us-east-1_geWllxg2l', ClientId:'7gis1uto72h5462s6ekvm7rkhd',};var userPool =newAmazonCognitoIdentity.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 ='us-east-1';// Add the User's Id Token to the Cognito credentials login map.AWS.config.credentials =newAWS.CognitoIdentityCredentials({ IdentityPoolId:'us-east-1:6d13aa02-7559-49f0-91ec-66047f4046da', Logins: {'cognito-idp.us-east-1.amazonaws.com/us-east-1_geWllxg2l': result.getIdToken().getJwtToken(), }, }); } });}//call refresh method in order to authenticate user and get new temp credentialsAWS.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>
Luego de lo anterior, se procede a ejecutar el siguiente comando: