¿Qué es la ejecución de tuberías envenenadas (EPP)?

La ejecución de canalizaciones envenenadas (PPE), un riesgo de seguridad de CI/CD de OWASP, es un vector de ataque que abusa de los permisos de acceso a un sistema de gestión de código fuente (SCM) con la intención de hacer que una canalización de CI ejecute comandos maliciosos. Aunque los atacantes PPE no tienen acceso al entorno de compilación, sí han obtenido acceso al SCM, lo que les permite inyectar código malicioso en la configuración del canal de compilación para manipular el proceso de compilación.

 

CICD-SEC-4: Explicación de la ejecución de la tubería envenenada

La ejecución de canalizaciones envenenadas (PPE), incluida como CICD-SEC-4 en los 10 principales riesgos de seguridad de CI/CD de OWASP, representa una sofisticada estrategia de ataque dirigida a los sistemas de integración continua e implementación continua (CI/CD).

Los clientes pueden disponer de diversas opciones:

En la estrategia PPE, los atacantes ejecutan código malicioso dentro de la parte CI del CI/CD pipeline, obviando la necesidad de acceder directamente al sistema CI/CD. El método consiste en manipular los permisos de un repositorio de gestión de código fuente (SCM). Al alterar los archivos de configuración de CI u otros archivos de los que depende el trabajo de la tubería CI, los atacantes inyectan comandos maliciosos, envenenando efectivamente la tubería CI y permitiendo la ejecución no autorizada de código.

Los ataques PPE exitosos pueden permitir una amplia gama de operaciones, todas ellas ejecutadas en el contexto de la identidad del oleoducto. Las operaciones maliciosas pueden incluir el acceso a secretos disponibles para el trabajo de IC, la obtención de acceso a activos externos para los que el nodo de trabajo tiene permisos, el envío de código y artefactos aparentemente legítimos a través de la canalización y el acceso a hosts y activos adicionales en la red o el entorno del nodo de trabajo.

Dado su impacto crítico, su baja detectabilidad y la existencia de múltiples técnicas de explotación, el ataque PPE supone una amenaza generalizada. Para los equipos de seguridad, los ingenieros y los miembros del equipo rojo, comprender los EPI y sus contramedidas es fundamental para la seguridad de la IC/CD.

Ejecución de la tubería definida

En el contexto de la integración continua (IC), el flujo de ejecución de la canalización se refiere a la secuencia de operaciones definida por el archivo de configuración de IC alojado en el repositorio que construye la canalización. Este archivo describe el orden de ejecución de los trabajos, además de detallar los ajustes del entorno de compilación y las condiciones que afectan al flujo. Cuando se activa, el trabajo de canalización extrae el código de la fuente elegida (por ejemplo, commit/branch) y ejecuta los comandos especificados en el archivo de configuración de CI contra ese código.

Los comandos de la canalización son invocados directamente por el archivo de configuración de CI o indirectamente por un script, una prueba de código o un linter que reside en un archivo separado al que se hace referencia desde el archivo de configuración de CI. Los archivos de configuración de CI suelen tener nombres y formatos coherentes, como Jenkinsfile (Jenkins), .gitlab-ci.yml (GitLab), .circleci/config.yml (CircleCI), y los archivos YAML de Acciones de GitHub ubicados en .github/workflows.

Los atacantes pueden explotar la capacidad de manipular los comandos ejecutados por la tubería, ya sea directa o indirectamente, pueden ser explotados por los atacantes para ejecutar código malicioso en la IC.

Cómo se produce la explotación del CICD-SEC-4

Para que un ataque PPE tenga éxito, deben cumplirse varios criterios:

  1. El atacante debe obtener permisos contra un repositorio SCM. Esto podría ser a través de credenciales de usuario, tokens de acceso, claves SSH, tokens OAuth u otros métodos. En algunos casos, el acceso anónimo a un repositorio público puede ser suficiente.
  2. Los cambios en el repositorio en cuestión deben activar una canalización CI sin aprobaciones ni revisiones adicionales. Esto podría ser a través de empujes directos a ramas remotas o a través de cambios sugeridos a través de un pull request de una rama o bifurcación remota.
  3. Los permisos obtenidos por el atacante deben permitir desencadenar los eventos que provocan la ejecución de la tubería.
  4. Los archivos que el atacante puede modificar deben definir los comandos que son ejecutados (directa o indirectamente) por la tubería.
  5. El nodo de canalización debe tener acceso a recursos no públicos, como secretos, otros nodos o recursos informáticos.

