mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2025-12-05 20:40:18 -08:00
Translated ['src/pentesting-cloud/aws-security/aws-privilege-escalation/
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -34,3 +34,4 @@ Temporary Items
|
||||
book
|
||||
book/*
|
||||
hacktricks-preprocessor.log
|
||||
hacktricks-preprocessor-error.log
|
||||
|
||||
@@ -7,7 +7,14 @@ from os import path
|
||||
from urllib.request import urlopen, Request
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
logging.basicConfig(filename='hacktricks-preprocessor.log', filemode='w', encoding='utf-8', level=logging.DEBUG)
|
||||
logger.setLevel(logging.DEBUG)
|
||||
handler = logging.FileHandler(filename='hacktricks-preprocessor.log', mode='w', encoding='utf-8')
|
||||
handler.setLevel(logging.DEBUG)
|
||||
logger.addHandler(handler)
|
||||
|
||||
handler2 = logging.FileHandler(filename='hacktricks-preprocessor-error.log', mode='w', encoding='utf-8')
|
||||
handler2.setLevel(logging.ERROR)
|
||||
logger.addHandler(handler2)
|
||||
|
||||
|
||||
def findtitle(search ,obj, key, path=(),):
|
||||
@@ -45,19 +52,29 @@ def ref(matchobj):
|
||||
try:
|
||||
if href.endswith("/"):
|
||||
href = href+"README.md" # Fix if ref points to a folder
|
||||
chapter, _path = findtitle(href, book, "source_path")
|
||||
logger.debug(f'Recursive title search result: {chapter["name"]}')
|
||||
title = chapter['name']
|
||||
if "#" in href:
|
||||
chapter, _path = findtitle(href.split("#")[0], book, "source_path")
|
||||
title = " ".join(href.split("#")[1].split("-")).title()
|
||||
logger.debug(f'Ref has # using title: {title}')
|
||||
else:
|
||||
chapter, _path = findtitle(href, book, "source_path")
|
||||
logger.debug(f'Recursive title search result: {chapter["name"]}')
|
||||
title = chapter['name']
|
||||
except Exception as e:
|
||||
try:
|
||||
dir = path.dirname(current_chapter['source_path'])
|
||||
logger.debug(f'Error getting chapter title: {href} trying with relative path {path.normpath(path.join(dir,href))}')
|
||||
chapter, _path = findtitle(path.normpath(path.join(dir,href)), book, "source_path")
|
||||
logger.debug(f'Recursive title search result: {chapter["name"]}')
|
||||
title = chapter['name']
|
||||
if "#" in href:
|
||||
chapter, _path = findtitle(path.normpath(path.join(dir,href.split('#')[0])), book, "source_path")
|
||||
title = " ".join(href.split("#")[1].split("-")).title()
|
||||
logger.debug(f'Ref has # using title: {title}')
|
||||
else:
|
||||
chapter, _path = findtitle(path.normpath(path.join(dir,href.split('#')[0])), book, "source_path")
|
||||
title = chapter["name"]
|
||||
logger.debug(f'Recursive title search result: {chapter["name"]}')
|
||||
except Exception as e:
|
||||
logger.debug(f'Error getting chapter title: {path.normpath(path.join(dir,href))}')
|
||||
print(f'Error getting chapter title: {path.normpath(path.join(dir,href))}')
|
||||
logger.debug(e)
|
||||
logger.error(f'Error getting chapter title: {path.normpath(path.join(dir,href))}')
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
@@ -85,13 +102,11 @@ def files(matchobj):
|
||||
|
||||
except Exception as e:
|
||||
logger.debug(e)
|
||||
logger.debug(f'Error searching file: {href}')
|
||||
print(f'Error searching file: {href}')
|
||||
logger.error(f'Error searching file: {href}')
|
||||
sys.exit(1)
|
||||
|
||||
if title=="":
|
||||
logger.debug(f'Error searching file: {href}')
|
||||
print(f'Error searching file: {href}')
|
||||
logger.error(f'Error searching file: {href}')
|
||||
sys.exit(1)
|
||||
|
||||
template = f"""<a class="content_ref" href="/files/{href}"><span class="content_ref_label">{title}</span></a>"""
|
||||
@@ -134,10 +149,11 @@ if __name__ == '__main__':
|
||||
for chapter in iterate_chapters(book['sections']):
|
||||
logger.debug(f"Chapter: {chapter['path']}")
|
||||
current_chapter = chapter
|
||||
regex = r'{{[\s]*#ref[\s]*}}(?:\n)?([^\\\n]*)(?:\n)?{{[\s]*#endref[\s]*}}'
|
||||
# regex = r'{{[\s]*#ref[\s]*}}(?:\n)?([^\\\n]*)(?:\n)?{{[\s]*#endref[\s]*}}'
|
||||
regex = r'{{[\s]*#ref[\s]*}}(?:\n)?([^\\\n#]*(?:#(.*))?)(?:\n)?{{[\s]*#endref[\s]*}}'
|
||||
new_content = re.sub(regex, ref, chapter['content'])
|
||||
regex = r'{{[\s]*#file[\s]*}}(?:\n)?([^\\\n]*)(?:\n)?{{[\s]*#endfile[\s]*}}'
|
||||
new_content = re.sub(regex, files, chapter['content'])
|
||||
new_content = re.sub(regex, files, new_content)
|
||||
new_content = add_read_time(new_content)
|
||||
chapter['content'] = new_content
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ Y el secuestro es posible porque hay una **pequeña ventana de tiempo desde el m
|
||||
|
||||
.png>)
|
||||
|
||||
El módulo de Pacu [`cfn__resouce_injection`](https://github.com/RhinoSecurityLabs/pacu/wiki/Module-Details#cfn__resource_injection) se puede usar para automatizar este ataque.\
|
||||
El módulo de Pacu [`cfn__resouce_injection`](https://github.com/RhinoSecurityLabs/pacu/wiki/Module-Details#cfn__resource_injection) se puede utilizar para automatizar este ataque.\
|
||||
Para más información, consulta la investigación original: [https://rhinosecuritylabs.com/aws/cloud-malware-cloudformation-injection/](https://rhinosecuritylabs.com/aws/cloud-malware-cloudformation-injection/)
|
||||
|
||||
### `s3:PutObject`, `s3:GetObject` <a href="#s3putobject-s3getobject" id="s3putobject-s3getobject"></a>
|
||||
@@ -60,12 +60,12 @@ Entonces, si tienes los permisos listados sobre estos archivos, hay un vector de
|
||||
Sigue la descripción en la sección *Abusing Terraform State Files* de la página *Terraform Security* para obtener código de explotación directamente utilizable:
|
||||
|
||||
{{#ref}}
|
||||
terraform-security.md#abusing-terraform-state-files
|
||||
pentesting-ci-cd/terraform-security.md#abusing-terraform-state-files
|
||||
{{#endref}}
|
||||
|
||||
### `s3:PutBucketPolicy`
|
||||
|
||||
Un atacante, que necesita estar **en la misma cuenta**, si no, se activará el error `The specified method is not allowed`, con este permiso podrá otorgarse más permisos sobre el/los bucket(s) permitiéndole leer, escribir, modificar, eliminar y exponer buckets.
|
||||
Un atacante, que necesita ser **de la misma cuenta**, si no, se activará el error `The specified method is not allowed`, con este permiso podrá otorgarse más permisos sobre el/los bucket(s) permitiéndole leer, escribir, modificar, eliminar y exponer buckets.
|
||||
```bash
|
||||
# Update Bucket policy
|
||||
aws s3api put-bucket-policy --policy file:///root/policy.json --bucket <bucket-name>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
Para más información sobre los servicios de Azure App, consulta:
|
||||
|
||||
{{#ref}}
|
||||
../az-services/az-app-service.md
|
||||
../az-services/az-app-services.md
|
||||
{{#endref}}
|
||||
|
||||
### Microsoft.Web/sites/publish/Action, Microsoft.Web/sites/basicPublishingCredentialsPolicies/read, Microsoft.Web/sites/config/read, Microsoft.Web/sites/read
|
||||
@@ -43,7 +43,7 @@ ssh root@127.0.0.1 -p 39895
|
||||
|
||||
Para obtener las credenciales SCM, puedes usar los siguientes **comandos y permisos**:
|
||||
|
||||
- El permiso **`Microsoft.Web/sites/publishxml/action`** permite llamar a:
|
||||
- El permiso **`Microsoft.Web/sites/publishxml/action`** permite llamar:
|
||||
```bash
|
||||
az webapp deployment list-publishing-profiles --name <app-name> --resource-group <res-group>
|
||||
# Example output
|
||||
@@ -118,7 +118,7 @@ az webapp deployment list-publishing-credentials --name <app-name> --resource-gr
|
||||
```
|
||||
Nota cómo las **credenciales son las mismas** que en el comando anterior.
|
||||
|
||||
- Otra opción sería **configurar tus propias credenciales** y usarlas:
|
||||
- Otra opción sería **establecer tus propias credenciales** y usarlas:
|
||||
```bash
|
||||
az webapp deployment user set \
|
||||
--user-name hacktricks \
|
||||
@@ -250,7 +250,7 @@ https://graph.microsoft.com/v1.0/me/drive/root/children
|
||||
```
|
||||
### Actualizar el código de la aplicación desde la fuente
|
||||
|
||||
- Si la fuente configurada es un proveedor de terceros como Github, BitBucket o un Repositorio de Azure, puedes **actualizar el código** del servicio de la aplicación comprometiendo el código fuente en el repositorio.
|
||||
- Si la fuente configurada es un proveedor de terceros como Github, BitBucket o un repositorio de Azure, puedes **actualizar el código** del servicio de la aplicación comprometiendo el código fuente en el repositorio.
|
||||
- Si la aplicación está configurada utilizando un **repositorio git remoto** (con nombre de usuario y contraseña), es posible obtener la **URL y las credenciales de autenticación básica** para clonar y enviar cambios con:
|
||||
- Usando el permiso **`Microsoft.Web/sites/sourcecontrols/read`**: `az webapp deployment source show --name <app-name> --resource-group <res-group>`
|
||||
- Usando el permiso **`Microsoft.Web/sites/config/list/action`**:
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## Información Básica
|
||||
|
||||
**Azure Function Apps** son un **servicio de computación sin servidor** que te permite ejecutar pequeñas piezas de código, llamadas **funciones**, sin gestionar la infraestructura subyacente. Están diseñadas para ejecutar código en respuesta a varios desencadenantes, como **solicitudes HTTP, temporizadores o eventos de otros servicios de Azure** como Blob Storage o Event Hubs. Las Function Apps admiten múltiples lenguajes de programación, incluidos C#, Python, JavaScript y Java, lo que las hace versátiles para construir **aplicaciones impulsadas por eventos**, automatizar flujos de trabajo o integrar servicios. Son rentables, ya que generalmente solo pagas por el tiempo de computación utilizado cuando se ejecuta tu código.
|
||||
**Azure Function Apps** son un **servicio de computación sin servidor** que te permite ejecutar pequeñas piezas de código, llamadas **funciones**, sin gestionar la infraestructura subyacente. Están diseñadas para ejecutar código en respuesta a varios desencadenadores, como **solicitudes HTTP, temporizadores o eventos de otros servicios de Azure** como Blob Storage o Event Hubs. Las Function Apps admiten múltiples lenguajes de programación, incluidos C#, Python, JavaScript y Java, lo que las hace versátiles para construir **aplicaciones impulsadas por eventos**, automatizar flujos de trabajo o integrar servicios. Son rentables, ya que generalmente solo pagas por el tiempo de computación utilizado cuando se ejecuta tu código.
|
||||
|
||||
> [!NOTE]
|
||||
> Ten en cuenta que **Functions son un subconjunto de los App Services**, por lo tanto, muchas de las características discutidas aquí también serán utilizadas por aplicaciones creadas como Azure Apps (`webapp` en cli).
|
||||
@@ -12,10 +12,10 @@
|
||||
### Diferentes Planes
|
||||
|
||||
- **Flex Consumption Plan**: Ofrece **escalado dinámico impulsado por eventos** con precios de pago por uso, añadiendo o eliminando instancias de función según la demanda. Soporta **redes virtuales** y **instancias pre-provisionadas** para reducir los inicios en frío, lo que lo hace adecuado para **cargas de trabajo variables** que no requieren soporte de contenedores.
|
||||
- **Traditional Consumption Plan**: La opción sin servidor predeterminada, donde **solo pagas por los recursos de computación cuando se ejecutan las funciones**. Escala automáticamente según los eventos entrantes e incluye **optimizaciones de inicio en frío**, pero no admite implementaciones de contenedores. Ideal para **cargas de trabajo intermitentes** que requieren escalado automático.
|
||||
- **Premium Plan**: Diseñado para **rendimiento consistente**, con **trabajadores precalentados** para eliminar los inicios en frío. Ofrece **tiempos de ejecución extendidos, redes virtuales**, y soporta **imágenes de Linux personalizadas**, lo que lo hace perfecto para **aplicaciones críticas** que necesitan alto rendimiento y características avanzadas.
|
||||
- **Traditional Consumption Plan**: La opción sin servidor predeterminada, donde **solo pagas por los recursos de computación cuando se ejecutan las funciones**. Escala automáticamente según los eventos entrantes e incluye **optimización de inicios en frío**, pero no admite implementaciones de contenedores. Ideal para **cargas de trabajo intermitentes** que requieren escalado automático.
|
||||
- **Premium Plan**: Diseñado para **rendimiento consistente**, con **trabajadores precalentados** para eliminar los inicios en frío. Ofrece **tiempos de ejecución extendidos, redes virtuales**, y soporta **imágenes personalizadas de Linux**, lo que lo hace perfecto para **aplicaciones críticas** que necesitan alto rendimiento y características avanzadas.
|
||||
- **Dedicated Plan**: Se ejecuta en máquinas virtuales dedicadas con **facturación predecible** y soporta escalado manual o automático. Permite ejecutar múltiples aplicaciones en el mismo plan, proporciona **aislamiento de computación**, y asegura **acceso seguro a la red** a través de App Service Environments, lo que lo hace ideal para **aplicaciones de larga duración** que necesitan asignación de recursos consistente.
|
||||
- **Container Apps**: Permite desplegar **aplicaciones de función en contenedores** en un entorno gestionado, junto con microservicios y APIs. Soporta bibliotecas personalizadas, migración de aplicaciones heredadas, y **procesamiento GPU**, eliminando la gestión de clústeres de Kubernetes. Ideal para **aplicaciones escalables en contenedores impulsadas por eventos**.
|
||||
- **Container Apps**: Permite desplegar **aplicaciones de función en contenedores** en un entorno gestionado, junto con microservicios y APIs. Soporta bibliotecas personalizadas, migración de aplicaciones heredadas, y **procesamiento GPU**, eliminando la gestión del clúster de Kubernetes. Ideal para **aplicaciones escalables en contenedores impulsadas por eventos**.
|
||||
|
||||
### **Buckets de Almacenamiento**
|
||||
|
||||
@@ -30,7 +30,7 @@ Además, al modificar el código dentro del bucket (en los diferentes formatos e
|
||||
|
||||
También es posible encontrar las **claves maestra y de funciones** almacenadas en la cuenta de almacenamiento en el contenedor **`azure-webjobs-secrets`** dentro de la carpeta **`<app-name>`** en los archivos JSON que puedes encontrar dentro.
|
||||
|
||||
Ten en cuenta que las Functions también permiten almacenar el código en una ubicación remota simplemente indicando la URL.
|
||||
Ten en cuenta que las Functions también permiten almacenar el código en una ubicación remota simplemente indicando la URL a la misma.
|
||||
|
||||
### Networking
|
||||
|
||||
@@ -56,12 +56,12 @@ En una **función de Windows** usando NodeJS, el código se encontraba en **`C:\
|
||||
|
||||
### **Identidades Gestionadas & Metadatos**
|
||||
|
||||
Al igual que [**VMs**](vms/), las Functions pueden tener **Identidades Gestionadas** de 2 tipos: Asignadas por el sistema y Asignadas por el usuario.
|
||||
Al igual que [**VMs**](vms/index.html), las Functions pueden tener **Identidades Gestionadas** de 2 tipos: Asignadas por el sistema y Asignadas por el usuario.
|
||||
|
||||
La **asignada por el sistema** será una identidad gestionada que **solo la función** que la tiene asignada podrá usar, mientras que las identidades gestionadas **asignadas por el usuario** son identidades gestionadas que **cualquier otro servicio de Azure podrá usar**.
|
||||
|
||||
> [!NOTE]
|
||||
> Al igual que en [**VMs**](vms/), las Functions pueden tener **1 identidad gestionada asignada por el sistema** y **varias asignadas por el usuario**, por lo que siempre es importante intentar encontrar todas ellas si comprometes la función porque podrías ser capaz de escalar privilegios a varias identidades gestionadas desde solo una Function.
|
||||
> Al igual que en [**VMs**](vms/index.html), las Functions pueden tener **1 identidad gestionada asignada por el sistema** y **varias asignadas por el usuario**, por lo que siempre es importante intentar encontrar todas ellas si comprometes la función porque podrías ser capaz de escalar privilegios a varias identidades gestionadas desde solo una Function.
|
||||
>
|
||||
> Si no se usa una identidad gestionada por el sistema pero una o más identidades gestionadas por el usuario están adjuntas a una función, por defecto no podrás obtener ningún token.
|
||||
|
||||
@@ -99,12 +99,12 @@ Al crear un endpoint dentro de una función usando un **desencadenador HTTP**, e
|
||||
Al igual que en App Services, las Functions también admiten autenticación básica para conectarse a **SCM** y **FTP** para desplegar código usando un **nombre de usuario y contraseña en una URL** proporcionada por Azure. Más información al respecto en:
|
||||
|
||||
{{#ref}}
|
||||
az-app-service.md
|
||||
az-app-services.md
|
||||
{{#endref}}
|
||||
|
||||
### Despliegues Basados en Github
|
||||
### Implementaciones Basadas en Github
|
||||
|
||||
Cuando se genera una función desde un repositorio de Github, la consola web de Azure permite **crear automáticamente un flujo de trabajo de Github en un repositorio específico** para que cada vez que se actualice este repositorio, se actualice el código de la función. De hecho, el yaml de Github Action para una función de python se ve así:
|
||||
Cuando se genera una función a partir de un repositorio de Github, la consola web de Azure permite **crear automáticamente un flujo de trabajo de Github en un repositorio específico** para que cada vez que se actualice este repositorio, se actualice el código de la función. De hecho, el yaml de Github Action para una función de python se ve así:
|
||||
|
||||
<details>
|
||||
|
||||
@@ -201,7 +201,7 @@ Además, se crea una **Identidad Administrada** para que la Acción de Github de
|
||||
|
||||
No todos los planes permiten desplegar contenedores, pero para aquellos que sí, la configuración contendrá la URL del contenedor. En la API, la configuración **`linuxFxVersion`** tendrá algo como: `DOCKER|mcr.microsoft.com/...`, mientras que en la consola web, la configuración mostrará los **ajustes de imagen**.
|
||||
|
||||
Además, **no se almacenará código fuente en la cuenta de almacenamiento** relacionada con la función, ya que no es necesario.
|
||||
Además, **no se almacenará código fuente en la** cuenta de almacenamiento relacionada con la función, ya que no es necesario.
|
||||
|
||||
## Enumeración
|
||||
```bash
|
||||
|
||||
Reference in New Issue
Block a user