Someone left the vault door unlocked, and the burglars brought a forklift
CVE-2025-10035 is a deserialization-to-command-injection chain in the License Servlet of Fortra GoAnywhere MFT — a managed file transfer gateway that enterprises deploy in the DMZ specifically to move sensitive data between business partners. All versions prior to 7.8.4 (standard release) and 7.6.3 (sustain release) are affected. The chain combines three issues: an authentication bypass on the License Servlet endpoint (known since 2023), hard-coded encryption keys that let an attacker recover session tokens offline, and the unsafe deserialization of attacker-controlled Java objects inside a SignedObject wrapper. The net result is unauthenticated remote code execution — full SYSTEM-level compromise of the MFT host from the internet.
Fortra rated this CVSS 10.0/CRITICAL, and for once the vendor score is exactly right. GoAnywhere MFT is *designed* to be internet-facing; its entire purpose is external file exchange. The auth bypass requires a single crafted GET request. The hard-coded keys are identical across all installations. Microsoft confirmed Storm-1175 was exploiting this as a zero-day starting September 10, 2025 — a full week before Fortra disclosed it on September 18 — dropping SimpleHelp and MeshAgent persistence tools and deploying Medusa ransomware within 24 hours of initial access. watchTowr Labs published a full PoC on September 24. CISA added it to KEV on September 29. The EPSS score of 0.998 puts it in the top 0.2% of all CVEs for exploitation probability. There is no legitimate reason to disagree with the vendor here.
6 steps from start to impact.
Locate exposed GoAnywhere admin/license endpoint
/goanywhere/ web path on ports 8000/8001 (admin console) or 443. Censys identified 740 internet-facing instances as of late September 2025. The License Servlet at /goanywhere/license/ is reachable on the same port as the admin console and does not require separate credentials.- Target GoAnywhere MFT instance is reachable from the internet on the admin console port
- Fortra advises restricting admin console to internal networks, but MFT appliances are internet-facing by design and many orgs expose the full web interface
Trigger authentication bypass via exception routing
/goanywhere/license/Unlicensed.xhtml/x with an invalid javax.faces.ViewState parameter and GARequestAction=activate. This triggers a JSF exception that routes to the AdminErrorHandlerServlet, which generates a valid license request token and attaches it to the attacker's HTTP session — no credentials required. The bypass has been possible since at least 2023 but was not publicly documented until watchTowr's analysis.- Reachable License Servlet endpoint
- GoAnywhere MFT version < 7.8.4 or sustain < 7.6.3
- A WAF with strict path-traversal rules might block the
/Unlicensed.xhtml/xsuffix, but this is a valid JSF path and most WAFs would pass it
/goanywhere/license/Unlicensed.xhtml/ with appended path segments and GARequestAction=activate parameter are strong indicators of exploitation attempts.Extract session token via hard-coded key decryption
bundle parameter. Because GoAnywhere uses hard-coded encryption keys identical across all installations, the attacker decrypts the bundle offline to extract the GUID session token. This token is required for the next stage and proves the attacker holds a valid session. watchTowr's PoC and the ThemeHackers GitHub repository both implement this decryption step.- Successful auth bypass from Step 2
- Knowledge of the hard-coded encryption key (published in PoC code)
- None — the key is static and publicly known post-PoC publication
.jsp files dropped post-exploitation.Deliver malicious serialized object to deserialization sink
/goanywhere/lic/accept/<GUID> with a crafted bundle parameter containing a malicious serialized Java object wrapped in a SignedObject. The LicenseResponseServlet.doPost() method passes this to BundleWorker.verify(), which calls SignedObject.getObject() — triggering unrestricted deserialization. Gadget chains such as CommonsBeanutils1 (present in GoAnywhere's classpath) convert the deserialization into arbitrary OS command execution. The signature verification against the baked-in public key is the one non-trivial step, but real-world exploitation by Storm-1175 proves it is solvable — possibly via private key compromise or an alternate code path.- Valid session GUID from Step 3
- Crafted serialized payload with appropriate gadget chain
- Ability to satisfy or bypass SignedObject signature verification
- The signature verification is the only technical friction point, but Storm-1175 demonstrated it is bypassable in production — the patch hardens deserialization but leaves signature logic untouched, suggesting the private key may have been compromised
/goanywhere/lic/accept/ paths. EDR on the MFT host should flag java.exe or the GoAnywhere process spawning unexpected child processes (cmd.exe, powershell.exe, bash).Achieve SYSTEM-level code execution and deploy persistence
.jsp webshells in GoAnywhere web directories, and performing system/user discovery. The MFT host's position in the DMZ with access to both external networks and internal file shares makes it an ideal pivot point.- Successful deserialization and command execution from Step 4
- EDR on the MFT host should detect RMM tool installation and webshell creation, but many MFT appliances run on hardened Linux without endpoint agents
.jsp files. Microsoft published specific IOCs including file hashes and C2 domains.Lateral movement and ransomware deployment
- SYSTEM-level access on MFT host
- Network connectivity to internal systems (standard for DMZ MFT)
- Network segmentation between DMZ and internal LAN should slow lateral movement, but MFT hosts require firewall rules to internal file stores and databases
The supporting signals.
| In-the-Wild Exploitation | Confirmed and active. Microsoft attributed exploitation to Storm-1175 starting September 10, 2025 — 8 days before public disclosure. Multiple organizations compromised with Medusa ransomware deployed within 24 hours of initial access. watchTowr Labs independently confirmed exploitation evidence from the same timeframe. |
|---|---|
| Proof-of-Concept | Public. watchTowr Labs published a detailed technical analysis and PoC on September 24, 2025. ThemeHackers/CVE-2025-10035 on GitHub provides a weaponized implementation. Multiple security vendors have published detection-oriented reproduction steps. |
| EPSS Score | 0.99799 — top 0.2 percentile. This is near the theoretical maximum, reflecting confirmed mass exploitation, public PoC availability, and trivial attack complexity. |
| CISA KEV Status | Listed September 29, 2025. Federal agencies subject to BOD 22-01 must remediate per CISA deadlines. Active exploitation confirmed prior to KEV listing. |
| CVSS Vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H — 10.0 Critical. Network-accessible, low complexity, no privileges or user interaction required, scope changed (attacker can pivot beyond the vulnerable component). Every metric is at maximum severity. |
| Affected Versions | All GoAnywhere MFT versions prior to 7.8.4 (standard release) and prior to 7.6.3 (sustain release). No version floor has been identified — the auth bypass predates 2023. |
| Fixed Versions | GoAnywhere MFT 7.8.4 (standard) and 7.6.3 (sustain). Patch hardens the deserialization routine with type restrictions but notably does not modify the signature verification logic. |
| Internet Exposure | Censys identified 740 internet-facing GoAnywhere MFT instances globally. Of the 65 reporting version numbers, 40 (~61%) run vulnerable versions. Actual vulnerable population is likely higher given 91% did not report versions. Fortra proactively contacted customers with exposed admin consoles. |
| Disclosure Timeline | Exploitation began ~Sept 10, 2025. Fortra disclosed and patched Sept 18, 2025. watchTowr PoC published Sept 24. CISA KEV added Sept 29. Microsoft attribution blog published Oct 6. |
| Reporting Researchers | Fortra internal discovery. Independent analysis by watchTowr Labs (Sean Yeoh, Orange Tsai), Rapid7 Labs, and Microsoft Threat Intelligence Center. Storm-1175 attribution by Microsoft MSTIC. |
Why this verdict
- Unauthenticated remote attack surface: The entire chain — from auth bypass through deserialization to SYSTEM-level command execution — requires zero credentials and zero user interaction. The attacker needs only network reachability to the GoAnywhere admin/license port, which is internet-exposed by design in the majority of MFT deployments.
- Confirmed zero-day exploitation with ransomware impact: Storm-1175 weaponized this vulnerability a full week before public disclosure, deploying Medusa ransomware within 24 hours of initial access. This is not theoretical — organizations have already been encrypted. The EPSS score of 0.998 and KEV listing confirm this is among the most actively exploited CVEs of 2025.
- Minimal friction in the attack chain: The auth bypass is a single GET request. The encryption keys are hard-coded and identical across all installations. The PoC is public and weaponized. The only non-trivial step (signature verification) has been demonstrably solved by threat actors in the wild. No step requires specialized tooling or insider knowledge post-PoC publication.
- Role multiplier: GoAnywhere MFT is canonically a network-edge, high-value-role component. MFT gateways sit in the DMZ bridging external partners and internal infrastructure. They hold SFTP keys, AD service account credentials, database connection strings, and sensitive files in transit. >90% of GoAnywhere deployments occupy this exact high-value network-edge role — it is the product's entire purpose. Blast radius is fleet-scale: the compromised MFT host provides direct pivot access to internal file shares, databases, and partner networks. Storm-1175 demonstrated domain-to-ransomware escalation within 24 hours. This firmly exceeds the CRITICAL floor.
- No meaningful friction downgrades apply: Unlike vulnerabilities requiring internal network access or authenticated sessions, this chain starts from the public internet against a product designed to be public-facing. WAF bypass is trivial (the path is valid JSF). The only population limiter is the ~740 internet-facing instances, but each instance protects an entire enterprise's file transfer infrastructure — the per-instance blast radius is enormous.
Why not higher?
CVSS 10.0 is the maximum possible score. The vendor has correctly assigned the ceiling. There is no higher severity to assign.
Why not lower?
Downgrading would require meaningful friction or a narrow blast radius, neither of which exists here. The product is internet-facing by design (no 'requires internal access' discount). The chain is fully unauthenticated (no 'requires credentials' discount). Exploitation is confirmed at scale by a ransomware group (not theoretical). The MFT gateway role means every compromised instance exposes an entire enterprise's file transfer data and provides a DMZ-to-LAN pivot. Even a strict friction audit finds nothing to subtract.
What to do — in priority order.
- Restrict admin console and License Servlet to internal/VPN-only access immediately — The entire attack chain requires network reachability to the GoAnywhere admin port (typically 8000/8001). Blocking internet access to these ports via firewall rules eliminates the unauthenticated attack vector. Deploy within hours — this is your noisgate mitigation SLA for CRITICAL: ≤ 3 days, but given active exploitation and KEV listing, treat this as an emergency change within hours. If the admin console must remain accessible, restrict it to known management IPs via allowlist.
- Upgrade to GoAnywhere MFT 7.8.4 or sustain release 7.6.3 — The vendor patch hardens the deserialization routine with type restrictions. This is the definitive fix. Deploy within the noisgate remediation SLA of ≤ 90 days, but given active ransomware exploitation, prioritize emergency patching within days, not weeks. Test in a staging environment first if possible, but do not let testing delay deployment beyond 72 hours.
- Deploy EDR or endpoint monitoring on GoAnywhere MFT hosts — Many MFT appliances run without endpoint agents, leaving post-exploitation activity invisible. Install EDR capable of detecting: RMM tool installation (SimpleHelp, MeshAgent), unexpected child process spawning from the Java/GoAnywhere process, and
.jspfile creation in web directories. This provides detection-in-depth if the network control fails. - Audit GoAnywhere host for IOCs published by Microsoft and Fortra — Check for: unexpected
.jspfiles in GoAnywhere web directories, SimpleHelp or MeshAgent binaries, unusual outbound connections to C2 infrastructure, and new local accounts. Microsoft's October 6 blog contains specific file hashes and C2 domains. If any IOCs are found, treat the host and all credentials it holds as compromised. - Rotate all credentials stored on or accessible from the MFT host — GoAnywhere MFT hosts typically store AD service account credentials, SFTP partner keys, database connection strings, and LDAP bind credentials. If exploitation cannot be ruled out, rotate these credentials immediately. The MFT host's DMZ position means a compromise exposes every system it connects to.
- Implement network segmentation between DMZ MFT hosts and internal LAN — Even if the MFT host is compromised, strict firewall rules limiting its internal connectivity to only required file share and database ports will slow lateral movement. Block all outbound RDP, SMB, and WMI from the MFT host to internal subnets except explicitly required destinations.
- WAF alone does not mitigate this. The auth bypass uses a valid JSF path (
/Unlicensed.xhtml/x) with standard HTTP parameters. Generic WAF rules for path traversal or SQL injection will not flag this. A custom WAF rule targeting the specific path pattern could help but is fragile and easily evaded with encoding variations. - Disabling the License Servlet is not a supported configuration. The servlet is integrated into GoAnywhere's core web application and cannot be independently disabled without breaking license management functionality.
- Network-level IDS signatures provide detection, not prevention. Snort/Suricata rules for the exploit pattern will alert but will not block the attack unless deployed inline as IPS. Even then, encrypted traffic (HTTPS) renders payload inspection ineffective without TLS termination upstream.
- Application-layer authentication (MFA on admin console) does not help. The vulnerability bypasses the authentication layer entirely — MFA on the admin login has no bearing on the License Servlet exception-routing bypass.
Crowdsourced verification payload.
Run this script on each GoAnywhere MFT host (Linux/Windows via bash or WSL) as any user with read access to the GoAnywhere installation directory. Example: bash check_cve_2025_10035.sh /opt/GoAnywhere. The script checks the installed version against the patched versions and probes the License Servlet endpoint for the auth bypass indicator.
#!/usr/bin/env bash
# CVE-2025-10035 Verification Script for GoAnywhere MFT
# Usage: bash check_cve_2025_10035.sh [GOANYWHERE_INSTALL_DIR] [OPTIONAL_URL]
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
set -euo pipefail
GA_DIR="${1:-/opt/GoAnywhere}"
GA_URL="${2:-}"
STATUS="UNKNOWN"
echo "=== CVE-2025-10035 Check ==="
echo "GoAnywhere directory: $GA_DIR"
# Method 1: Version file check
if [ -f "$GA_DIR/version.txt" ]; then
VERSION=$(cat "$GA_DIR/version.txt" | grep -oP '[0-9]+\.[0-9]+\.[0-9]+' | head -1)
echo "Detected version: $VERSION"
if [ -n "$VERSION" ]; then
MAJOR=$(echo "$VERSION" | cut -d. -f1)
MINOR=$(echo "$VERSION" | cut -d. -f2)
PATCH=$(echo "$VERSION" | cut -d. -f3)
# Fixed in 7.8.4 (standard) or 7.6.3 (sustain)
if [ "$MAJOR" -gt 7 ]; then
STATUS="PATCHED"
elif [ "$MAJOR" -eq 7 ] && [ "$MINOR" -gt 8 ]; then
STATUS="PATCHED"
elif [ "$MAJOR" -eq 7 ] && [ "$MINOR" -eq 8 ] && [ "$PATCH" -ge 4 ]; then
STATUS="PATCHED"
elif [ "$MAJOR" -eq 7 ] && [ "$MINOR" -eq 6 ] && [ "$PATCH" -ge 3 ]; then
STATUS="PATCHED"
else
STATUS="VULNERABLE"
fi
fi
elif [ -f "$GA_DIR/build.properties" ]; then
VERSION=$(grep -oP 'version=\K[0-9]+\.[0-9]+\.[0-9]+' "$GA_DIR/build.properties" 2>/dev/null || true)
echo "Detected version from build.properties: ${VERSION:-not found}"
if [ -n "$VERSION" ]; then
MAJOR=$(echo "$VERSION" | cut -d. -f1)
MINOR=$(echo "$VERSION" | cut -d. -f2)
PATCH=$(echo "$VERSION" | cut -d. -f3)
if [ "$MAJOR" -gt 7 ]; then
STATUS="PATCHED"
elif [ "$MAJOR" -eq 7 ] && [ "$MINOR" -gt 8 ]; then
STATUS="PATCHED"
elif [ "$MAJOR" -eq 7 ] && [ "$MINOR" -eq 8 ] && [ "$PATCH" -ge 4 ]; then
STATUS="PATCHED"
elif [ "$MAJOR" -eq 7 ] && [ "$MINOR" -eq 6 ] && [ "$PATCH" -ge 3 ]; then
STATUS="PATCHED"
else
STATUS="VULNERABLE"
fi
fi
else
echo "WARNING: Could not find version file at $GA_DIR"
fi
# Method 2: HTTP endpoint probe (optional)
if [ -n "$GA_URL" ]; then
echo "Probing endpoint: $GA_URL"
PROBE_URL="${GA_URL}/goanywhere/license/Unlicensed.xhtml/noisgate_check?javax.faces.ViewState=noisgate&GARequestAction=activate"
HTTP_RESP=$(curl -sk -o /dev/null -w '%{http_code}:%{redirect_url}' -L --max-redirs 0 "$PROBE_URL" 2>/dev/null || echo "000:")
HTTP_CODE=$(echo "$HTTP_RESP" | cut -d: -f1)
REDIRECT_URL=$(echo "$HTTP_RESP" | cut -d: -f2-)
echo "HTTP response code: $HTTP_CODE"
if echo "$REDIRECT_URL" | grep -q 'bundle='; then
echo "RESULT: Redirect contains bundle parameter - VULNERABLE"
STATUS="VULNERABLE"
elif [ "$HTTP_CODE" = "302" ] || [ "$HTTP_CODE" = "301" ]; then
if ! echo "$REDIRECT_URL" | grep -q 'bundle='; then
echo "RESULT: Redirect without bundle parameter - likely PATCHED"
if [ "$STATUS" = "UNKNOWN" ]; then STATUS="PATCHED"; fi
fi
elif [ "$HTTP_CODE" = "403" ] || [ "$HTTP_CODE" = "404" ]; then
echo "RESULT: Endpoint blocked or not found - likely mitigated"
if [ "$STATUS" = "UNKNOWN" ]; then STATUS="PATCHED"; fi
else
echo "RESULT: Inconclusive HTTP response"
fi
fi
echo ""
echo "=== VERDICT: $STATUS ==="
case "$STATUS" in
VULNERABLE) exit 1 ;;
PATCHED) exit 0 ;;
*) exit 2 ;;
esac- Fortra Security Advisory FI-2025-012
- Rapid7 ETR: Critical Unauthenticated RCE in GoAnywhere MFT
- watchTowr Labs: Is This Bad? This Feels Bad (GoAnywhere CVE-2025-10035)
- Microsoft Security Blog: Investigating Active Exploitation of CVE-2025-10035
- Censys Advisory: CVE-2025-10035 Exposure Data
- Bitsight: Critical Vulnerability Alert CVE-2025-10035
- The Hacker News: Fortra GoAnywhere CVSS 10 Flaw Exploited as 0-Day
- GitHub Advisory GHSA-fcfw-g3g2-2588
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.