AWS - S3, Athena & Glacier Enum

Aprende hacking en AWS desde cero hasta experto con htARTE (HackTricks AWS Red Team Expert)!

Otras formas de apoyar a HackTricks:

S3

Amazon S3 es un servicio que te permite almacenar grandes cantidades de datos.

Amazon S3 proporciona múltiples opciones para lograr la protección de datos en reposo. Las opciones incluyen Permisos (Política), Cifrado (Cliente y Servidor), Versionado de Buckets y Eliminación basada en MFA. El usuario puede habilitar cualquiera de estas opciones para lograr la protección de datos. La replicación de datos es una facilidad interna de AWS donde S3 replica automáticamente cada objeto en todas las Zonas de Disponibilidad y la organización no necesita habilitarla en este caso.

Con permisos basados en recursos, puedes definir permisos para subdirectorios de tu bucket por separado.

Versionado de Buckets y Eliminación basada en MFA

Cuando se habilita el versionado de buckets, cualquier acción que intente alterar un archivo dentro de un archivo generará una nueva versión del archivo, manteniendo también el contenido anterior del mismo. Por lo tanto, no sobrescribirá su contenido.

Además, la eliminación basada en MFA evitará que se eliminen versiones de archivos en el bucket de S3 y también que se deshabilite el Versionado de Buckets, por lo que un atacante no podrá alterar estos archivos.

Registros de acceso de S3

Es posible habilitar el registro de acceso de S3 (que por defecto está deshabilitado) para algún bucket y guardar los registros en un bucket diferente para saber quién está accediendo al bucket (ambos buckets deben estar en la misma región).

URLs prefirmadas de S3

Es posible generar una URL prefirmada que generalmente se puede utilizar para acceder al archivo especificado en el bucket. Una URL prefirmada se ve así:

https://<bucket-name>.s3.us-east-1.amazonaws.com/asd.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ASIAUUE8GZC4S5L3TY3P%2F20230227%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230227T142551Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Security-Token=IQoJb3JpZ2luX2VjELf%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaCXVzLWVhc3QtMSJHMEUCIBhQpdETJO3HKKDk2hjNIrPWwBE8gZaQccZFV3kCpPCWAiEAid3ueDtFFU%2FOQfUpvxYTGO%2BHoS4SWDMUrQAE0pIaB40qggMIYBAAGgwzMTgxNDIxMzg1NTMiDJLI5t7gr2EGxG1Y5CrfAioW0foHIQ074y4gvk0c%2B%2Fmqc7cNWb1njQslQkeePHkseJ3owzc%2FCwkgE0EuZTd4mw0aJciA2XIbJRCLPWTb%2FCBKPnIMJ5aBzIiA2ltsiUNQTTUxYmEgXZoJ6rFYgcodnmWW0Et4Xw59UlHnCDB2bLImxPprriyCzDDCD6nLyp3J8pFF1S8h3ZTJE7XguA8joMs4%2B2B1%2FeOZfuxXKyXPYSKQOOSbQiHUQc%2BFnOfwxleRL16prWk1t7TamvHR%2Bt3UgMn5QWzB3p8FgWwpJ6GjHLkYMJZ379tkimL1tJ7o%2BIod%2FMYrS7LDCifP9d%2FuYOhKWGhaakPuJKJh9fl%2B0vGl7kmApXigROxEWon6ms75laXebltsWwKcKuYca%2BUWu4jVJx%2BWUfI4ofoaGiCSaKALTqwu4QNBRT%2BMoK6h%2BQa7gN7JFGg322lkxRY53x27WMbUE4unn5EmI54T4dWt1%2Bg8ljDS%2BvKfBjqmAWRwuqyfwXa5YC3xxttOr3YVvR6%2BaXpzWtvNJQNnb6v0uI3%2BTtTexZkJpLQYqFcgZLQSxsXWSnf988qvASCIUhAzp2UnS1uqy7QjtD5T73zksYN2aesll7rvB80qIuujG6NOdHnRJ2M5%2FKXXNo1Yd15MtzPuSjRoSB9RSMon5jFu31OrQnA9eCUoawxbB0nHqwK8a43CKBZHhA8RoUAJW%2B48EuFsp3U%3D&X-Amz-Signature=3436e4139e84dbcf5e2e6086c0ebc92f4e1e9332b6fda24697bc339acbf2cdfa

Un URL prefirmado se puede crear desde la CLI utilizando las credenciales de un principal con acceso al objeto (si la cuenta que utilizas no tiene acceso, se creará un URL prefirmado más corto pero será inútil)

aws s3 presign --region <bucket-region> 's3://<bucket-name>/<file-name>'

La única permiso requerido para generar una URL prefirmada es el permiso que se está otorgando, por lo tanto, para el comando anterior, el único permiso necesario por el principal es s3:GetObject

También es posible crear URLs prefirmadas con otros permisos:

import boto3
url = boto3.client('s3').generate_presigned_url(
ClientMethod='put_object',
Params={'Bucket': 'BUCKET_NAME', 'Key': 'OBJECT_KEY'},
ExpiresIn=3600
)

Mecanismos de Encriptación de S3

DEK significa Clave de Encriptación de Datos y es la clave que siempre se genera y se utiliza para encriptar datos.

Encriptación en el lado del servidor con claves gestionadas por S3, SSE-S3

Esta opción requiere una configuración mínima y todas las claves de encriptación utilizadas son gestionadas por AWS. Todo lo que necesitas hacer es subir tus datos y S3 se encargará de todos los demás aspectos. A cada bucket en una cuenta de S3 se le asigna una clave de bucket.

  • Encriptación:

  • Datos del objeto + DEK de texto plano creado --> Datos encriptados (almacenados dentro de S3)

  • DEK de texto plano creado + Clave Maestra de S3 --> DEK encriptado (almacenado dentro de S3) y el texto plano se elimina de la memoria

  • Desencriptación:

  • DEK encriptado + Clave Maestra de S3 --> DEK de texto plano

  • DEK de texto plano + Datos encriptados --> Datos del objeto

Por favor, ten en cuenta que en este caso la clave es gestionada por AWS (rotación solo cada 3 años). Si utilizas tu propia clave, podrás rotar, deshabilitar y aplicar control de acceso.

Encriptación en el lado del servidor con claves gestionadas por KMS, SSE-KMS

Este método permite que S3 utilice el servicio de gestión de claves para generar tus claves de encriptación de datos. KMS te brinda una mayor flexibilidad en la gestión de tus claves. Por ejemplo, puedes deshabilitar, rotar y aplicar controles de acceso al CMK, y ordenar en contra de su uso utilizando AWS Cloud Trail.

  • Encriptación:

  • S3 solicita claves de datos a KMS CMK

  • KMS utiliza un CMK para generar el par DEK de texto plano y DEK encriptado y los envía a S3

  • S3 utiliza la clave de texto plano para encriptar los datos, almacena los datos encriptados y la clave encriptada y elimina de la memoria la clave de texto plano

  • Desencriptación:

  • S3 solicita a KMS desencriptar la clave de datos encriptada del objeto

  • KMS desencripta la clave de datos con el CMK y la envía de vuelta a S3

  • S3 desencripta los datos del objeto

Encriptación en el lado del servidor con claves proporcionadas por el cliente, SSE-C

Esta opción te brinda la oportunidad de proporcionar tu propia clave maestra que ya puedas estar utilizando fuera de AWS. Tu clave proporcionada por el cliente se enviaría con tus datos a S3, donde S3 realizaría la encriptación por ti.

  • Encriptación:

  • El usuario envía los datos del objeto + Clave del cliente a S3

  • La clave del cliente se utiliza para encriptar los datos y se almacenan los datos encriptados

  • se almacena también un valor HMAC salteado de la clave del cliente para futura validación de la clave

  • la clave del cliente se elimina de la memoria

  • Desencriptación:

  • El usuario envía la clave del cliente

  • La clave se valida contra el valor HMAC almacenado

  • La clave proporcionada por el cliente se utiliza entonces para desencriptar los datos

