We Measured 1'448 Swiss NetScalers for CitrixBleed 3

Passive measurement of Swiss Citrix NetScaler exposure to CVE-2026-3055. 57 hosts still on pre patch builds, a new fingerprinting signal, and one very ambitious honeypot.

threat-intelvulnerability-scanningnetwork-security

In July 2025, Darktrace attributed a European telco breach to Salt Typhoon. The initial access point was a Citrix NetScaler Gateway. The same group (tracked as Earth Estries, GhostEmperor, UNC2286) has been linked to intrusions in more than eighty countries across telecoms, energy, and transport. Switzerland carries a lot of that target profile. A dense NetScaler footprint. Cantonal governments, private banks, pension funds, a national telco, private hospitals, utilities. The kind of attack surface a PRC aligned operator would pick up on a Monday morning.

In March 2026, Citrix published advisory CTX696300. CVE-2026-3055. CVSS 9.3. An out of bounds read in the SAML IdP code path that lets an unauthenticated attacker read process memory, including admin session IDs, the same basic shape as the original CitrixBleed. The fix shipped in NetScaler ADC and Gateway 14.1-60.58, 13.1-62.23, and 13.1-37.262 for the FIPS and NDcPP variants. CISA put it on the KEV catalog with a patch deadline of 2026-04-02 for US federal agencies. WatchTowr saw reconnaissance from known threat actor IPs starting 2026-03-27. The press settled on the nickname CitrixBleed 3.

Four weeks after the patch dropped, I wanted to know how much of Switzerland was still on pre patch builds. Not because a specific operator is under any particular suspicion, but because the window between “CVE announced” and “CVE patched in deployed fleets” is where attackers actually live, and I had not seen a public measurement of that window for Swiss NetScalers in particular.

One early clarification. I am not claiming Salt Typhoon has been observed using CVE-2026-3055. Darktrace’s 2025 disclosure names the class of appliance that was the initial access point but does not publicly identify which CVE was used, and several 2025 NetScaler memory overread vulnerabilities fit the window. The reason Salt Typhoon matters to this writeup is that the Swiss NetScaler footprint looks like the kind of targets this actor already operates against, and the March 2026 CVE lives on the same playbook. Unauthenticated session ID leak, pivot to Citrix VDA hosts, persistent RAT via DLL sideloading.

How I measured it

The scope was Swiss NetScalers only, reachable on the internet, and banner grab methods only. Two Shodan queries (country:CH http.title:"Citrix Gateway" and country:CH product:"Citrix NetScaler") gave 3’661 raw records, which deduped to 2’318 unique IP and port pairs. For each survivor I ran at most four HTTP GETs against static resources that every NetScaler serves unauthenticated by design. The plug in inventory at /vpn/pluginlist.xml. The login page, the locale strings and the gzip bundle at /vpn/js/rdx/core/lang/rdx_en.json.gz.

One record in that raw pool dominated the first pass in an obvious way. A single IP, geolocated to Switzerland, with Shodan entries on roughly 870 distinct ports ranging from the low system ports all the way up into the high ephemeral space. Every port returned a byte identical HTML body. Every port advertised the same, fairly old, NetScaler version. No single appliance operates 870 gateway ports on one IP. This is a honeypot or a tarpit, and given that whoever is running it is probably on the defending side of the fence, I will not describe the fingerprint in more detail than that. I filtered the IP out of the dataset. The relevant point for this study is that without filtering, the raw count would have come in at something like “870 old Swiss NetScalers, most of them on the same admin”, which is the kind of number that writes itself into a loud headline and then quietly falls apart under review. Fleet wide measurement against an uncurated Shodan pull is always subject to this, and anyone reporting big NetScaler exposure numbers without describing how they handle decoys is almost certainly overcounting.

After the filter, 1’448 real Swiss NetScalers were left to classify.

The obvious next step was to use the fingerprinting method Fox-IT published in December 2022. That method leaks the NetScaler build through two signals: the MD5 hash of a specific JavaScript file appearing as ?v=<md5> on login page asset URLs, and the gzip mtime preserved inside rdx_en.json.gz. Fox-IT’s open source CSV then maps either signal to a version string.

Both signals are now effectively dead on modern Swiss NetScalers. Two hosts out of 1’448 still carry the ?v=<md5> query parameter. Of the 1’316 hosts that returned HTTP 200 on rdx_en.json.gz, only two leaked anything other than a three byte stub with a zeroed mtime. The other 1’314 return the stub. That is a 99.85% kill rate across the responsive population, or 90.7% across the full 1’448. Citrix’s anti fingerprinting patch works. Anyone still sizing NetScaler exposure with the 2022 method is dramatically undercounting.

Which meant finding another signal. The one that worked is almost embarrassingly mundane. The HTTP Last-Modified header on /vpn/pluginlist.xml preserves the on disk mtime of that file. So does the Last-Modified on rdx_en.json.gz, even though the gzip mtime inside the body has been zeroed. The question is where those mtimes come from. Two hypotheses. One, the admin’s system clock stamps the file at install or upgrade time. In that case, two unrelated admins should almost never share a second precise timestamp, and two different files on the same host would both be stamped at the same install moment. Two, the mtimes are baked into Citrix’s release image itself and survive install and upgrade unchanged. In that case, every customer who installed the same image reports the same second, and each file in that image carries its own build time mtime, which would produce a consistent offset between files that replicates across every host on the image.

The data kills the first hypothesis cleanly.

Two hundred and nine Swiss NetScalers, spread across forty three distinct network operator ASNs, simultaneously return Last-Modified: Sat, 18 Apr 2026 16:00:01 GMT on /vpn/pluginlist.xml and Last-Modified: Sat, 18 Apr 2026 15:00:01 GMT on /vpn/js/rdx/core/lang/rdx_en.json.gz. The two files are exactly one hour apart, to the second, across every single one of those 209 hosts. The forty three ASNs include Swisscom, Sunrise, DV Bern AG (the cantonal IT provider that hosts Canton Bern government systems), MTF Solutions, the SWITCH academic backbone, the Bank for International Settlements (the Basel headquartered central bank of central banks), Lonza, Migros, Etat du Valais, Etat de Genève, Kanton Basel Stadt, Banque Lombard Odier, Swissquote, the compute block behind Schwyzer Kantonalbank, IWB (a Basel public utility), and twenty eight others that span hosting, payments, industrial, and residential ISP. An admin’s install clock touching both files at install time would make both timestamps equal. MSP coordination cannot produce a second precise one hour offset across BIS, a pharma multinational, three cantonal governments, four banks, a national retailer, and an academic network. The mtimes are not generated at install but baked into the release image :)

A second cluster confirms the mechanism from a different angle. 189 hosts across 33 distinct ASNs share a different pair: Last-Modified: Fri, 10 Apr 2026 07:00:01 GMT on both files, same second on both this time. A different release image. A different internal offset pattern. The same extraordinary consistency across another set of unrelated operators. Two images, two different internal signatures, both preserved exactly on every host that ran the upgrade.

The 209 count requires each host to return the expected pair of timestamps across both files. If I relax that and look at /vpn/pluginlist.xml alone, the April 18 16:00:01 cluster grows to 325 hosts across 57 ASNs. The two file version is the stronger argument because it disproves install time touch directly. The one file version shows the same pattern on an even larger slice of the fleet. I have not found a vendor reference that documents this. It replaces Fox-IT’s now dead technique with something that works on the current fleet. However I assume I did no rocket science here and that this is already known somewhere but I didn’t come across it yet.

One consequence of this is worth stating plainly. Last-Modified on a given NetScaler is not the date that NetScaler was installed. It is the date Citrix built the release image the NetScaler is running. Every host on the April 10 release reports 2026-04-10. Every host on the April 18 release reports 2026-04-18. A host still running an older release reports that older release’s date. The timestamp is identical across appliances on the same image (which is how the preservation mechanism was proven above), and it changes when Citrix ships a new image. Citrix shipped the CVE-2026-3055 fix on 2026-03-23, so any NetScaler reporting a Last-Modified earlier than that date is running an image built before the patch existed.

With that signal in hand, classification is trivial. Any host with a Last-Modified before 2026-03-24 is on a build from before the CitrixBleed 3 patch shipped. Anything on or after that date is on a post patch build. It is a heuristic (a host might be on a post patch date from a maintenance branch that does not carry this particular fix), but for fleet sizing it is the best you can get from outside without authentication.

What the data says

From 1’448 real Swiss NetScalers:

Bucket               Hosts      Share   Bar
─────────────────────────────────────────────────────────────
Evidence of vuln        57      3.9%    ██
Likely patched       1'277     88.2%    ████████████████████████████████████████████
Unreachable            101      7.0%    ███▌
Unknown                 13      0.9%    ▌
─────────────────────────────────────────────────────────────
Total                1'448    100.0%

Two of the 57 are on pre 2026 builds (one from June 2023, one from July 2025). The remaining 55 are on 2026 builds dated earlier than the patch release. Roughly 3.9% of the Swiss real fleet is still on a build that predates the fix, four weeks after advisory. Without a parallel measurement in another country I cannot say whether that is better or worse than average. Internally, the shape of the distribution says more than the aggregate.

The daily histogram of the Last-Modified field is the cleanest way to see that shape. Each row is one calendar day of build date; the bar length is the host count with that day’s build:

2026-03-15 ▎                                                                  1
2026-03-17 ████████████████████                                               21   ← pre patch mass deploy
2026-03-18 ██████                                                              7
2026-03-19 ██████                                                              7
2026-03-20 █████                                                               6
2026-03-21 ████                                                                4
2026-03-22 █████                                                               6
2026-03-23 ██                                                                  2   ← PATCH DATE (CTX696300)
───────────────────────────── PATCH DATE LINE ──────────────────────────────────
2026-03-24 █████                                                               6
2026-03-27 ████████                                                            9
2026-03-28 █████████████                                                      14
2026-03-30 ████████████                                                       13
2026-04-01 ███████████                                                        12
2026-04-04 ███████████████                                                    16
2026-04-10 ███████████████████████████████████████████████████                382   ← mass deploy #1
2026-04-16 ██████████████████████████                                          27
2026-04-18 █████████████████████████████████████████████████████████████████  600   ← mass deploy #2
2026-04-19 █████████████████████████████████████████████████████████          65
2026-04-20 ██████████████████████████                                          27   (snapshot day)

The cliff at 2026-03-23 is the patch date. The two fat peaks, 382 hosts on 2026-04-10 and 600 hosts on 2026-04-18, are mass deploys. Swiss integrators move customer fleets together. When Citrix releases a maintenance build, the big MSPs roll it to their tenants within days (love the speed). The April 18 peak alone spans 82 distinct ASNs on that single day. A small number of integrators make one deployment decision and large swathes of end customer infrastructure inherit the patch state at once.

The more interesting clusters are the ones still below the cliff. Specifically:

Shared Last-ModifiedHostsInterpretation
Tue, 17 Mar 2026 15:07:22 GMT8One pre patch build, rolled to eight unrelated customer orgs six days before the CVE dropped
Tue, 17 Mar 2026 15:46:39 GMT7Same pattern, different integrator, seven customer orgs
Tue, 17 Mar 2026 08:00:02 GMT5Hosted at one Swiss ISP, fronting customer brands in healthcare and finance
Thu, 19 Mar 2026 01:00:06 GMT3Ticino ISP, three appliances on the same build

These are the hosts where an integrator pushed a March 17 build to a customer fleet six days before that build became known vulnerable. The end customers inherited the exposure without any direct choice in the matter. The fix itself is not complicated. For most of these organisations, patching velocity is whatever their MSP decides it is.

Rough sectoral bucketing of the 57 vulnerable hosts:

SectorCount
ISP and telco (appliances operated on behalf of end customers)19
Industrial (manufacturing, chemicals, design)9
IT services and MSPs (multi tenant exposure)5
Finance (pension fund, bank portal, regulated FSI)4
Government and public sector (cantonal IT, municipal, education)3
Healthcare (hospital groups, medical imaging, medtech portals)2 plus
Other15

The healthcare count understates reality because several healthcare brands appear under an ISP or MSP organisation tag rather than their own. Cross referencing hostnames brings at least six healthcare adjacent hosts into the vulnerable set.

The cross sector pattern is the one that actually matters. The majority of vulnerable hosts are operated by someone other than the organisation whose data runs through them. These are ISP hosted NetScalers fronting customer login portals, or MSP managed appliances that serve a dozen customers each. The end organisation paid for a service. That service happens to be vulnerable this month. And the organisation has no real visibility into when it will not be.

