The post-exploit command table was the last frozen Mar-Apr artifact. Recomputed
the cmd.gz.war -> /cmd.gz/cmd.jsp webshell POSTs (SD-WAN vManage, CVE-2026-20127)
from the live-window exports: only 33 executions, 3 distinct commands (id x21,
dir x10, ls x2), all trivial enumeration from a handful of IPs.
The baseline's full chain (819 id, 372 XMRig via kernel.sh, /etc/shadow reads,
gs-netcat reverse shells) did not recur. Preserved that finding as labeled
historical context in the callout; the table now leads with live reality.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bx33CDbC3G8DQMQMARewof
Living-doc consistency pass after the Jul 16 data refresh (PR #163). The
hand-written deep-dives and infra tables were still on the frozen Mar-Apr
baseline and contradicted the auto-updated charts.
Prose fixes:
- SAP: was "third most targeted, 1,179 hits". Now #6 at 1,638 (1,024 on the
CVE-2022-22536 Apr 9-11 burst + 614 on CVE-2025-31324 across the window).
Reframed as a historical burst, dropped the stale ranking.
- SonicWall: was "478 attempts / 284 IPs, most distributed". Now 1,693 hits;
dropped the "most distributed" superlative (it contradicted the Next.js
section) and documented the verified libredtail-http/apache.selfrep worm
staging rotation (31.57 -> 204.76 -> 125.135 -> 14.46 -> 217.60).
- Dropped the stale "31-day observation window" anchors (window is now ~4 mo).
Infra rebuild from the raw live-window exports (Apr 19 - Jul 16, newest-wins
day-dedup via scripts/extract_edge_infra.py), ASN/geo via Team Cymru + IPinfo:
- Scanner-UA chart: self-identification collapsed 38.7% -> ~5% as the
browser-spoofing CitrixBleed 2 flood took over; recomputed tool families.
- Staging Infrastructure: current worm-rotation hosts + new campaigns
(softwaretech loader, Next.js cloak stager, Cloudflare-fronted installer).
- Multi-Device Operators: current cross-decoy scanners; known research
scanners (ONYPHE, LeakIX) excluded.
- Replaced the unverifiable "Active" status badge with an Observed telemetry
window (no liveness probe of live malicious hosts).
- Flagged the webshell-command breakdown as a Mar-Apr baseline capture.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bx33CDbC3G8DQMQMARewof
The edge-exploits page's scanner-UA, staging, and multi-device-operator
tables were hand-curated from a one-off Mar-Apr pass and had no build step,
so every data refresh left them stale. This is that missing step.
Reads the raw Defused exports in ~/Downloads, applies the same newest-wins
day-dedup as transform_defused_csv.py so its numbers reconcile with the
page charts, and prints a defanged, curated view (named-tool vs
browser-masquerade UA split, staging URLs with first/last-seen, operator
IP -> decoy coverage). Persists nothing to the repo (decision #009); ASN
for chosen hosts is filled via Team Cymru / enrich_staging_domains.py.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bx33CDbC3G8DQMQMARewof
Complete the living-document refresh on top of the Carson cradle rebuild:
- daily/volume: +3 MHaggis days (Jul 14-16) via analyze_clickgrab; total_sites_crawled
26,969 -> 27,269, window now through 2026-07-16.
- carson_landscape refreshed to 3,774 (gist, Jul 16). total_domains held at the Carson
XLSX set (3,777) -- analyze preserves it distinct from the landscape count, no clobber.
- clickfix_lure_keywords.yml regenerated from the updated MHaggis cache (IOK / URLScan
page.body pivots; feeds IOK rules, not rendered on the trends page).
Frozen by design, not refreshed (DECISIONS #011): payload_examples (rich generator gone,
pre-Oct-2025 reports LFS-locked) and staging_domains (21 entries, all already
ASN-enriched; new infra is manual curation, and enrich_staging_domains is local-only).
Detection recs are all behavior/chokepoint-anchored and already cover the summer cradle
reversal (the cradle-agnostic rule caught msiexec and the PowerShell comeback), so no new
rule -- adding one would be false coverage.
Verified: jekyll builds clean (exit 0, full build ~341s), clickgrab page renders with the
refreshed data.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bx33CDbC3G8DQMQMARewof
Rebuild the clean per-domain command classification from the July 17 Carson
ClickFix Hunter export via build_domain_monthly.py (manual/local, not CI).
3,321 -> 3,777 domains; June completed (74 -> 424, the prior export only had
June through the 16th), July added. domain_monthly / domain_cradles_total /
domain_evasion_totals refreshed; payload_examples / daily / staging_domains
byte-preserved.
The trend this surfaces: the cradle mix rotated back to remote download cradles.
IWR is 28% of June domains and 36% of July, WebClient 15% then 24%, curl 33% in
July, while msiexec (the late-2025 story) fell to <=1% since May and 0% in July.
The spring inline-encoding wave (base64's one-month May campaign, hex-XOR heavy
Apr-May) faded to near-zero by July.
Completing June corrected two now-false hardcoded claims: hex-XOR did NOT climb
"back to 84% in June" -- that was the partial n=74 export; complete June is 16%
(69/424), declining to 0% July. Fixed both spots, extended the msiexec trajectory
through July, and added a callout for the summer remote-fetch reversal.
Verified: historical months (through May) byte-stable, cradle + evasion charts
screenshot-verified (June IWR resurgence and hex-XOR decline render correctly),
0 console errors.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bx33CDbC3G8DQMQMARewof
transform_provenance.py short() hard-truncated the AS org description at 28
chars, cutting mid-word -- the top provider read "Emil Vitukhnovskii trading
a". Fall back to the AS handle when the org would overflow, so the label reads
the recognizable "GreatFlower". Labels that already fit are unchanged.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bx33CDbC3G8DQMQMARewof
Regenerate _data/edge_exploits_provenance.yml for the Apr-Jul 2026 window
(was Jul 3), 2,998 cumulative unique source IPs.
The local enrich_asns.py had been raw-summing overlapping exports, inflating
June 6.6x (105,888 vs the correct 16,113) and floating one ASN (datacampus,
the truncated Jun 10 spike's host) into the top purely as a double-counting
artifact. Gave it the same per-day MAX-wins merge + Jun 10 gap + :port strip
as transform_defused_csv.py, so per-month ASN totals now match the event page
exactly (May 50,016 / Jun 16,113 / Jul 3,537).
enrich_asns.py / hll.py / bulletproof_asns.yml are gitignored, local-only
(they touch raw IPs + an optional key, decision #009); only the IP-free
aggregate yml is committed. Keyless Team Cymru only; IPinfo cross-check skipped.
Verified: per-month totals reconciled to the event page; provenance stacked
chart screenshot-verified (May dominant = GreatFlower, the CitrixBleed 2 surge host).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bx33CDbC3G8DQMQMARewof
Fill the May 20-Jun 9 hole (uploaded 46,209-row export) and extend the
edge-exploits page to Jul 16. Total 75,420 -> 88,299. The story is a
CitrixBleed 2 (CVE-2025-5777) surge: 62,205 hits (70% of all traffic),
peaking May 26 at 29,274 hits from a single source (193.202.84.145).
transform_defused_csv.py:
- day merge is now per-day MAX-wins, not newest-wins, so a newer export's
partial window-start day can't overwrite an older complete count
(fixed Jun 16: 10 -> true 139).
- a row-capped export's truncated oldest day renders as a GAP, not a
partial bar (supersedes the 2026-07-03 partial flag). Jun 10 is the
first such gap; a narrow uncapped re-export closes it automatically.
- strip the source :port newer exports append to Attacker IP, keeping
unique-IP counts consistent across export formats (32,258 -> 2,988).
- CitrixBleed 2 daily series now spans the live window.
page: refreshed volume/target/CitrixBleed/Next.js/cPanel prose to the new
totals and the May 26 single-source surge; extended the CB2 chart to Jul 16;
dropped the now-dormant partial-day styling.
Verified: transform output cross-checked against an independent max-wins
re-derivation; page built under Jekyll, both charts screenshot-verified.
edge_exploits_provenance.yml (ASN section) not regenerated -- separate
IP->ASN pipeline, follow-up.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bx33CDbC3G8DQMQMARewof
The desktop nav shows the arcade pixel section icons (chokepoint,
attack-chain, trends, framework .png) next to each item, but the mobile
hamburger menu used generic hand-drawn SVG glyphs instead, breaking the
icon theme between desktop and mobile.
Swap the four section items' m-ic SVGs for the same pixel icons the
desktop nav uses; add a scoped .m-ic img rule (20px, image-rendering:
pixelated) so they stay crisp. Contribute keeps its glyph (it has no
section pixel icon on desktop either).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W87Fdr8vD1ZiR8jumj4Ud5
The supplementary variant cards showed a bare 'Hunt' badge while every
other rule card renders the tier's pixel icon (research/hunt/analyst.png)
inside the badge. All four supplementary variants are hunt-tier, so add
the hunt.png icon to match the established badge styling.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W87Fdr8vD1ZiR8jumj4Ud5
Adds four experimental Sigma variants extracted from the Detection
Chokepoints slide deck, covering angles the existing repo rules do not.
All are status: experimental and render in a new guarded 'Supplementary
Variants' block on their chokepoint page (mirrors the hunt-network
precedent: additive, only renders where the file exists).
New rules:
- clickfix/hunt-registry.yml ClickFix RunMRU/TypedPaths registry write
(URL + lure keywords/LOLBins) - registry_set
- clickfix/hunt-downloadfix.yml DownloadFix - browser-written :Zone.Identifier
ADS on a fix/repair-themed filename. Credits
mr.d0x (FileFix origin) and links jfmaes'
DownloadFix PoC (github.com/jfmaes/downloadfix)
- renamed-rmm/hunt-signer.yml Renamed RMM keyed on Authenticode Company
signer (durable vs image-name). EXAMPLE A-C
signer subset; full list from LOLRMM
- ransomware-service/hunt-process.yml Direct taskkill of a named EDR *process*
(vs the service-name rules). Sophos example
Plumbing (additive, cannot affect other pages):
- scripts/aggregate.py: register the four new basenames in SIGMA_LEVELS
- _layouts/chokepoint.html: guarded 'Supplementary Variants' block that
inlines any present variant with GitHub/Download/Copy actions
Provenance: transcribed from Detection Chokepoints.pdf (rules were embedded
images). renamed-rmm signer list and ransomware process list are deliberate
illustrative subsets, documented inline. Detection-reviewer pass: 3 APPROVED,
downloadfix revised (dropped mismapped T1553.005). Rules are authored, NOT
capture-validated - experimental until telemetry confirms.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W87Fdr8vD1ZiR8jumj4Ud5
Audit of the live site found 42 OSINT pivot cards: 1 real pivot with
no URL at all (aitm-websocket-relay), and 4 whose link diverged from
the query shown on the card. Policy applied: the query on the card is
exactly what the link executes; where a platform cannot express the
query, the displayed query is rewritten to the platform's real syntax.
- aitm-websocket-relay/URLScan: original query was invalid on the
platform (page.ip.asn is not a field; filename:*.js is a rejected
leading wildcard). Rewritten to (page.asn:AS37963 OR page.asn:AS9009)
AND page.status:200 AND page.mimeType:"application/javascript" -
verified live, 1583 results as of 2026-07-13 - and URL added
- lsass/LOLDrivers: site has no deep-linkable query syntax; displayed
query is now the free-text term to type (lsass), guidance in Notes
- lsass/ANY.RUN: ?search= URL parameter is ignored by the app
(verified live); same free-text treatment (sekurlsa)
- edr-bypass/GitHub: link now carries the full query incl. the
(path:*.c OR path:*.asm) qualifiers; query parenthesized
- renamed-rmm/VirusTotal: link now carries all four metadata: terms,
not just AnyDesk
- schema/chokepoint-schema.yml: document the URL field (template had
it, schema did not - why contributors kept omitting it)
graph-api-recon-burst's N/A card is intentional (not externally
observable) and left as-is.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W87Fdr8vD1ZiR8jumj4Ud5
theme-arcade.css opened with a cross-origin @import to Google Fonts,
which delayed the whole overlay sheet: H1s painted white from
style.css first, then snapped orange when the arcade layer applied.
On slow or mobile connections both states were visible, reading as
inconsistent heading colors across pages.
- Self-host Press Start 2P + VT323 woff2 (OFL) under assets/fonts/,
replace the @import with local @font-face blocks
- Preload the two latin subsets in the default layout head
- Drop the dead 'color: var(--text)' H1 declarations on the three
trend pages (clickgrab, edge-exploits, masq-infra) that the
overlay's !important was silently overriding; arcade orange is
the confirmed canonical H1 treatment sitewide
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W87Fdr8vD1ZiR8jumj4Ud5
Merges the new Defused export (Jun 10 - Jul 3) into the accumulating
edge-exploits history: 25,420 -> 75,420 events. CitrixBleed 2 (CVE-2025-5777)
exploitation jumped 11,145 -> 56,338 hits, NetScaler now >90% of decoy traffic.
transform_defused_csv.py now detects two conditions automatically instead of
relying on hardcoded date constants:
- Gap days: no export covers May 20 - Jun 9, 2026 (21 days), rendered as a
visible gap on the page.
- Row-cap truncation: this export hit a suspected 50,000-row console cap
(unverified exact limit) with a clean mid-record cutoff on its oldest day,
Jun 10 -- flagged partial (undercounts) rather than dropped or trusted as-is.
index.html's gap/volume text is now Liquid-bound to meta.date_range_note and
meta.live_decoy_count instead of hardcoded, so it won't go stale on the next
refresh. The daily chart distinguishes row-cap-partial days from the existing
export-cutoff artifact day.
--check-seed passes clean against the original seed data.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011suj1d1CVCVeJDtgPKrMzi
A shared link now signals what it is — a new chokepoint, attack chain, or trends
entry — instead of the generic site card. Home and generic pages keep og.png.
- templates/og-card.html: HTML card template (build tool, excluded from site),
rendered at 1200x630 with Press Start 2P / VT323 + the section pixel icon.
- assets/img/social/og-{chokepoints,attack-chains,trends}.png: the three cards.
- assets/img/pixel/trends.png: stripped the baked-in U-frame so the wave icon
floats like the other nav icons.
- _config.yml: scoped jekyll-seo-tag defaults (chokepoints collection /
attack-chains / trends); site-wide default unchanged.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CrCkcgXrEpHAiJRUhU9mFm
Selecting 2+ actors on any attack-chain page now highlights the techniques they
all share in cyan (.state-converge) and fades single-actor cells (.state-partial),
so the convergence reads without inspecting per-actor dots. The same selection
mirrors onto the convergence matrix: selected actors' rows light in their own
colour, the rest dim, and the chokepoint (tfoot) invariant row stays fixed.
Legend hint updated to describe the cyan glow.
Verified on the ransomware page (Akira+Play = 19 shared cyan cells) at 1440 and
375 breakpoints, 0 console errors.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CrCkcgXrEpHAiJRUhU9mFm
The daily cron cut a fresh dated branch (data/clickgrab-${DATE}) and opened
a new PR every run. Since each PR edits the tail + meta of the same growing
_data/clickgrab_trends.yml, they mutually conflict the moment one merges,
leaving a pileup of stuck PRs (#146/#147/#148).
Fixes the structure rather than the symptom:
- Publish to a fixed rolling branch (data/clickgrab-auto), force-pushed each
run and refreshed via `gh pr edit`, so at most one ClickGrab PR is ever
open and it always shows a clean append-only diff vs main.
- Drop cadence from daily to weekly (Mondays 06:00 UTC). The generator's
14-day lookback + watermark dedup backfills every daily bucket regardless,
so weekly captures the same data with far less churn.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YQzGNdzZK4svMZPTK9BikA