Los pipelines que ejecutan código no revisado, como los desencadenados por pull requests o commits a ramas arbitrarias del repositorio, son más susceptibles a los PPE. Una vez que un atacante puede ejecutar código malicioso dentro de la tubería de IC, puede llevar a cabo operaciones maliciosas en el contexto de la identidad de la tubería.

Tres tipos de ejecución de tuberías envenenadas

La ejecución de tuberías envenenadas se manifiesta de tres formas distintas: PPE directa (D-PPE), PPE indirecta (I-PPE) y PPE pública (3PE).

EPI directo

En un escenario de PPE directa, los atacantes modifican el archivo de configuración de CI en un repositorio al que tienen acceso, ya sea empujando el cambio directamente a una rama remota desprotegida en el repositorio o enviando un pull request con el cambio desde una rama o fork. La ejecución de la tubería se desencadena por los eventos de solicitud push o pull, tal y como se definen por los comandos en el archivo de configuración de CI modificado, lo que resulta en la ejecución de los comandos maliciosos en el nodo de compilación una vez que se desencadena la tubería de compilación.

Flujo de ataque de ejecución directa de tuberías envenenadas

Figura 1: Flujo de ataque de ejecución directa de tuberías envenenadas

El ejemplo de ataque D-PPE ilustrado en la figura 1 se desarrolla en la siguiente sucesión de pasos:

  1. Un adversario inicia una nueva rama remota dentro del repositorio, alterando el archivo de configuración de la tubería con instrucciones dañinas para recuperar las credenciales de AWS almacenadas dentro de la organización de GitHub y transmitirlas a un servidor externo bajo el control del atacante.
  2. El empuje de código activa una canalización que extrae el código, incluido el archivo de configuración de la canalización maliciosa, del repositorio.
  3. La tubería funciona según el archivo de configuración, ahora contaminado por el atacante. Las instrucciones maliciosas ordenan cargar en memoria las credenciales de AWS, almacenadas como secretos de repositorio.
  4. Siguiendo las instrucciones del atacante, la tubería lleva a cabo la tarea de transmitir las credenciales de AWS a un servidor bajo el control del atacante.
  5. En posesión de las credenciales robadas, el atacante adquiere la capacidad de infiltrarse en el entorno de producción.

EPI indirecto

La PPE indirecta se produce cuando la posibilidad de D-PPE no está disponible para un adversario con acceso a un repositorio SCM:

  • Si la canalización está configurada para extraer el archivo de configuración CI de una rama separada y protegida en el mismo repositorio.
  • Si el archivo de configuración de CI se almacena en un repositorio separado del código fuente, sin la opción de que un usuario pueda editarlo directamente.
  • Si la compilación CI se define en el propio sistema CI, en lugar de en un archivo almacenado en el código fuente.

En estos escenarios, el atacante aún puede envenenar la canalización inyectando código malicioso en archivos referenciados por el archivo de configuración de la canalización, como scripts referenciados desde dentro del archivo de configuración de la canalización, pruebas de código o herramientas automáticas como linters y escáneres de seguridad utilizados en el CI. Por ejemplo:

  • La utilidad make ejecuta los comandos definidos en el archivo Makefile.
  • Scripts referenciados desde dentro del archivo de configuración de la tubería, que se almacenan en el mismo repositorio que el propio código fuente (por ejemplo, python myscript.py - donde myscript.py sería manipulado por el atacante).
  • Pruebas de código: Los marcos de pruebas que se ejecutan sobre el código de la aplicación dentro del proceso de compilación dependen de archivos dedicados, almacenados en el mismo repositorio que el código fuente. Los atacantes que puedan manipular el código responsable de las pruebas podrán entonces ejecutar comandos maliciosos dentro de la compilación.
  • Herramientas automáticas: Los linters y los escáneres de seguridad utilizados en la IC suelen basarse en un archivo de configuración que reside en el repositorio y que normalmente carga y ejecuta código externo desde una ubicación definida dentro del archivo de configuración.