Grouping the reachable fleet by ASN and looking at patch rate, where patch rate is patched divided by (vuln plus patched):

Operator (ASN level, anonymised)       Total  Vuln  Patched  Patch rate
───────────────────────────────────────────────────────────────────────
Largest Swiss telco (AS3303)             358    20      293    93.6%   ████████████████████▊
Largest Swiss integrator (AS20988)       137     0      132   100.0%   ████████████████████████
Second largest telco (AS6730)            121     5      106    95.5%   █████████████████████
Cantonal integrator (AS203732)            45     0       43   100.0%   ████████████████████████
Residential ISP (AS1836)                  29     7       20    74.1%   ████████████████▊
Ticino ISP (AS48350)                      17     4       11    73.3%   ████████████████▌

Two stories live in this table. The largest Swiss integrator (AS20988, 137 customer NetScalers) was at 100% patched a month after the CVE. Zero vulnerable which is the benchmark! It is achievable. At the same time, two smaller operators sit in the low seventies. One mid sized residential ISP has seven vulnerable appliances out of 29. A Ticino based ISP has four out of 17. Their end customers are inheriting a month plus of lag with no visible way to intervene.

The worst performers are mostly smaller regional ISPs offering NetScaler as a service. Not large integrators with a real patch program. Residential or small business ISPs that bought a handful of NetScaler licences to front customer portals without building the operational muscle to keep up with vendor advisories.

What this actually means

If you run NetScaler in Switzerland (or anywhere else), the real question is not “did the CVE apply to me” but “who patches it when the next one drops”. Most of the organisations that have ended up in the wrong bucket this month are not running NetScaler themselves. They contracted that work out and the contract probably did not specify time to patch in days. Nobody checks it, the CVE lands and the integrator does or does not act quickly. Eventually the customer finds out via a blog like this one.

A few concrete things worth doing while reading this:

Check which maintenance branch your appliance is on. 14.1-60.58 or later, 13.1-62.23 or later, 13.1-37.262 or later for FIPS and NDcPP. CTX696300 is Citrix’s advisory.

If you are a SAML IdP (the precondition for this particular bug) the upgrade is immediate. If you are not, the upgrade is still immediate because the next vulnerability will find whatever code path you actually use.

If your appliance is managed by an ISP or an MSP, ask them explicitly when they applied this fix. “We patch monthly” describes a process. CVEs care about specific dates. The spread in this data says the gap between a well run integrator and a less well run one is four weeks of exposure, sometimes more.

A few caveats I want to be honest about. The “likely patched” bucket is a heuristic. A build dated after the patch release was produced in the post patch era, but I cannot confirm from the outside that this specific fix was carried into whatever maintenance branch it came from. The actual exploitable population also depends on SAML IdP configuration, which is not determinable passively. Some of the 57 may not be running that code path. Some of the 1’277 might be, on a non fixed branch. Net effect, 57 is an upper bound on the exploitable set, probably within plus or minus 20% of reality. Two of the 57 have a Last-Modified on 2026-03-23, the same day the patch shipped, and might actually be on the fixed build. I flagged them pre patch to be conservative. Load balanced public VIPs hide fleet diversity. Shodan’s geolocation is MaxMind and is imperfect at sub 2% error. And the whole measurement is a single snapshot from 2026-04-20. Anyone who patches on 2026-04-21 will still look unpatched here.

The method generalises. The same pipeline will work against Fortinet SSL VPN, Ivanti Connect Secure, F5 BIG-IP, and any other edge appliance that leaks file mtimes preserved in its release image through static HTTP responses.

If you want to see what your own public IP looks like from the outside without running any of this yourself, Sentinel scans it and delivers an AI written report in about 30 minutes. Free scan and no account required. It checks for CitrixBleed 3 and for the rest of the catalogue of open admin panels, expired certificates, end of life software, and other perimeter issues that tend to show up together. The report tells you which CVEs apply to your environment and which ones matter most.

The NetScalers in Switzerland are mostly patched. The ones that are not cluster on a handful of smaller ISPs and inside a few MSP fleets with slower cadences. Knowing which category your infrastructure sits in is a matter of asking the right person. Or running a scan and seeing the answer yourself.