Critical CVE Response

Why Is an 11-Year-Old FTP Bug in This Week’s KEV Additions?

Dark cyberpunk illustration of an old rusted iron hatch standing ajar in a wall of modern dark server racks, orange light spilling onto a wet floor while cyan data traces bend toward the opening.

The oldest vulnerability on the list is from 2014. The newest is from 2023. Between them sit a 2015 FTP bug, a 2015 DNS crash, a 2016 Struts command injection, a 2019 VPN path traversal, two 2021 flaws in a document server and a source-code platform, and a 2023 information leak in a headless CMS. Eight in total, and that is the complete set of software vulnerabilities that ten government agencies across seven countries say Chinese state-linked operators exploited successfully to steal email and credentials from governments, hospitals, manufacturers and IT providers.

The advisory is AA26-281A, published on October 8 by the FBI, CISA, the NSA, the UK NCSC, Australia's ACSC, the Canadian Centre for Cyber Security, Japan's National Police Agency and National Cybersecurity Office, New Zealand's NCSC and Spain's CNI. It runs 58 pages, 39 of them indicators of compromise. It names Integrity Technology Group, a China-based for-profit company with links to the Chinese government, as the enabler: the firm builds and buys offensive tooling, hosts infrastructure and compromises networks. The agencies say the operators it supports use tradecraft consistent with activity the industry tracks as Flax Typhoon, Ethereal Panda and Red Juliett, with the standard caveat that vendor names do not map one to one onto government tracking.

Read the eight entries by date and the espionage framing falls away. Five of them were added to CISA's Known Exploited Vulnerabilities catalog on the same day the advisory landed, and all five carry a remediation due date of October 11. Here is the verdict. If nothing on your external perimeter answers on port 21, you run no BIND of your own, you have no Struts 2.3 application, no ONLYOFFICE Docs server and no Strapi below 4.8, the CVE table is somebody else's work and you can skip it. The rest of the advisory applies to you anyway, because it describes password spraying across ten Microsoft mail interfaces and a replication attack against the domain controller, and every tenant and every domain has those whether anyone signed off on them or not.

What the FBI recovered

The technical detail comes from multiple FBI investigations, and it describes activity reaching back to at least mid-January 2021. The reconnaissance layer is entirely off the shelf: BBScan, dirsearch, Fscan, ksubdomain, masscan, Nmap, OneForAll, ShuiZe and WPScan, concentrated on ports 21, 22, 53, 80, 443 and 1080, with dirsearch enumerating PHP and ASP (.NET) pages. The agencies draw the obvious conclusion in one line: the use of open-source tools typically found on GitHub suggests the operators look for more vulnerable targets rather than harder ones.

On top of that sits MicroScan, a Python web application the operators have used since as early as 2017. It carries more than 1,300 penetration-testing scripts and the advisory names the services those scripts target: OpenSSL, Oracle WebLogic, Rejetto HFS, WordPress, Juniper ScreenOS, Jenkins and Apache Struts. A dashboard shows the hits. This is a vulnerability-scanning product, operated at scale, pointed at the public internet.

What follows access is just as unremarkable. Persistence is a SoftEther VPN client, downloaded with PowerShell on Windows or curl and wget on Linux, installed under the filename conhost.exe or dllhost.exe, and set to reconnect at startup. The advisory notes the reason plainly: endpoint detection is less likely to flag SoftEther because SoftEther is legitimate software. Collection is a PHP script, Curlc4.txt, that talks to the Exchange Web Services API, compresses the mail it pulls and sometimes encrypts it with RC4 or AES-128-CBC before upload. Cloud mail goes out through office-cli, a command-line utility driven by stored client_id, tenant_id and secret values. In some cases the operators restricted access to the stolen archive to IP addresses in Xiamen.

Victims named in the advisory span Government Services and Facilities, Critical Manufacturing, Healthcare and Public Health and Information Technology, plus law enforcement, education and religious organizations, across Southeast Asia, Africa and North America.

Each of the eight needs something specific to be true

A CVE in an advisory is a claim about someone else's estate until you check the precondition. Four of the five new KEV entries carry forensicTriage: Yes in the catalog data, which under BOD 26-04 means the patch alone does not close the item. Here is what each one actually requires.

The five added on October 8

  • CVE-2015-3306, ProFTPD 1.3.5, fixed in 1.3.5a. CISA describes arbitrary file read and write through the SITE CPFR and SITE CPTO commands. It needs an FTP service reachable from the attacker and the copy module loaded.
  • CVE-2015-5477, ISC BIND 9.x before 9.9.7-P2 and 9.10.x before 9.10.2-P3. A crafted TKEY query trips a REQUIRE assertion and named exits. ISC rates it critical, lists no workaround, and notes that the vulnerable code runs before ACLs are evaluated, so a locked-down configuration does not protect you. Recursive and authoritative servers are both affected. The impact stops at denial of service.
  • CVE-2016-3081, Apache Struts 2.3.19 through 2.3.28, excluding 2.3.20.3 and 2.3.24.3. Remote code execution through the method: prefix, and only when Dynamic Method Invocation is enabled. Apache's S2-032 note treats disabling that feature as an acceptable alternative to upgrading; the fixed releases are 2.3.20.3, 2.3.24.3 and 2.3.28.1.
  • CVE-2021-3199, ONLYOFFICE Docs 5.1.5 through 5.6.2, fixed in 5.6.3. A /.. sequence in an image upload parameter escapes the directory, and CISA says it can reach code execution. The catalog entry scopes it to deployments using JWT.
  • CVE-2023-22894, Strapi, listed in the advisory as affecting up to 4.5.5. The query filter exposes sensitive user detail, and CISA notes it chains with CVE-2023-22621 to reach code execution. Read the precondition before you panic: it needs admin panel access first. CISA also flags the affected builds as possibly end of life and tells operators to move to a supported release rather than patch in place, and it points at Strapi's own disclosure and release notes rather than restating a range. Take your version boundary from the vendor.

The three that were already listed

  • CVE-2014-6278, GNU Bash through 4.3 (bash43-026). OS command injection, the Shellshock family, twelve years old this month.
  • CVE-2019-11510, Pulse Connect Secure 8.2 before 8.2R12.1, 8.3 before 8.3R7.1 and 9.0 before 9.0R3.4. Unauthenticated path traversal on a remote-access appliance.
  • CVE-2021-22205, GitLab, all versions from 11.9. Code injection to remote execution.

CVE-2015-5477 is the only one of the five without the forensic triage flag, which tracks with its impact. A crash leaves a restart, not a foothold.

Date every service your perimeter answers on

The practical read of AA26-281A is an age audit. Everything the operators used to get in was documented, patched and widely reported years before they used it. The work is finding the hosts where that is still untrue, and that starts with an inventory rather than a patch run.

# Run against address space you own. Service and version detection only.
RANGES="203.0.113.0/24"
STAMP=$(date -u +%Y%m%d)

nmap -Pn -sV --version-intensity 5 \
     -p 21,22,53,80,443,1080,8080,8443 \
     -oA "perimeter-$STAMP" "$RANGES"

# Surface only the products AA26-281A names.
grep -Ei 'proftpd|bind|isc|onlyoffice|strapi|struts|gitlab|pulse|shellshock' \
     "perimeter-$STAMP.nmap"

Then read a version off each candidate rather than guessing from a banner. Three of these report their build without authentication, which is convenient for you and for everyone else.

# BIND, if the server still answers the version query.
dig @ns1.example.internal version.bind chaos txt +short

# ONLYOFFICE Docs exposes its build on the healthcheck path.
curl -sk --max-time 5 https://docs.example.internal/healthcheck

# Struts: the constant that decides whether CVE-2016-3081 applies at all.
grep -rn 'struts.enable.DynamicMethodInvocation' \
     /opt/app/WEB-INF/classes/struts.properties /opt/app/WEB-INF/struts.xml

# Strapi: read the installed version on the host, not over the network.
npm ls @strapi/strapi --depth=0 2>/dev/null || grep -m1 '"@strapi/strapi"' package.json

Keep the catalog itself in the loop rather than waiting for a newsletter. The KEV feed is JSON and the additions are one query away.

curl -s https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json \
  | jq -r '.vulnerabilities[]
           | select(.dateAdded == "2026-10-08")
           | [.cveID, .vendorProject, .product, .dueDate, .forensicTriage]
           | @tsv'

The half of the advisory that lands in every tenant

Set the CVE table aside and the rest of AA26-281A describes an attack path with no software vulnerability in it. The operators run EBurst, an open-source Python tool, to spray and guess passwords against Microsoft Exchange and Microsoft 365. The advisory lists the interfaces it walks: ECP, EWS, OAB, OWA, RPC, API, MAPI, PowerShell, Autodiscover and Microsoft-Server-ActiveSync. Ten of them, and the agencies add an instruction rather than an observation: defenders should include these interfaces when defending against EBurst.

Most spray detection watches the sign-in page. A tool that walks ten interfaces finds the one nobody watches. The signature is the same in all of them - one source address, many accounts, a small number of failures each - so group by client application and source rather than by user.

SigninLogs
| where TimeGenerated > ago(7d)
| where ResultType != 0
| summarize
    failures = count(),
    accounts = dcount(UserPrincipalName),
    firstSeen = min(TimeGenerated),
    lastSeen  = max(TimeGenerated)
  by IPAddress, ClientAppUsed, ResultType
| where accounts >= 10 and failures < accounts * 5
| sort by accounts desc

The second control is older than the tool that defeats it. The operators used a binary called DC.exe to run DCSync: an RPC binding to a domain controller, then the Directory Replication Service to pull account credentials, group membership and trust relationships. The advisory lists the Active Directory object identifiers the binary queried. You do not need them. You need event 4662 on each domain controller, filtered to the three replication extended rights.

# Run on each domain controller. Requires the "Audit Directory Service
# Access" subcategory to be enabled, or 4662 will never be written.
$replRights = '1131f6aa-9c07-11d1-f79f-00c04fc2dcd2',  # Get-Changes
              '1131f6ad-9c07-11d1-f79f-00c04fc2dcd2',  # Get-Changes-All
              '89e95b76-444d-4c62-991a-0facbeda640c'   # In-Filtered-Set
$pattern = ($replRights -join '|')

Get-WinEvent -FilterHashtable @{
    LogName   = 'Security'
    Id        = 4662
    StartTime = (Get-Date).AddDays(-30)
} |
Where-Object { $_.Message -match $pattern } |
Select-Object @{ Name = 'Account'; Expression = { $_.Properties[1].Value } } |
Group-Object Account |
Sort-Object Count -Descending |
Format-Table Count, Name -AutoSize

Two kinds of name belong in that output: the computer accounts of your own domain controllers, and whatever account runs directory synchronization to Entra ID. A third name is the finding. Build the allowlist once, on a quiet week, and the query becomes a five-second check instead of a research project.

Put a release year next to every exposed service

Pull the external list first, before any patching. For every service that answers, record three things: the product, the version it reports, and the year that version shipped. Sort by the third column. Anything older than the support contract you are currently paying for is the part of your estate this advisory describes, and the ProFTPD and BIND entries say that a 2015 release date is no protection against a 2026 adversary. Then run the sign-in query and the 4662 query whatever the perimeter scan returns, because the mail interfaces and the replication rights are present in every environment by default.

If that external list turns out to be longer than you expected, or nobody in the building owns it, close that gap before you close any CVE. The advisory's own final mitigation says the same thing in agency language: engage a skilled tester to evaluate your public attack surface and fix what the commonly exploited vulnerabilities reach.

Want to know what your perimeter still answers on?

We run external attack-surface reviews that start exactly here: every internet-reachable service, the version each one reports, and the exploited-vulnerability entries that match it. Book a session to walk through your external footprint. If you would rather price a test of that footprint yourself first, the penetration testing cost calculator takes about two minutes and needs no signup.