Prowler: Análisis de seguridad en AWS

En este post, vamos a hablar de AWS y como mediante Prowler, podemos hacer un escaneo de una o varias cuentas de AWS y exportar los datos a AWS SecurityHub para tener una visibilidad global de una forma centralizada y gratuita (o casi).

Vamos por partes, Prowler es una herramienta OpenSource que analiza las cuentas de AWS y te saca un informe detallado de los recursos que no están bien configurados. Para esto, se basa en diferentes frameworks de seguridad como PCI-DSS, ISO27001, GDPR, HIPAA, CIS…
Es muy configurable y la información que reporta, lo hace de una manera clara e intuitiva junto con links a la documentación de AWS para poder aplicar los cambios (esto solo en el reporte HTML). Una de las partes buenas de esta herramienta, es que se integra con AWS Security Hub, de modo que los informes, se pueden exportar directamente para poder verlos aquí.

Y por dar mas detalle de AWS SecurityHub, es una herramienta de AWS que se encarga de integrar diferentes análisis ya sean de sus propias herramientas (WAF, Config, Firewall…) como de herramientas de terceros para tener todo centralizado. En el caso de herramientas de terceros, el coste de importar evidencias es gratuito hasta las 10k. A partir de ahí, tiene un precio de $0.00003/evidencia

Vamos al lio. Para la infraestructura de AWS, vamos a utilizar un entorno multi-account gestionado con una organización. Esto nos vale para que SecurityHub detecte automáticamente todas las cuentas y les habilite el SecurityHub de manera automática. Y la gestión de todo (o casi todo), se haga solo desde una sola cuenta. De este modo, se simplifica el proceso.

Como buena práctica, recomiendan que la cuenta Root de la organización, no sea el que administre el SecurityHub. Por eso, en este caso, el administrador, será la cuenta de security.

Una vez explicado esto, vamos a desplegarlo. Para eso, vamos a usar Terraform. Es bastante sencillo y simple. Lo único que hay que tener en cuenta, es que en la cuenta Root, hay que definir como administrador de SecurityHub a la cuenta de Security (Por que por defecto, el administrador es la cuenta root de la organización)

A continuación, pongo los permisos necesarios para desplegar SecurityHub en todas las cuentas

Permisos necesarios en la cuenta Root:

"securityhub:EnableOrganizationAdminAccount",
"securityhub:ListOrganizationAdminAccounts",
"securityhub:DisableOrganizationAdminAccount"

Permisos necesarios en la cuenta de Security:

"securityhub:EnableSecurityHub",
"securityhub:GetEnabledStandards",
"securityhub:DisableSecurityHub",
"securityhub:CreateMembers",
"securityhub:InviteMembers",
"securityhub:GetMembers",
"securityhub:DisassociateMembers",
"securityhub:DeleteMembers",
"securityhub:EnableOrganizationAdminAccount",
"securityhub:ListOrganizationAdminAccounts",
"securityhub:DisableOrganizationAdminAccount",
"securityhub:UpdateOrganizationConfiguration",
"securityhub:DescribeOrganizationConfiguration",
"securityhub:EnableImportFindingsForProduct",
"securityhub:ListEnabledProductsForImport",
"securityhub:DisableImportFindingsForProduct",

Permisos necesarios en todas las cuentas para poder habilitar la integración de prowler (esto es un poco tedioso, pero es la única forma que he encontrado de poder habilitarlo en el resto de las cuentas por Terraform. No se puede replicar automáticamente)

"securityhub:EnableImportFindingsForProduct",
"securityhub:ListEnabledProductsForImport",
"securityhub:DisableImportFindingsForProduct",

Y ahora, el código de SecurityHub. En este caso, se va a desplegar desde la cuenta de Security y habrá varios recursos que los desplegaremos en otras cuentas utilizando los providers pertinentes.

resource "aws_securityhub_account" "security" {
}