Encriptación en el lado del cliente con KMS, CSE-KMS

De manera similar a SSE-KMS, esto también utiliza el servicio de gestión de claves para generar tus claves de encriptación de datos. Sin embargo, esta vez KMS es invocado a través del cliente y no de S3. La encriptación luego se realiza en el lado del cliente y los datos encriptados se envían a S3 para ser almacenados.

  • Encriptación:

  • El cliente solicita una clave de datos a KMS

  • KMS devuelve el DEK de texto plano y el DEK encriptado con el CMK

  • Ambas claves se envían de vuelta

  • El cliente luego encripta los datos con el DEK de texto plano y envía a S3 los datos encriptados + el DEK encriptado (que se guarda como metadatos de los datos encriptados dentro de S3)

  • Desencriptación:

  • Los datos encriptados con el DEK encriptado se envían al cliente

  • El cliente solicita a KMS desencriptar la clave encriptada utilizando el CMK y KMS devuelve el DEK de texto plano

  • El cliente ahora puede desencriptar los datos encriptados

Encriptación en el lado del cliente con claves proporcionadas por el cliente, CSE-C

Utilizando este mecanismo, puedes utilizar tus propias claves proporcionadas y utilizar un cliente de AWS-SDK para encriptar tus datos antes de enviarlos a S3 para su almacenamiento.

  • Encriptación:

  • El cliente genera un DEK y encripta los datos de texto plano

  • Luego, utilizando su propio CMK personalizado, encripta el DEK

  • envía los datos encriptados + DEK encriptado a S3 donde se almacenan

  • Desencriptación:

  • S3 envía los datos encriptados y el DEK

  • Como el cliente ya tiene el CMK utilizado para encriptar el DEK, desencripta el DEK y luego utiliza el DEK de texto plano para desencriptar los datos

Enumeración

Una de las formas tradicionales principales de comprometer organizaciones de AWS comienza por comprometer buckets accesibles públicamente. Puedes encontrar enumeradores de buckets públicos en esta página.

# Get buckets ACLs
aws s3api get-bucket-acl --bucket <bucket-name>
aws s3api get-object-acl --bucket <bucket-name> --key flag

# Get policy
aws s3api get-bucket-policy --bucket <bucket-name>
aws s3api get-bucket-policy-status --bucket <bucket-name> #if it's public

# list S3 buckets associated with a profile
aws s3 ls
aws s3api list-buckets

# list content of bucket (no creds)
aws s3 ls s3://bucket-name --no-sign-request
aws s3 ls s3://bucket-name --recursive

# list content of bucket (with creds)
aws s3 ls s3://bucket-name
aws s3api list-objects-v2 --bucket <bucket-name>
aws s3api list-objects --bucket <bucket-name>
aws s3api list-object-versions --bucket <bucket-name>

# copy local folder to S3
aws s3 cp MyFolder s3://bucket-name --recursive

# delete
aws s3 rb s3://bucket-name –-force

# download a whole S3 bucket
aws s3 sync s3://<bucket>/ .

# move S3 bucket to different location
aws s3 sync s3://oldbucket s3://newbucket --source-region us-west-1

# list the sizes of an S3 bucket and its contents
aws s3api list-objects --bucket BUCKETNAME --output json --query "[sum(Contents[].Size), length(Contents[])]"

# Update Bucket policy
aws s3api put-bucket-policy --policy file:///root/policy.json --bucket <bucket-name>
##JSON policy example
{
"Id": "Policy1568185116930",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1568184932403",
"Action": [
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::welcome",
"Principal": "*"
},
{
"Sid": "Stmt1568185007451",
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::welcome/*",
"Principal": "*"
}
]
}

# Update bucket ACL
aws s3api get-bucket-acl --bucket <bucket-name> # Way 1 to get the ACL
aws s3api put-bucket-acl --bucket <bucket-name> --access-control-policy file://acl.json

aws s3api get-object-acl --bucket <bucket-name> --key flag #Way 2 to get the ACL
aws s3api put-object-acl --bucket <bucket-name> --key flag --access-control-policy file://objacl.json

##JSON ACL example
## Make sure to modify the Owner’s displayName and ID according to the Object ACL you retrieved.
{
"Owner": {
"DisplayName": "<DisplayName>",
"ID": "<ID>"
},
"Grants": [
{
"Grantee": {
"Type": "Group",
"URI": "http://acs.amazonaws.com/groups/global/AuthenticatedUsers"
},
"Permission": "FULL_CONTROL"
}
]
}
## An ACL should give you the permission WRITE_ACP to be able to put a new ACL

dual-stack

Puedes acceder a un bucket de S3 a través de un punto de conexión de doble pila utilizando un nombre de punto de conexión de estilo alojado virtual o de estilo de ruta. Estos son útiles para acceder a S3 a través de IPv6.

Los puntos de conexión de doble pila utilizan la siguiente sintaxis:

  • bucketname.s3.dualstack.aws-region.amazonaws.com

  • s3.dualstack.aws-region.amazonaws.com/bucketname

Escalada de privilegios

En la siguiente página puedes verificar cómo abusar de los permisos de S3 para escalar privilegios:

pageAWS - S3 Privesc

Acceso no autenticado

pageAWS - S3 Unauthenticated Enum

Post Explotación de S3

pageAWS - S3 Post Exploitation

Persistencia

pageAWS - S3 Persistence

Otras vulnerabilidades de S3

Problema de Envenenamiento de Caché HTTP de S3

Según esta investigación era posible almacenar en caché la respuesta de un bucket arbitrario como si perteneciera a otro. Esto podría haber sido abusado para cambiar, por ejemplo, las respuestas de archivos javascript y comprometer páginas arbitrarias que utilizan S3 para almacenar código estático.

Amazon Athena

Amazon Athena es un servicio de consulta interactivo que facilita el análisis de datos directamente en Amazon Simple Storage Service (Amazon S3) utilizando SQL estándar.

Necesitas preparar una tabla de base de datos relacional con el formato del contenido que va a aparecer en los buckets de S3 monitoreados. Luego, Amazon Athena podrá poblar la base de datos a partir de los registros, para que puedas hacer consultas.

Amazon Athena admite la capacidad de consultar datos de S3 que ya están encriptados y, si está configurado para hacerlo, Athena también puede encriptar los resultados de la consulta que luego se pueden almacenar en S3.

Esta encriptación de resultados es independiente de los datos de S3 consultados subyacentes, lo que significa que incluso si los datos de S3 no están encriptados, los resultados consultados pueden estar encriptados. Un par de puntos a tener en cuenta es que Amazon Athena solo admite datos que han sido encriptados con los siguientes métodos de encriptación de S3, SSE-S3, SSE-KMS y CSE-KMS.

SSE-C y CSE-E no son compatibles. Además de esto, es importante entender que Amazon Athena solo ejecutará consultas contra objetos encriptados que estén en la misma región que la consulta en sí. Si necesitas consultar datos de S3 que han sido encriptados usando KMS, entonces se requieren permisos específicos por parte del usuario de Athena para permitirles realizar la consulta.

Enumeración

# Get catalogs
aws athena list-data-catalogs

# Get databases inside catalog
aws athena list-databases --catalog-name <catalog-name>
aws athena list-table-metadata --catalog-name <catalog-name> --database-name <db-name>

# Get query executions, queries and results
aws athena list-query-executions
aws athena get-query-execution --query-execution-id <id> # Get query and meta of results
aws athena get-query-results --query-execution-id <id> # This will rerun the query and get the results

# Get workgroups & Prepared statements
aws athena list-work-groups
aws athena list-prepared-statements --work-group <wg-name>
aws athena get-prepared-statement --statement-name <name> --work-group <wg-name>

# Run query
aws athena start-query-execution --query-string <query>

Referencias

Aprende hacking en AWS de cero a héroe con htARTE (HackTricks AWS Red Team Expert)!

Otras formas de apoyar a HackTricks:

Última actualización