En lugar de envenenar la tubería mediante un EPP directo, el atacante que lanza un ataque EPP indirecto inyecta código malicioso en los archivos a los que hace referencia el archivo de configuración. El código malicioso se ejecuta finalmente en el nodo pipeline y ejecuta los comandos declarados en los archivos.

Flujo de ataque de ejecución indirecta de tuberías envenenadas

Figura 2: Flujo de ataque de ejecución indirecta de tuberías envenenadas

En este ejemplo de ataque I-PPE, la cadena de acontecimientos se desarrolla del siguiente modo:

  1. Un atacante crea una pull request en el repositorio, anexando comandos maliciosos al archivo Makefile.
  2. Dado que el pipeline está configurado para dispararse en cualquier PR contra el repositorio, el pipeline Jenkins se dispara, obteniendo el código del repositorio - incluyendo el Makefile malicioso.
  3. La tubería se ejecuta basándose en el archivo de configuración almacenado en la rama principal. Llega a la fase de compilación y carga las credenciales de AWS en variables de entorno, tal y como se definieron en el Jenkinsfile original. A continuación, ejecuta el comando make build, que ejecuta el comando malicioso que se añadió en Makefile.
  4. La función de compilación maliciosa definida en el Makefile se ejecuta, enviando las credenciales de AWS a un servidor controlado por el atacante.
  5. El atacante puede entonces utilizar las credenciales robadas para acceder al entorno de producción de AWS.

EPI público

El EPP público es un tipo de ataque EPP ejecutado por atacantes anónimos en Internet. Los repositorios públicos suelen permitir que cualquier usuario contribuya, normalmente creando pull requests. Si la tubería CI de un repositorio público ejecuta código no revisado sugerido por usuarios anónimos, es susceptible de sufrir un ataque PPE público. El EPP público también puede exponer activos internos, como secretos de proyectos privados, en los casos en los que la tubería del repositorio público vulnerable se ejecute en la misma instancia de IC que las privadas.

 

Importancia de la ejecución segura de canalizaciones en CI/CD

La ejecución de código malicioso no revisado en el CI a través de un ataque PPE exitoso proporciona a los atacantes el mismo nivel de acceso y capacidad que el trabajo de compilación:

  • Acceso a secretos disponibles para el trabajo CI, como secretos inyectados como variables de entorno o secretos adicionales almacenados en el CI. Al ser responsables de construir código e implementar artefactos, los sistemas CI/CD suelen contener docenas de credenciales y tokens de alto valor, como a un proveedor en la nube, a registros de artefactos y al propio SCM.
  • Acceso a activos externos sobre los que el nodo de trabajo tiene permisos, como archivos almacenados en el sistema de archivos del nodo, o credenciales a un entorno de nube accesible a través del host subyacente.
  • Capacidad para enviar código y artefactos más adelante en el pipeline, bajo la apariencia de código legítimo construido por el proceso de construcción.
  • Capacidad para acceder a hosts y activos adicionales en la red/entorno del nodo de trabajo.

Pero las organizaciones pueden salvaguardar sus productos de software y su infraestructura con una ejecución de canalización segura que garantice que todo el código compilado, probado e implementado es legítimo y no ha sido manipulado.

Riesgos asociados a la ejecución de tuberías envenenadas

Las implicaciones de la PPE pueden ser graves, desde el acceso no autorizado a los datos, la integridad comprometida del software, las interrupciones del sistema, hasta la violación de datos o incluso la toma total del sistema. Estos riesgos suponen amenazas significativas tanto para la empresa como para sus clientes, lo que subraya la gravedad de los EPI.

Impacto descendente de un conducto de IC envenenado

Figura 3: Impacto descendente de un conducto de IC envenenado

En la operación de compromiso de la cadena de suministro de ocho pasos que se ve en la figura 3, el atacante obtiene acceso a la tubería de IC y envenena los componentes de la aplicación SaaS. A través del componente envenenado, el atacante construye una funcionalidad de puerta trasera en la aplicación y envía los plugins envenenados a los clientes descendentes. Como es probable que las organizaciones posteriores perciban el paquete envenenado como legítimo, lo incorporan a su infraestructura en la nube o in situ.

A partir de una tubería de IC envenenada, el atacante logra un daño colateral exponencial, habiendo creado un acceso de puerta trasera a innumerables organizaciones. Este fue el caso del ataque SolarWinds.

LEA MÁS: Anatomía de un ataque a un canal de CI/CD

 

Prevención de la ejecución de tuberías envenenadas

Prevenir y mitigar el vector de ataque PPE implica múltiples medidas que abarcan tanto los sistemas SCM como los CI:

  • Asegúrese de que los pipelines que ejecutan código no revisado se ejecutan en nodos aislados frente a los expuestos a secretos y entornos sensibles.
  • Evalúe la necesidad de activar canalizaciones en repositorios públicos de contribuidores externos. Cuando sea posible, absténgase de ejecutar canalizaciones que se originen en bifurcaciones y considere la posibilidad de añadir controles como exigir la aprobación manual para la ejecución de canalizaciones.
  • Para las canalizaciones sensibles, por ejemplo las que están expuestas a secretos, asegúrese de que cada rama que esté configurada para activar una canalización en el sistema CI tenga una regla de protección de rama correlativa en el SCM.
  • Para evitar la manipulación del archivo de configuración CI para ejecutar código malicioso en la canalización, cada archivo de configuración CI debe ser revisado antes de que se ejecute la canalización. Alternativamente, el archivo de configuración CI puede gestionarse en una rama remota, separada de la rama que contiene el código que se está construyendo en el pipeline. La sucursal remota debe configurarse como protegida.
  • Elimine los permisos concedidos en el repositorio SCM a los usuarios que no los necesiten.
  • Cada canalización sólo debe tener acceso a las credenciales que necesita para cumplir su propósito. Las credenciales deben tener los privilegios mínimos requeridos.

 

Preguntas frecuentes sobre la ejecución de tuberías envenenadas

Un servidor de compilación es una máquina en la que se lleva a cabo el proceso de compilación de un proyecto. Compila el código fuente en código ejecutable.
Un entorno de ensayo es una réplica del entorno de producción utilizado para las pruebas. Ayuda a detectar posibles errores o problemas antes de que afecten al usuario final.
Un linter es una herramienta que analiza el código fuente para señalar errores de programación, fallos, errores estilísticos y construcciones sospechosas. Si el linter detecta problemas, la canalización puede configurarse para que falle, impidiendo que el código pase a la siguiente fase. Esto ayuda a las organizaciones a implementar únicamente el código que cumple las normas de calidad definidas.
La implementación azul/verde es una estrategia de gestión de lanzamientos que reduce el tiempo de inactividad y el riesgo mediante la ejecución de dos entornos de producción idénticos, denominados azul y verde. En cualquier momento, sólo uno está en vivo, con el entorno en vivo sirviendo a todo el tráfico de producción.
Una reversión es el proceso de volver a la versión anterior de una aplicación informática si la nueva versión presenta problemas. Es una medida de seguridad que garantiza la estabilidad del sistema en caso de implementaciones problemáticas.
Una prueba de humo, también conocida como prueba de verificación de compilación, es un tipo de prueba de software que comprende un conjunto no exhaustivo de pruebas cuyo objetivo es garantizar que las funciones más importantes funcionan.
Un lanzamiento canario es una técnica para reducir el riesgo de introducir nuevas versiones de software en producción desplegando lentamente el cambio a un subconjunto de usuarios antes de desplegarlo a toda la infraestructura.
La infraestructura como código es el proceso de gestión y aprovisionamiento de centros de datos informáticos mediante archivos de definición legibles por máquina, en lugar de mediante la configuración física del hardware o herramientas de configuración interactivas.
La integración continua es una práctica de desarrollo en la que los desarrolladores fusionan regularmente sus cambios de código en un repositorio central, seguido de compilaciones y pruebas automatizadas.
La entrega continua es la práctica de automatizar todo el proceso de lanzamiento de software. Una vez superadas las pruebas automatizadas, los cambios en el código se implementan automáticamente en un entorno similar al de producción para su posterior comprobación y validación.
Una canalización de implementación es el camino que sigue un cambio de código desde el control de versiones hasta el entorno de producción. Implica etapas como la compilación, la prueba y la implementación.
Anterior ¿Qué es una configuración insegura del sistema?