resource "aws_securityhub_organization_admin_account" "security" {
  provider         = aws.root
  admin_account_id = data.aws_caller_identity.current.account_id
}

resource "aws_securityhub_organization_configuration" "security" {
  auto_enable = true
}

data "aws_region" "current" {}

resource "aws_securityhub_product_subscription" "prowler" {
  depends_on  = [aws_securityhub_account.security]
  product_arn = "arn:aws:securityhub:${data.aws_region.current.name}::product/prowler/prowler"
}

Una vez aplicado esto, SecurityHub ya estará aplicado en todas las cuentas. Pero por defecto, todas las cuentas, vienen como Not Member por lo que hay que añadirlas. Para esto, se puede hacer por la consola web o desde terraform de la siguiente manera:

resource "aws_securityhub_member" "production" {
  depends_on = [aws_securityhub_account.security]
  account_id = "XXXXXXXXXXX"
  email      = ""
  invite     = true
}

Y con esto, la cuenta production estaría integrada. Habría que realizar esto con el resto de cuentas

Como hemos comentado antes, otra de las cosas malas, es que las integraciones no se replican automáticamente, por lo que hay que hacerlo en cada cuenta. Para esto, realizar los siguiente cambiando el proveedor a la cuenta correcta

resource "aws_securityhub_product_subscription" "prowler_production" {
  provider = aws.production
  depends_on  = [aws_securityhub_account.security]
  product_arn = "arn:aws:securityhub:${data.aws_region.current.name}::product/prowler/prowler"
}

Una vez hecho esto, SecurityHub ya estaría preparado en todas las cuentas para poder recibir los reportes de Prowler. Ahora queda configurar en cada cuenta un role que pueda asumir Prowler con los permisos y políticas correctas.

resource "aws_iam_role" "prowler_role" {
  name                = "prowler_role"
  assume_role_policy  = jsonencode({
    Version = "2012-10-17"
    Statement = [
        {
          Action   = [
            "sts:AssumeRole",
            "organizations:ListAccounts*",
            "organizations:ListTagsForResource",
            "securityhub:BatchImportFindings",
            "securityhub:GetFindings"
          ]
          Effect   = "Allow"
          Resource = "*"
        },
      ]
  })
  managed_policy_arns = [
    "arn:aws:iam::aws:policy/SecurityAudit",
    "arn:aws:iam::aws:policy/job-function/ViewOnlyAccess"
  ]
}

Y ahora solo quedaría ejecutar Prowler. Esto puede hacerse de diferentes modos, ya sea desde un job en cada cuenta, desde una operación en una cuenta centralizada, en un runner, fargate, cronjob…
En nuestro caso lo vamos a lanzar como operación desde una cuenta centralizada a través de gitlab runner.
Este sería el comando que se lanzaría

./prowler -b -q -r ${AWS_REGION} -f ${AWS_REGION} -M json-asff -S -A ${AWS_ACCOUNT_ID} -R prowler_role -O ${AWS_ACCOUNT_ID_ROOT}
  • -b: para que no aparezca el banner
  • -q: para que no muestre los checks success (de este modo, nos ahorramos enviar mas resultados al SecurityHub)
  • -r: para fijar la región de la API de AWS
  • -f: para filtrar por la región que nos interese
  • -M: para convertirlo en el formato aceptado por SecurityHub
  • – S: para enviárselo a SecurityHub
  • -A: el ID de la cuenta donde asumiremos el role
  • -R: el nombre del role que asumiremos
  • -O: la cuenta root de la organización (esto hará que nos muestre información extra)

Ejecutando esto, generará un análisis en cada una de las cuentas y reportará el resultado a su respectivo SecurityHub. Y se podrá gestionar todo desde la cuenta administrador, en este caso la de Security.

Como consejo, deshabilitar los perfiles standard de seguridad que están activados por defecto en todas las cuentas (esto hay que hacerlo manualmente). Y esto hará que genere mas métricas por lo que el coste aumentará.


Also published on Medium.

Leave a Reply

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *