Conceptos de seguridad
Jerarquía de recursos
Google Cloud usa una jerarquía de recursos que es similar, conceptualmente, a la de un sistema de archivos tradicional. Esto proporciona un flujo de trabajo lógico principal / secundario con puntos de conexión específicos para políticas y permisos.
En un nivel alto, se ve así:
Organization
--> Folders
--> Projects
--> Resourc
Una máquina virtual (denominada instancia informática) es un recurso. Un recurso reside en un proyecto, probablemente junto con otras instancias de cómputo, depósitos de almacenamiento, etc.
Roles de IAM
Hay tres tipos de roles en IAM:
- Funciones básicas / primitivas , que incluyen las funciones de propietario , editor y espectador que existían antes de la introducción de IAM.
- Roles predefinidos , que brindan acceso granular para un servicio específico y son administrados por Google Cloud. Hay muchos roles predefinidos, puedes verlos todos con los privilegios que tienen aquí .
- Roles personalizados , que brindan acceso granular de acuerdo con una lista de permisos especificada por el usuario.
Hay miles de permisos en GCP. Para comprobar si un rol tiene permisos, puede buscar el permiso aquí y ver qué roles lo tienen.
También puede buscar aquí roles predefinidos ofrecidos por cada producto.
Roles básicos
Nombre | Título | Permisos |
roles / lectura | Espectador | Permisos para acciones de solo lectura que no afectan el estado, como ver (pero no modificar) recursos o datos existentes. |
roles / editor | Editor | Todos los permisos de espectador , más los permisos para acciones que modifican el estado, como cambiar los recursos existentes. |
roles / propietario | Dueño | Todos los permisos de editor y los permisos para las siguientes acciones: – Administre roles y permisos para un proyecto y todos los recursos dentro del proyecto. – Configurar la facturación de un proyecto. |
Puedes probar el siguiente comando para enumerar específicamente las funciones asignadas a tu cuenta de servicio en todo el proyecto en el proyecto actual:
PROJECT=$(curl http://metadata.google.internal/computeMetadata/v1/project/project-id \
-H "Metadata-Flavor: Google" -s)
ACCOUNT=$(curl http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/email \
-H "Metadata-Flavor: Google" -s)
gcloud projects get-iam-policy $PROJECT \
--flatten="bindings[].members" \
--format='table(bindings.role)' \
--filter="bindings.members:$ACCOUNT"
No se preocupe demasiado si se le niega el acceso al comando anterior. Todavía es posible averiguar qué puede hacer simplemente intentando hacerlo.
De manera más general, puede acortar el comando a lo siguiente para tener una idea de los roles asignados en todo el proyecto a todos los miembros .
gcloud projects get-iam-policy [PROJECT-ID]
O para ver la política de IAM asignada a una sola instancia de cómputo , puede intentar lo siguiente.
gcloud compute instances get-iam-policy [INSTANCE] --zone [ZONE]
Cuentas de servicio
A las instancias de máquinas virtuales se les suele asignar una cuenta de servicio . Cada proyecto de GCP tiene una cuenta de servicio predeterminada , y esta se asignará a nuevas instancias de Compute a menos que se especifique lo contrario. Los administradores pueden optar por utilizar una cuenta personalizada o ninguna. Esta cuenta de servicio puede ser utilizada por cualquier usuario o aplicación en la máquina para comunicarse con las API de Google. Puede ejecutar el siguiente comando para ver qué cuentas están disponibles:
gcloud auth list
Las cuentas de servicio predeterminadas se verán como una de las siguientes:
[email protected]
[email protected]
Una cuenta de servicio personalizada se verá así:
SERVICE_ACCOUNT_NAME@PROJECT_NAME.iam.gserviceaccount.com
Si gcloud auth list
devuelve varias cuentas disponibles , algo interesante está sucediendo. Por lo general, solo debería ver la cuenta de servicio. Si hay más de uno, puede recorrer cada uso gcloud config set account [CUENTA]
mientras prueba las distintas tareas de este blog.
Ámbitos de acceso
La cuenta de servicio en una instancia de GCP Compute usará OAuth para comunicarse con las API de Google Cloud. Cuando se utilizan alcances de acceso , el token de OAuth que se genera para la instancia tendrá una limitación de alcance incluida . Esto define en qué puntos finales de API se puede autenticar . No no define los permisos reales .
Cuando se usa una cuenta de servicio personalizada , Google recomienda que no se utilicen los alcances de acceso y confiar totalmente en IAM . El portal de administración web en realidad hace cumplir esto, pero los alcances de acceso aún se pueden aplicar a las instancias que usan cuentas de servicio personalizadas de manera programática.
Hay tres opciones al configurar un alcance de acceso en una instancia de VM:
- Permitir acceso predeterminado
- Todo el acceso completo a todas las API de la nube
- Establecer el acceso para cada API
Se puede ver lo que ámbitos se asigna por la consulta de la metadatos URL. A continuación, se muestra un ejemplo de una máquina virtual con acceso «predeterminado» asignado:
curl http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/scopes \
-H 'Metadata-Flavor:Google'
https://www.googleapis.com/auth/devstorage.read_only
https://www.googleapis.com/auth/logging.write
https://www.googleapis.com/auth/monitoring.write
https://www.googleapis.com/auth/servicecontrol
https://www.googleapis.com/auth/service.management.readonly
https://www.googleapis.com/auth/trace.append
Lo más interesante del alcance predeterminado es . Esto otorga acceso de lectura a todos los depósitos de almacenamiento del proyecto. Esto puede ser devastador, lo que, por supuesto, es genial para nosotros como atacantes. devstorage.read_only
Esto es lo que verá en una instancia sin limitaciones de alcance :
curl http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/scopes -H 'Metadata-Flavor:Google'
https://www.googleapis.com/auth/cloud-platform
Este cloud-platform
alcance es lo que realmente estamos esperando, ya que nos permitirá autenticarnos en cualquier función de la API y aprovechar todo el poder de nuestros permisos IAM asignados.
Es posible encontrar algunos conflictos al utilizar IAM y ámbitos de acceso . Por ejemplo, su cuenta de servicio puede tener el rol de IAM, compute.instanceAdmin
pero la instancia que ha violado se ha paralizado con la limitación de alcance de https://www.googleapis.com/auth/compute.readonly
. Esto evitaría que realice cambios con el token de OAuth que se asigna automáticamente a su instancia.
Credenciales por defecto
Token de cuenta de servicio predeterminado
El servidor de metadatos disponible para una instancia determinada proporcionará a cualquier usuario / proceso en esa instancia un token OAuth que se usa automáticamente como las credenciales predeterminadas cuando se comunica con las API de Google a través del gcloud
comando.
Puede recuperar e inspeccionar el token con el siguiente comando curl:
curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" \
-H "Metadata-Flavor: Google"
Que recibirá una respuesta como la siguiente:1
{
"access_token":"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_QtAS08i85nHq39HE3C2LTrCARA",
"expires_in":3599,
"token_type":"Bearer"
}
Este token es la combinación de la cuenta de servicio y los alcances de acceso asignados a la instancia de Compute. Por lo tanto, aunque su cuenta de servicio puede tener todos los privilegios de IAM imaginables, este token de OAuth en particular puede estar limitado en las API con las que puede comunicarse debido a los alcances de acceso .
Credenciales predeterminadas de la aplicación
Cuando se utiliza una de las bibliotecas cliente GCP oficiales de Google, el código buscará credenciales automáticamente siguiendo una estrategia llamada Credenciales predeterminadas de la aplicación .
1 .Primero, verificará el código fuente en sí . Los desarrolladores pueden optar por apuntar estáticamente a un archivo de clave de cuenta de servicio.
2 .La siguiente es una variable de entorno llamada . Esto se puede configurar para que apunte a un archivo de clave de cuenta de servicio .GOOGLE_APPLICATION_CREDENTIALS
3 .Finalmente, si no se proporciona ninguno de estos, la aplicación volverá a utilizar el token predeterminado proporcionado por el servidor de metadatos como se describe en la sección anterior.
Encontrar el archivo JSON real con las credenciales de la cuenta de servicio es generalmente mucho más deseable que confiar en el token OAuth en el servidor de metadatos. Esto se debe a que las credenciales de la cuenta de servicio sin procesar se pueden activar sin la carga de los alcances de acceso y sin el breve período de vencimiento que generalmente se aplica a los tokens.
Redes
Las instancias informáticas están conectadas a redes denominadas VPC o nubes privadas virtuales . Las reglas de firewall de GCP se definen en este nivel de red, pero se aplican individualmente a una instancia de Compute. Cada red, de forma predeterminada, tiene dos reglas de firewall implícitas : permitir la salida y denegar la entrada.
Cada proyecto de GCP se proporciona con una VPC llamada default
, que aplica las siguientes reglas a todas las instancias:
- default-allow-internal (permite todo el tráfico de otras instancias en la
default
red) - default-allow-ssh (permite 22 desde todas partes)
- default-allow-rdp (permite 3389 desde cualquier lugar)
- default-allow-icmp (permite hacer ping desde cualquier lugar)
Conoce a los vecinos
Las reglas de firewall pueden ser más permisivas para las direcciones IP internas. Esto es especialmente cierto para la VPC predeterminada, que permite todo el tráfico entre instancias de Compute.
Puede obtener una buena vista legible de todas las subredes en el proyecto actual con el siguiente comando:
gcloud compute networks subnets list
Y una descripción general de todas las direcciones IP internas / externas de las instancias de cómputo utilizando lo siguiente:1
gcloud compute instances list
Si te vuelves loco con nmap desde una instancia de Compute, Google lo notará y probablemente enviará un correo electrónico de alerta al propietario del proyecto. Es más probable que esto suceda si está escaneando direcciones IP públicas fuera de su proyecto actual. Ve con cuidado.
Enumeración de puertos públicos
Quizás no ha podido aprovechar su acceso actual para moverse a través del proyecto internamente, pero TIENE acceso de lectura a la API de cálculo. Vale la pena enumerar todas las instancias con puertos de firewall abiertos al mundo; es posible que encuentre una aplicación insegura para violar y esperar que aterrice en una posición más poderosa.
En la sección anterior, ha reunido una lista de todas las direcciones IP públicas. Puede ejecutar nmap contra todos ellos, pero esto puede llevar años y podría bloquear su IP de origen.
Al atacar desde Internet, las reglas predeterminadas no proporcionan ganancias rápidas en máquinas configuradas correctamente. Vale la pena verificar la autenticación de contraseña en SSH y contraseñas débiles en RDP, por supuesto, pero eso es un hecho.
Lo que realmente nos interesa son otras reglas de firewall que se han aplicado intencionalmente a una instancia. Si tenemos suerte, tropezaremos con una aplicación insegura, una interfaz de administración con una contraseña predeterminada o cualquier otra cosa que podamos aprovechar.
Las reglas del cortafuegos se pueden aplicar a los casos a través de los métodos siguientes:
- las etiquetas de redes
- Las cuentas de servicio
- Todas las instancias dentro de una VPC
Desafortunadamente, no existe un comando simple gcloud
para escupir todas las instancias de cómputo con puertos abiertos en Internet. Debe conectar los puntos entre las reglas de firewall, las etiquetas de red, las cuentas de servicios y las instancias.Hemos automatizado esto completamente usando este script de Python que exportará lo siguiente:
- Archivo CSV que muestra instancia, IP pública, TCP permitido, UDP permitido
- escaneo de nmap para apuntar a todas las instancias en puertos de entrada permitidos desde la Internet pública (0.0.0.0/0)
- masscan para apuntar al rango TCP completo de aquellas instancias que permiten TODOS los puertos TCP desde la Internet pública (0.0.0.0/0)
Enumeración
Herramientas automáticas
- https://gitlab.com/gitlab-com/gl-security/security-operations/gl-redteam/gcp_enum: Bash script para enumerar un entorno GCP utilizando CLI gcloud y guardar los resultados
- https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation: Secuencias de comandos para enumerar los privilegios elevados de IAM y para escalar privilegios en GCP abusar de ellos (no pude hacer que ejecute la secuencia de enumeración)
- https://github.com/lyft/cartography: Herramienta para enumerar y de impresión en un gráfico de los recursos y las relaciones de las diferentes plataformas en la nube
- https://github.com/RyanJarv/awesome-cloud-sec: Esta es una lista de herramientas de seguridad en la nube
Enumeración
Descripción | Comando |
Lista de roles | gcloud iam roles list --filter='etag:AA==' |
Obtener la descripción y los permisos de un rol | gcloud iam roles describe roles/container.admin |
Obtener la política iam de una organización | gcloud organizations get-iam-policy |
Obtener la política iam de un proyecto | gcloud projects get-iam-policy <project-id> |
Obtener la política iam de una carpeta | gcloud resource-manager folders get-iam-policy |
Obtener miembros de un grupo | gcloud identity groups memberships search-transitive-memberships [email protected] |
Obtener los permisos de un rol | gcloud iam roles describe roles/accessapproval.approver |
Permisos comprobables en un recurso | gcloud iam list-testable-permissions --filter "NOT apiDisabled: true |
Lista de roles que se pueden conceder para un recurso | gcloud iam list-grantable-roles <project URL> |
Lista de roles personalizados en un proyecto | gcloud iam roles list --project $PROJECT_ID |
Lista de cuentas de servicio | gcloud iam service-accounts list |
Ataques no autenticados
Listas de verificación de seguridad de GCP genéricas
Escalada de privilegios locales/Pivoting SSH
Supongamos que ha comprometido una VM en GCP, existen algunos privilegios de GCP que pueden permitirle escalar privilegios localmente, a otras máquinas y también pivotar a otras VM :GCP: escalamiento de privilegios locales / pivote SSH
Si ha encontrado alguna vulnerabilidad SSRF en un entorno de GCP, consulte esta página .
Escalada de privilegios en la nube
Permisos interesantes de GCP
La forma más común, una vez que ha obtenido algunas credenciales de nube, ha comprometido algún servicio que se ejecuta dentro de una nube, es abusar de los privilegios configurados incorrectamente que la cuenta comprometida pueda tener. Entonces, lo primero que debe hacer es enumerar sus privilegios.
Además, durante esta enumeración, recuerde que los permisos también se pueden establecer en el nivel más alto de «Organización» .GCP – Permisos interesantes
Omitir ámbitos de acceso
Cuando se utilizan alcances de acceso , el token de OAuth que se genera para la instancia informática (VM) tendrá una limitación de alcance incluida . Sin embargo, es posible que pueda evitar esta limitación y aprovechar los permisos que tiene la cuenta comprometida.
La mejor manera de eludir esta restricción es encontrar nuevas credenciales en el host comprometido, encontrar la clave de servicio para generar un token OUATH sin restricción o saltar a una VM diferente menos restringida .
Pop otra caja
Es posible que exista otra caja en el entorno con ámbitos de acceso menos restrictivos. Si puede ver el resultado de gcloud compute instances list --quiet --format=json
, busque instancias con el alcance específico que desea o el alcance con todo incluido.auth/cloud-platform
También esté atento a las instancias que tienen asignada la cuenta de servicio predeterminada ( [email protected]
).
Encuentra claves de cuenta de servicio
Google afirma muy claramente «Los alcances de acceso no son un mecanismo de seguridad … no tienen ningún efecto cuando se realizan solicitudes no autenticadas a través de OAuth» .
Por lo tanto, si encuentra una clave de cuenta de servicio almacenada en la instancia, puede omitir la limitación. Estas son claves privadas RSA que se pueden usar para autenticarse en la API de Google Cloud y solicitar un nuevo token OAuth sin limitaciones de alcance .
Verifique si alguna cuenta de servicio ha exportado una clave en algún momento con:
for i in $(gcloud iam service-accounts list --format="table[no-heading](email)"); do
echo Looking for keys for $i:
gcloud iam service-accounts keys list --iam-account $i
done
Estos archivos no se almacenan en una instancia de Compute de forma predeterminada , por lo que tendría que tener suerte de encontrarlos. El nombre predeterminado del archivo es [project-id]-[portion-of-key-id].json
. Por lo tanto, si el nombre de su proyecto es test-project
, puede buscar en el sistema de archivos este archivo clave.test-project*.json
El contenido del archivo se parece a esto:
{
"type": "service_account",
"project_id": "[PROJECT-ID]",
"private_key_id": "[KEY-ID]",
"private_key": "-----BEGIN PRIVATE KEY-----\n[PRIVATE-KEY]\n-----END PRIVATE KEY-----\n",
"client_email": "[SERVICE-ACCOUNT-EMAIL]",
"client_id": "[CLIENT-ID]",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://accounts.google.com/o/oauth2/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/[SERVICE-ACCOUNT-EMAIL]"
}
O, si se generan desde la CLI , se verán así:1
{
"name": "projects/[PROJECT-ID]/serviceAccounts/[SERVICE-ACCOUNT-EMAIL]/keys/[KEY-ID]",
"privateKeyType": "TYPE_GOOGLE_CREDENTIALS_FILE",
"privateKeyData": "[PRIVATE-KEY]",
"validAfterTime": "[DATE]",
"validBeforeTime": "[DATE]",
"keyAlgorithm": "KEY_ALG_RSA_2048"
}
Si encuentra uno de estos archivos, puede indicarle al comando que se vuelva a autenticar con esta cuenta de servicio. Puede hacer esto en la instancia o en cualquier máquina que tenga las herramientas instaladas.gcloud
gcloud auth activate-service-account --key-file [FILE]
Ahora puede probar su nuevo token de OAuth de la siguiente manera:1
TOKEN=`gcloud auth print-access-token`
curl https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=$TOKEN
Debería ver una https://www.googleapis.com/auth/cloud-platform
lista en los ámbitos, lo que significa que no está limitado por ningún ámbito de acceso a nivel de instancia . Ahora tiene todo el poder para usar todos sus permisos de IAM asignados.
Suplantación de la cuenta de servicio
Hacerse pasar por una cuenta de servicio puede ser muy útil para obtener nuevos y mejores privilegios .
Hay tres formas de hacerse pasar por otra cuenta de servicio :
- Autenticación usando claves privadas RSA (cubierto arriba )
- Autorización mediante políticas de Cloud IAM (tratadas aquí )
- Implementar trabajos en servicios de GCP (más aplicable al compromiso de una cuenta de usuario)
Otorgar acceso a la consola de administración
El acceso a la consola de administración de GCP se proporciona a las cuentas de usuario, no a las cuentas de servicio . Para iniciar sesión en la interfaz web, puede otorgar acceso a una cuenta de Google que usted controla. Esta puede ser una cuenta genérica » @ gmail.com «, no es necesario que sea miembro de la organización de destino .
Sin embargo, para otorgar la función primitiva de propietario a una cuenta genérica «@ gmail.com», deberá usar la consola web . gcloud
se producirá un error si intenta otorgarle un permiso por encima del Editor.
Puede utilizar el siguiente comando para otorgar a un usuario la función primitiva de Editor para su proyecto existente:
gcloud projects add-iam-policy-binding [PROJECT] --member user:[EMAIL] --role roles/editor
Si tuvo éxito aquí, intente acceder a la interfaz web y explorar desde allí.Este es el nivel más alto que puede asignar con la herramienta gcloud .
Difusión al espacio de trabajo mediante la delegación de autoridad en todo el dominio
Espacio de trabajo es c de Google plataforma OLABORACIÓN y productividad que consiste en cosas como Gmail, Google Calendar, Google Drive, Google Docs, etc.
A las cuentas de servicio en GCP se les pueden otorgar los derechos para acceder mediante programación a los datos del usuario en Workspace al hacerse pasar por usuarios legítimos. Esto se conoce como delegación de todo el dominio . Esto incluye acciones como leer correo electrónico en GMail, acceder a Google Docs e incluso crear nuevas cuentas de usuario en la organización de G Suite.
Workspace tiene su propia API , completamente independiente de GCP. Los permisos se otorgan al espacio de trabajo y no existe ninguna relación predeterminada entre GCP y el espacio de trabajo .
Sin embargo, es posible otorgar permisos a una cuenta de servicio sobre un usuario de Workspace. Si tiene acceso a la interfaz de usuario web en este momento, puede navegar a IAM -> Cuentas de servicio y ver si alguna de las cuentas tiene «Habilitado» en la columna «Delegación de todo el dominio» . Es posible que la columna en sí no aparezca si no hay cuentas habilitadas (puede leer los detalles de cada cuenta de servicio para confirmar esto). Al momento de escribir estas líneas, no hay forma de hacerlo programáticamente, aunque existe una solicitud para esta función en el rastreador de errores de Google.
Para crear esta relación es necesario habilitarla en GCP y también en Workforce .
Probar el acceso al espacio de trabajo
Para probar este acceso, necesitará las credenciales de la cuenta de servicio exportadas en JSON formato . Es posible que los haya adquirido en un paso anterior, o puede que tenga el acceso necesario ahora para crear una clave para una cuenta de servicio que sabe que tiene habilitada la delegación en todo el dominio.
Este tema es un poco complicado … su cuenta de servicio tiene algo llamado «client_email» que puede ver en el archivo de credenciales JSON que exporta. Probablemente se parezca a algo así [email protected]
. Si intenta acceder a las llamadas de la API de Workforce directamente con ese correo electrónico, incluso con la delegación habilitada, fallará. Esto se debe a que el directorio de Workforce no incluirá las direcciones de correo electrónico de la cuenta de servicio de GCP. En cambio, para interactuar con Workforce, necesitamos suplantarnos a usuarios válidos de Workforce.
Lo que realmente quiere hacer es hacerse pasar por un usuario con acceso administrativo y luego usar ese acceso para hacer algo como restablecer una contraseña, deshabilitar la autenticación multifactor o simplemente crearse una nueva y brillante cuenta de administrador.
Gitlab ha creado este script de Python que puede hacer dos cosas: enumerar el directorio de usuarios y crear una nueva cuenta administrativa. Así es como lo usaría:
# Validate access only
./gcp_delegation.py --keyfile ./credentials.json \
--impersonate [email protected] \
--domain target-org.com
# List the directory
./gcp_delegation.py --keyfile ./credentials.json \
--impersonate [email protected] \
--domain target-org.com \
--list
# Create a new admin account
./gcp_delegation.py --keyfile ./credentials.json \
--impersonate [email protected] \
--domain target-org.com \
--account pwned
Puede probar este script en una variedad de direcciones de correo electrónico para hacerse pasar por varios usuarios . La salida estándar indicará si la cuenta de servicio tiene acceso a Workforce e incluirá una contraseña aleatoria para la nueva cuenta de administrador, si se crea una.
Si tiene éxito al crear una nueva cuenta de administrador, puede iniciar sesión en la consola de administración de Google y tener control total sobre todo en G Suite para cada usuario: correo electrónico, documentos, calendario, etc. Vuélvase loco.
Referencias
https://github.com/cloudnative-security/hacking-kubernetes
https://www.elladodelmal.com/2019/01/hacking-kubernetes-auditoria-de.html