Laboratorio controlado de investigación y reproducción de vulnerabilidades para CVE-2020-14343 en PyYAML
Este proyecto demuestra CVE-2020-14343 en un entorno Docker controlado y aislado.
El laboratorio contiene dos entornos:
yaml.safe_load()El laboratorio demuestra el ciclo de vida completo de la vulnerabilidad:
La carga útil de reproducción utilizada en este laboratorio es intencionadamente inofensiva y solo imprime un marcador de prueba.
| Propiedad | Detalles |
|---|---|
| CVE | CVE-2020-14343 |
| Producto | PyYAML |
| Versiones afectadas | Versiones anteriores a 5.4 |
| Versión corregida | 5.4 |
| Tipo de vulnerabilidad | Validación incorrecta de entrada (CWE-20) |
| Gravedad | Crítica |
| Superficie de ataque | Entrada YAML procesada mediante funcionalidad de carga vulnerable |
| CVSS | 9.3 (CVSS v4, GitHub Advisory) |
La vulnerabilidad se produce cuando una entrada YAML no confiable se procesa mediante funcionalidad de carga vulnerable de PyYAML.
Las versiones de PyYAML anteriores a 5.4 permitían etiquetas YAML especialmente diseñadas, incluidas etiquetas específicas de Python como:
!!python/object/new
para alcanzar la funcionalidad de construcción de objetos cuando se utilizaba FullLoader.
Un documento YAML malicioso puede, por lo tanto, provocar la ejecución no intencionada de código Python.
El problema estaba relacionado con una corrección incompleta de una vulnerabilidad anterior de PyYAML.
PyYAML 5.4 corrigió CVE-2020-14343 moviendo las etiquetas Python arbitrarias a UnsafeLoader.
Para las aplicaciones que procesan YAML no confiable, este laboratorio también utiliza yaml.safe_load() como enfoque de carga seguro.
El laboratorio contiene dos servicios Docker aislados:
Host Machine
|
+------------+------------+
| |
v v
Vulnerable App Patched App
localhost:5000 localhost:5001
| |
PyYAML 5.3.1 PyYAML 5.4
FullLoader SafeLoader
| |
v v
Payload executes Payload rejected
| Servicio | Puerto del host | Puerto del contenedor | PyYAML | Propósito |
|---|---|---|---|---|
| vulnerable | 5000 | 5000 | 5.3.1 | Entorno vulnerable |
| patched | 5001 | 5000 | 5.4 | Entorno remediado |
cve-2020-14343-lab/
├── vulnerable/
│ ├── app.py
│ ├── Dockerfile
│ └── requirements.txt
├── patched/
│ ├── app.py
│ ├── Dockerfile
│ └── requirements.txt
├── exploit/
│ └── reproduce.py
├── detection/
│ └── detect.py
├── screenshots/
│ ├── 01-docker-compose-running.png
│ ├── 02-vulnerable-detection.png
│ ├── 03-patched-detection.png
│ ├── 04a-vulnerable-request.png
│ ├── 04b-vulnerable-execution-log.png
│ └── 05-patched-exploit-blocked.png
├── blog/
│ └── CVE-2020-14343-Technical-Blog.pdf
├── docker-compose.yml
├── README.md
└── .gitignore
| Archivo/Directorio | Propósito |
|---|---|
vulnerable/app.py | Aplicación Flask que utiliza carga de YAML vulnerable |
vulnerable/Dockerfile | Construye la imagen Docker vulnerable |
vulnerable/requirements.txt | Fija PyYAML en 5.3.1 |
patched/app.py | Aplicación Flask que utiliza carga de YAML segura |
patched/Dockerfile | Construye la imagen Docker parcheada |
patched/requirements.txt | Fija PyYAML en 5.4 |
exploit/reproduce.py | Reproduce la vulnerabilidad utilizando una carga útil controlada |
detection/detect.py | Comprueba la versión de PyYAML dentro de un contenedor Docker |
docker-compose.yml | Construye y ejecuta ambos entornos |
screenshots/ | Contiene las evidencias capturadas durante el laboratorio |
blog/ | Contiene el PDF del blog técnico de 800–1200 palabras |
Se requiere el siguiente software:
Docker Desktop debe estar en ejecución antes de iniciar el laboratorio.
La aplicación vulnerable está expuesta intencionalmente solo en la máquina local mediante los mapeos de puertos de Docker.
Desde el directorio raíz del proyecto, ejecute:
docker compose up --build -d
Ejecutar:
docker compose ps
Ambos servicios deberían mostrar Up.
Abrir:
http://127.0.0.1:5000
I'm ready to translate chunk 13, but the actual content to translate wasn't included in your message — only the instructions and the "INPUT:" label with nothing after it.
Please paste the Markdown content for chunk 13 and I'll return the Spanish translation following all the rules you specified.
{
"message": "CVE-2020-14343 vulnerable YAML parser"
}
Abrir:
http://127.0.0.1:5001
I'm ready to translate chunk 13, but the actual content to translate wasn't included in your message — only the instructions and the "INPUT:" label with nothing after it.
Please paste the Markdown content for chunk 13 and I'll return the Spanish translation following all the rules you specified.
{
"message": "CVE-2020-14343 patched YAML parser"
}
docker compose up -d
docker compose down
docker compose up --build -d
docker compose ps
docker logs cve-vulnerable
docker logs cve-patched
La aplicación vulnerable expone un endpoint /parse que acepta entrada YAML.
El entorno vulnerable utiliza:
yaml.FullLoaderEl script de reproducción se encuentra en:
exploit/reproduce.py
La aplicación vulnerable está disponible en:
http://127.0.0.1:5000/parse
Ejecutar:
python exploit/reproduce.py
El script envía una carga útil YAML controlada que contiene una etiqueta YAML específica de Python.
En el entorno vulnerable, la carga útil es aceptada y la aplicación devuelve una respuesta HTTP 200.
El marcador de prueba controlado:
CVE-2020-14343-TEST
se ejecuta dentro del contenedor de la aplicación vulnerable.
La ejecución se puede verificar usando:
docker logs cve-vulnerable
La salida esperada del registro incluye:
CVE-2020-14343-TEST
Esto demuestra la ejecución de código a través del comportamiento vulnerable de carga de YAML.
La carga útil de reproducción es intencionalmente inofensiva. Solo imprime un marcador de prueba y no modifica el sistema anfitrión, no accede a credenciales, no accede a datos sensibles, no interactúa con sistemas externos ni realiza acciones destructivas.
El script de detección se encuentra en: