mirror of
https://github.com/iimp0ster/detection-chokepoints
synced 2026-08-09 12:41:00 +00:00
chore(trends): refresh edge-exploits from Jul 3 export, flag gap + row-cap day
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
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
3853e3c041
commit
3ace655d55
@@ -2,6 +2,22 @@
|
||||
|
||||
All notable changes to this detection chokepoints repository will be documented in this file.
|
||||
|
||||
## [2026-07-03] - Edge-exploits trend refresh (Jun 10 - Jul 3, 2026 export)
|
||||
|
||||
Source: Defused Cyber honeypot telemetry, manual console export (`export_shared_20260703_183931.csv`)
|
||||
|
||||
### Changed
|
||||
|
||||
- `_data/edge_exploits.yml`, `_data/edge_exploits_provenance.yml` — merged the new export; total events 25,420 → 75,420. CitrixBleed 2 (CVE-2025-5777) exploitation jumped 11,145 → 56,338 hits, Citrix NetScaler now >90% of decoy traffic.
|
||||
- `trends/edge-exploits/index.html` — chart caption and volume blurb now pull `meta.date_range_note` / `meta.live_decoy_count` via Liquid instead of hardcoded text, so they stay in sync on future refreshes. Daily chart flags row-cap-truncated days (new `partial` styling, distinct from the existing export-cutoff `artifact` styling).
|
||||
- `scripts/transform_defused_csv.py` — generalized gap detection (previously hardcoded to the one-time Apr 14-18 baseline seam) to scan the full live window every run, and added detection for row-capped exports (Defused's console appears to cap at 50,000 rows; `unverified:` no documented limit found, inferred from this export's clean mid-record cutoff).
|
||||
|
||||
### Notes
|
||||
|
||||
- Confirmed gap: May 20 - Jun 9, 2026 (21 days) — no export was taken, no data recoverable.
|
||||
- Confirmed partial day: Jun 10, 2026 — the new export hit the suspected 50,000-row cap sorted newest-first, cutting off before covering the full day. Flagged on the page rather than excluded or silently trusted.
|
||||
- `--check-seed` regression-tested clean against the original May-only seed before merging the new export.
|
||||
|
||||
## [2026-05-29] - AiTM / Tycoon 2FA Chokepoints (4 new entries)
|
||||
|
||||
Source: Elastic Security Labs — Tycoon 2FA AiTM Detection Engineering (2026-05-27)
|
||||
|
||||
+445
-118
@@ -7,114 +7,138 @@ meta:
|
||||
source_url: https://defusedcyber.com/
|
||||
severity_scope: high and critical severity alerts only
|
||||
baseline_window: 'Mar 14 - Apr 13, 2026'
|
||||
live_window: 'Apr 19 - May 19, 2026'
|
||||
date_range: 'Mar 14 - May 19, 2026'
|
||||
date_range_note: 'two export windows, 6-day gap Apr 14-18'
|
||||
total_events: 25420
|
||||
total_display: 25.4k
|
||||
total_events_display: '25,420'
|
||||
live_window: 'Apr 19 - Jul 3, 2026'
|
||||
date_range: 'Mar 14 - Jul 3, 2026'
|
||||
date_range_note: 'two export windows, 6-day gap Apr 14-18; gap May 20-Jun 9 (no export covers this period); Jun 10 partial (export hit the row cap; data begins partway through the day)'
|
||||
total_events: 75420
|
||||
total_display: 75.4k
|
||||
total_events_display: '75,420'
|
||||
decoy_count_display: 25+
|
||||
cve_count_display: 50+
|
||||
live_decoy_count: 27
|
||||
live_cve_count: 38
|
||||
live_unique_ips: 1034
|
||||
generated: '2026-06-14'
|
||||
live_decoy_count: 35
|
||||
live_cve_count: 54
|
||||
live_unique_ips: 1662
|
||||
generated: '2026-07-03'
|
||||
headline:
|
||||
- key: citrixbleed2
|
||||
label: CitrixBleed 2
|
||||
cve: CVE-2025-5777
|
||||
count: 11145
|
||||
display: '11,145'
|
||||
count: 56338
|
||||
display: '56,338'
|
||||
- key: nextjs_rce
|
||||
label: Next.js RCE (new)
|
||||
cve: CVE-2025-55182
|
||||
count: 2683
|
||||
display: '2,683'
|
||||
count: 4997
|
||||
display: '4,997'
|
||||
- key: cpanel_whm
|
||||
label: cPanel WHM chain
|
||||
cve: CVE-2026-41940
|
||||
count: 1515
|
||||
display: '1,515'
|
||||
count: 1728
|
||||
display: '1,728'
|
||||
targets:
|
||||
- name: Citrix NetScaler
|
||||
count: 11995
|
||||
display: '11,995'
|
||||
count: 57261
|
||||
display: '57,261'
|
||||
- name: React Server
|
||||
count: 2683
|
||||
display: '2,683'
|
||||
count: 4997
|
||||
display: '4,997'
|
||||
- name: FortiWeb
|
||||
count: 2037
|
||||
display: '2,037'
|
||||
count: 2336
|
||||
display: '2,336'
|
||||
- name: cPanel WHM
|
||||
count: 1515
|
||||
display: '1,515'
|
||||
- name: Cisco SD-WAN
|
||||
count: 1383
|
||||
display: '1,383'
|
||||
count: 1728
|
||||
display: '1,728'
|
||||
- name: SAP Netweaver
|
||||
count: 1341
|
||||
display: '1,341'
|
||||
- name: Ivanti Connect Secure
|
||||
count: 1035
|
||||
display: '1,035'
|
||||
count: 1465
|
||||
display: '1,465'
|
||||
- name: Cisco SD-WAN
|
||||
count: 1435
|
||||
display: '1,435'
|
||||
- name: SonicWall SMA
|
||||
count: 834
|
||||
display: '834'
|
||||
count: 1257
|
||||
display: '1,257'
|
||||
- name: Ivanti Connect Secure
|
||||
count: 1240
|
||||
display: '1,240'
|
||||
- name: F5 Big-IP Legacy
|
||||
count: 272
|
||||
display: '272'
|
||||
count: 507
|
||||
display: '507'
|
||||
- name: F5 Big-IP
|
||||
count: 213
|
||||
display: '213'
|
||||
count: 304
|
||||
display: '304'
|
||||
- name: Fortinet FortiSandbox
|
||||
count: 184
|
||||
display: '184'
|
||||
- name: Palo Alto GlobalProtect
|
||||
count: 145
|
||||
display: '145'
|
||||
count: 172
|
||||
display: '172'
|
||||
- name: Cisco Unified Communications Manager
|
||||
count: 167
|
||||
display: '167'
|
||||
- name: Ivanti EPMM
|
||||
count: 72
|
||||
display: '72'
|
||||
- name: Cisco Identity Services Engine
|
||||
count: 56
|
||||
display: '56'
|
||||
count: 151
|
||||
display: '151'
|
||||
- name: Ubiquiti UniFi OS Server
|
||||
count: 126
|
||||
display: '126'
|
||||
- name: SharePoint
|
||||
count: 48
|
||||
display: '48'
|
||||
count: 81
|
||||
display: '81'
|
||||
- name: FortiGate
|
||||
count: 41
|
||||
display: '41'
|
||||
count: 64
|
||||
display: '64'
|
||||
- name: Cisco Identity Services Engine
|
||||
count: 60
|
||||
display: '60'
|
||||
- name: Fortinet FortiClient EMS
|
||||
count: 25
|
||||
display: '25'
|
||||
count: 46
|
||||
display: '46'
|
||||
- name: Drupal CMS (PostgreSQL)
|
||||
count: 33
|
||||
display: '33'
|
||||
- name: Oracle E-Business
|
||||
count: 18
|
||||
display: '18'
|
||||
count: 31
|
||||
display: '31'
|
||||
- name: FortiSIEM
|
||||
count: 9
|
||||
display: '9'
|
||||
count: 17
|
||||
display: '17'
|
||||
- name: Sitecore XP
|
||||
count: 8
|
||||
display: '8'
|
||||
count: 16
|
||||
display: '16'
|
||||
- name: BeyondTrust Remote Support
|
||||
count: 14
|
||||
display: '14'
|
||||
- name: Check Point Mobile Access SSL VPN
|
||||
count: 13
|
||||
display: '13'
|
||||
- name: Cisco Smart Software Manager On-Prem
|
||||
count: 7
|
||||
display: '7'
|
||||
count: 12
|
||||
display: '12'
|
||||
- name: GoAnywhere MFT
|
||||
count: 12
|
||||
display: '12'
|
||||
- name: SolarWinds Serv-U
|
||||
count: 7
|
||||
display: '7'
|
||||
- name: VMware vCenter
|
||||
count: 6
|
||||
display: '6'
|
||||
- name: Cisco IOS XE
|
||||
count: 4
|
||||
display: '4'
|
||||
- name: Jenkins Server
|
||||
count: 4
|
||||
display: '4'
|
||||
- name: Windows WSUS
|
||||
count: 4
|
||||
display: '4'
|
||||
- name: BeyondTrust Remote Support
|
||||
count: 3
|
||||
display: '3'
|
||||
- name: Atlassian Jira
|
||||
count: 2
|
||||
display: '2'
|
||||
- name: SolarWinds Web Help Desk
|
||||
count: 2
|
||||
display: '2'
|
||||
- name: Cisco IOS XE
|
||||
count: 1
|
||||
display: '1'
|
||||
- name: VMware vCenter
|
||||
- name: N8N
|
||||
count: 1
|
||||
display: '1'
|
||||
daily:
|
||||
@@ -347,9 +371,169 @@ daily:
|
||||
total: 101
|
||||
unique_ips: 52
|
||||
- date: '2026-05-19'
|
||||
label: May 19*
|
||||
label: May 19
|
||||
total: 3084
|
||||
unique_ips: 45
|
||||
- date: '2026-05-20'
|
||||
label: ''
|
||||
total: null
|
||||
- date: '2026-05-21'
|
||||
label: ''
|
||||
total: null
|
||||
- date: '2026-05-22'
|
||||
label: ''
|
||||
total: null
|
||||
- date: '2026-05-23'
|
||||
label: ''
|
||||
total: null
|
||||
- date: '2026-05-24'
|
||||
label: ''
|
||||
total: null
|
||||
- date: '2026-05-25'
|
||||
label: ''
|
||||
total: null
|
||||
- date: '2026-05-26'
|
||||
label: ''
|
||||
total: null
|
||||
- date: '2026-05-27'
|
||||
label: ''
|
||||
total: null
|
||||
- date: '2026-05-28'
|
||||
label: ''
|
||||
total: null
|
||||
- date: '2026-05-29'
|
||||
label: ''
|
||||
total: null
|
||||
- date: '2026-05-30'
|
||||
label: ''
|
||||
total: null
|
||||
- date: '2026-05-31'
|
||||
label: ''
|
||||
total: null
|
||||
- date: '2026-06-01'
|
||||
label: ''
|
||||
total: null
|
||||
- date: '2026-06-02'
|
||||
label: ''
|
||||
total: null
|
||||
- date: '2026-06-03'
|
||||
label: ''
|
||||
total: null
|
||||
- date: '2026-06-04'
|
||||
label: ''
|
||||
total: null
|
||||
- date: '2026-06-05'
|
||||
label: ''
|
||||
total: null
|
||||
- date: '2026-06-06'
|
||||
label: ''
|
||||
total: null
|
||||
- date: '2026-06-07'
|
||||
label: ''
|
||||
total: null
|
||||
- date: '2026-06-08'
|
||||
label: ''
|
||||
total: null
|
||||
- date: '2026-06-09'
|
||||
label: ''
|
||||
total: null
|
||||
- date: '2026-06-10'
|
||||
label: Jun 10†
|
||||
total: 36528
|
||||
unique_ips: 25
|
||||
partial: true
|
||||
- date: '2026-06-11'
|
||||
label: Jun 11
|
||||
total: 145
|
||||
unique_ips: 56
|
||||
- date: '2026-06-12'
|
||||
label: Jun 12
|
||||
total: 7090
|
||||
unique_ips: 67
|
||||
- date: '2026-06-13'
|
||||
label: Jun 13
|
||||
total: 161
|
||||
unique_ips: 48
|
||||
- date: '2026-06-14'
|
||||
label: Jun 14
|
||||
total: 105
|
||||
unique_ips: 47
|
||||
- date: '2026-06-15'
|
||||
label: Jun 15
|
||||
total: 70
|
||||
unique_ips: 31
|
||||
- date: '2026-06-16'
|
||||
label: Jun 16
|
||||
total: 139
|
||||
unique_ips: 59
|
||||
- date: '2026-06-17'
|
||||
label: Jun 17
|
||||
total: 149
|
||||
unique_ips: 63
|
||||
- date: '2026-06-18'
|
||||
label: Jun 18
|
||||
total: 126
|
||||
unique_ips: 63
|
||||
- date: '2026-06-19'
|
||||
label: Jun 19
|
||||
total: 182
|
||||
unique_ips: 61
|
||||
- date: '2026-06-20'
|
||||
label: Jun 20
|
||||
total: 100
|
||||
unique_ips: 50
|
||||
- date: '2026-06-21'
|
||||
label: Jun 21
|
||||
total: 115
|
||||
unique_ips: 57
|
||||
- date: '2026-06-22'
|
||||
label: Jun 22
|
||||
total: 237
|
||||
unique_ips: 66
|
||||
- date: '2026-06-23'
|
||||
label: Jun 23
|
||||
total: 1147
|
||||
unique_ips: 50
|
||||
- date: '2026-06-24'
|
||||
label: Jun 24
|
||||
total: 1062
|
||||
unique_ips: 56
|
||||
- date: '2026-06-25'
|
||||
label: Jun 25
|
||||
total: 152
|
||||
unique_ips: 58
|
||||
- date: '2026-06-26'
|
||||
label: Jun 26
|
||||
total: 149
|
||||
unique_ips: 54
|
||||
- date: '2026-06-27'
|
||||
label: Jun 27
|
||||
total: 128
|
||||
unique_ips: 51
|
||||
- date: '2026-06-28'
|
||||
label: Jun 28
|
||||
total: 603
|
||||
unique_ips: 49
|
||||
- date: '2026-06-29'
|
||||
label: Jun 29
|
||||
total: 1112
|
||||
unique_ips: 44
|
||||
- date: '2026-06-30'
|
||||
label: Jun 30
|
||||
total: 161
|
||||
unique_ips: 53
|
||||
- date: '2026-07-01'
|
||||
label: Jul 1
|
||||
total: 135
|
||||
unique_ips: 50
|
||||
- date: '2026-07-02'
|
||||
label: Jul 2
|
||||
total: 120
|
||||
unique_ips: 61
|
||||
- date: '2026-07-03'
|
||||
label: Jul 3*
|
||||
total: 84
|
||||
unique_ips: 30
|
||||
artifact: true
|
||||
cb2_daily:
|
||||
labels:
|
||||
@@ -382,85 +566,117 @@ cb2_daily:
|
||||
- 270
|
||||
cves:
|
||||
- id: CVE-2025-5777
|
||||
count: 3033
|
||||
count: 48226
|
||||
- id: CVE-2025-55182
|
||||
count: 2683
|
||||
count: 4997
|
||||
- id: CVE-2026-41940
|
||||
count: 1515
|
||||
count: 1728
|
||||
- id: CVE-2025-25257
|
||||
count: 966
|
||||
count: 1210
|
||||
- id: CVE-2025-40599
|
||||
count: 356
|
||||
count: 779
|
||||
- id: CVE-2022-1388
|
||||
count: 314
|
||||
count: 593
|
||||
- id: CVE-2023-46805
|
||||
count: 246
|
||||
- id: CVE-2023-46747
|
||||
count: 171
|
||||
count: 404
|
||||
- id: CVE-2025-31324
|
||||
count: 162
|
||||
- id: CVE-2024-3400
|
||||
count: 147
|
||||
count: 286
|
||||
- id: CVE-2023-46747
|
||||
count: 218
|
||||
- id: CVE-2026-3055
|
||||
count: 146
|
||||
count: 201
|
||||
- id: CVE-2026-20127
|
||||
count: 175
|
||||
- id: CVE-2024-3400
|
||||
count: 155
|
||||
- id: CVE-2026-20230
|
||||
count: 123
|
||||
- id: CVE-2019-19781
|
||||
count: 92
|
||||
- id: CVE-2026-39808
|
||||
count: 92
|
||||
- id: CVE-2026-39813
|
||||
count: 92
|
||||
- id: CVE-2025-53770
|
||||
count: 81
|
||||
- id: CVE-2026-34910
|
||||
count: 78
|
||||
- id: CVE-2023-4966
|
||||
count: 74
|
||||
- id: CVE-2025-20281
|
||||
count: 54
|
||||
- id: CVE-2025-53770
|
||||
count: 48
|
||||
count: 76
|
||||
- id: CVE-2025-64446
|
||||
count: 44
|
||||
- id: CVE-2022-40684
|
||||
count: 41
|
||||
count: 73
|
||||
- id: CVE-2025-4427
|
||||
count: 39
|
||||
- id: CVE-2019-11510
|
||||
count: 37
|
||||
- id: CVE-2026-21643
|
||||
count: 25
|
||||
count: 59
|
||||
- id: CVE-2026-1281
|
||||
count: 18
|
||||
- id: CVE-2024-21887
|
||||
count: 16
|
||||
count: 59
|
||||
- id: CVE-2019-11510
|
||||
count: 58
|
||||
- id: CVE-2025-20281
|
||||
count: 58
|
||||
- id: CVE-2022-40684
|
||||
count: 49
|
||||
- id: CVE-2026-34908
|
||||
count: 48
|
||||
- id: CVE-2026-20045
|
||||
count: 44
|
||||
- id: CVE-2023-35081
|
||||
count: 15
|
||||
- id: CVE-2025-61882
|
||||
count: 12
|
||||
count: 33
|
||||
- id: CVE-2026-9082
|
||||
count: 33
|
||||
- id: CVE-2024-21887
|
||||
count: 29
|
||||
- id: CVE-2026-21643
|
||||
count: 28
|
||||
- id: CVE-2026-0257
|
||||
count: 19
|
||||
- id: CVE-2018-13379
|
||||
count: 18
|
||||
- id: CVE-2026-35616
|
||||
count: 18
|
||||
- id: CVE-2025-64155
|
||||
count: 9
|
||||
- id: CVE-2023-35813
|
||||
count: 8
|
||||
- id: CVE-2024-0204
|
||||
count: 7
|
||||
- id: CVE-2024-20419
|
||||
count: 7
|
||||
count: 17
|
||||
- id: CVE-2022-21587
|
||||
count: 16
|
||||
- id: CVE-2023-35813
|
||||
count: 16
|
||||
- id: CVE-2025-61882
|
||||
count: 15
|
||||
- id: CVE-2026-1731
|
||||
count: 14
|
||||
- id: CVE-2026-50751
|
||||
count: 13
|
||||
- id: CVE-2024-0204
|
||||
count: 12
|
||||
- id: CVE-2024-20419
|
||||
count: 12
|
||||
- id: CVE-2023-27997
|
||||
count: 8
|
||||
- id: CVE-2024-21893
|
||||
count: 8
|
||||
- id: CVE-2024-28995
|
||||
count: 7
|
||||
- id: CVE-2021-21972
|
||||
count: 6
|
||||
- id: CVE-2023-20198
|
||||
count: 4
|
||||
- id: CVE-2024-43044
|
||||
count: 4
|
||||
- id: CVE-2025-59287
|
||||
count: 4
|
||||
- id: CVE-2026-1731
|
||||
count: 3
|
||||
- id: CVE-2022-0540
|
||||
count: 2
|
||||
- id: CVE-2023-3519
|
||||
count: 2
|
||||
- id: CVE-2025-20337
|
||||
count: 2
|
||||
- id: CVE-2021-21972
|
||||
count: 1
|
||||
- id: CVE-2023-20198
|
||||
count: 1
|
||||
- id: CVE-2024-21893
|
||||
- id: CVE-2026-8451
|
||||
count: 2
|
||||
- id: CVE-2025-68613
|
||||
count: 1
|
||||
exploit_recon:
|
||||
exploit_total: 7005
|
||||
recon_total: 3414
|
||||
exploit_pct: 67
|
||||
exploit_total: 53946
|
||||
recon_total: 6473
|
||||
exploit_pct: 89
|
||||
daily:
|
||||
- date: '2026-04-19'
|
||||
label: Apr 19
|
||||
@@ -586,7 +802,118 @@ exploit_recon:
|
||||
label: May 19
|
||||
exploit: 3030
|
||||
recon: 54
|
||||
- date: '2026-06-10'
|
||||
label: Jun 10
|
||||
exploit: 36508
|
||||
recon: 20
|
||||
- date: '2026-06-11'
|
||||
label: Jun 11
|
||||
exploit: 95
|
||||
recon: 50
|
||||
- date: '2026-06-12'
|
||||
label: Jun 12
|
||||
exploit: 6997
|
||||
recon: 93
|
||||
- date: '2026-06-13'
|
||||
label: Jun 13
|
||||
exploit: 126
|
||||
recon: 35
|
||||
- date: '2026-06-14'
|
||||
label: Jun 14
|
||||
exploit: 46
|
||||
recon: 59
|
||||
- date: '2026-06-15'
|
||||
label: Jun 15
|
||||
exploit: 38
|
||||
recon: 32
|
||||
- date: '2026-06-16'
|
||||
label: Jun 16
|
||||
exploit: 88
|
||||
recon: 51
|
||||
- date: '2026-06-17'
|
||||
label: Jun 17
|
||||
exploit: 71
|
||||
recon: 78
|
||||
- date: '2026-06-18'
|
||||
label: Jun 18
|
||||
exploit: 67
|
||||
recon: 59
|
||||
- date: '2026-06-19'
|
||||
label: Jun 19
|
||||
exploit: 83
|
||||
recon: 99
|
||||
- date: '2026-06-20'
|
||||
label: Jun 20
|
||||
exploit: 49
|
||||
recon: 51
|
||||
- date: '2026-06-21'
|
||||
label: Jun 21
|
||||
exploit: 69
|
||||
recon: 46
|
||||
- date: '2026-06-22'
|
||||
label: Jun 22
|
||||
exploit: 170
|
||||
recon: 67
|
||||
- date: '2026-06-23'
|
||||
label: Jun 23
|
||||
exploit: 1091
|
||||
recon: 56
|
||||
- date: '2026-06-24'
|
||||
label: Jun 24
|
||||
exploit: 915
|
||||
recon: 147
|
||||
- date: '2026-06-25'
|
||||
label: Jun 25
|
||||
exploit: 49
|
||||
recon: 103
|
||||
- date: '2026-06-26'
|
||||
label: Jun 26
|
||||
exploit: 45
|
||||
recon: 104
|
||||
- date: '2026-06-27'
|
||||
label: Jun 27
|
||||
exploit: 68
|
||||
recon: 60
|
||||
- date: '2026-06-28'
|
||||
label: Jun 28
|
||||
exploit: 82
|
||||
recon: 521
|
||||
- date: '2026-06-29'
|
||||
label: Jun 29
|
||||
exploit: 34
|
||||
recon: 1078
|
||||
- date: '2026-06-30'
|
||||
label: Jun 30
|
||||
exploit: 106
|
||||
recon: 55
|
||||
- date: '2026-07-01'
|
||||
label: Jul 1
|
||||
exploit: 57
|
||||
recon: 78
|
||||
- date: '2026-07-02'
|
||||
label: Jul 2
|
||||
exploit: 49
|
||||
recon: 71
|
||||
- date: '2026-07-03'
|
||||
label: Jul 3
|
||||
exploit: 38
|
||||
recon: 46
|
||||
lead_times:
|
||||
- cve: CVE-2024-21893
|
||||
recon_first: '2026-05-01'
|
||||
exploit_first: '2026-06-17'
|
||||
lead_days: 47
|
||||
exploit_count: 1
|
||||
- cve: CVE-2023-20198
|
||||
recon_first: '2026-05-18'
|
||||
exploit_first: '2026-06-27'
|
||||
lead_days: 40
|
||||
exploit_count: 1
|
||||
- cve: CVE-2026-20045
|
||||
recon_first: '2026-06-12'
|
||||
exploit_first: '2026-06-27'
|
||||
lead_days: 15
|
||||
exploit_count: 4
|
||||
- cve: CVE-2025-55182
|
||||
recon_first: '2026-04-19'
|
||||
exploit_first: '2026-04-25'
|
||||
@@ -596,9 +923,9 @@ lead_times:
|
||||
recon_first: '2026-04-22'
|
||||
exploit_first: '2026-04-26'
|
||||
lead_days: 4
|
||||
exploit_count: 113
|
||||
exploit_count: 130
|
||||
- cve: CVE-2025-4427
|
||||
recon_first: '2026-04-27'
|
||||
exploit_first: '2026-04-29'
|
||||
lead_days: 2
|
||||
exploit_count: 24
|
||||
exploit_count: 44
|
||||
|
||||
@@ -3,15 +3,37 @@
|
||||
|
||||
meta:
|
||||
source: 'Defused honeypot attacker IPs, enriched via Team Cymru (+ IPinfo cross-check)'
|
||||
generated: '2026-06-15'
|
||||
window: Apr 2026 - May 2026
|
||||
cumulative_unique_ips: 1029
|
||||
generated: '2026-07-03'
|
||||
window: Apr 2026 - Jul 2026
|
||||
cumulative_unique_ips: 1664
|
||||
bulletproof_pct: 0
|
||||
total_events: 10419
|
||||
total_events: 60419
|
||||
month_labels:
|
||||
- Apr 2026
|
||||
- May 2026
|
||||
- Jun 2026
|
||||
- Jul 2026
|
||||
providers:
|
||||
- name: Data Campus Limited
|
||||
asn: 215929
|
||||
bulletproof: false
|
||||
total: 36484
|
||||
display: '36,484'
|
||||
series:
|
||||
- 0
|
||||
- 1
|
||||
- 36483
|
||||
- 0
|
||||
- name: Emil Vitukhnovskii trading a
|
||||
asn: 202226
|
||||
bulletproof: false
|
||||
total: 4710
|
||||
display: '4,710'
|
||||
series:
|
||||
- 0
|
||||
- 9
|
||||
- 4701
|
||||
- 0
|
||||
- name: H2NEXUS LTD
|
||||
asn: 215730
|
||||
bulletproof: false
|
||||
@@ -20,102 +42,96 @@ providers:
|
||||
series:
|
||||
- 43
|
||||
- 3067
|
||||
- 0
|
||||
- 0
|
||||
- name: Fast Servers (Pty) Ltd
|
||||
asn: 43444
|
||||
bulletproof: false
|
||||
total: 2193
|
||||
display: '2,193'
|
||||
series:
|
||||
- 0
|
||||
- 2
|
||||
- 2191
|
||||
- 0
|
||||
- name: 'Amazon.com, Inc.'
|
||||
asn: 16509
|
||||
bulletproof: false
|
||||
total: 1049
|
||||
display: '1,049'
|
||||
total: 2083
|
||||
display: '2,083'
|
||||
series:
|
||||
- 1039
|
||||
- 10
|
||||
- name: 'No.31,Jin-rong Street'
|
||||
asn: 4134
|
||||
- 1034
|
||||
- 0
|
||||
- name: Omegatech LTD
|
||||
asn: 202412
|
||||
bulletproof: false
|
||||
total: 883
|
||||
display: '883'
|
||||
total: 1933
|
||||
display: '1,933'
|
||||
series:
|
||||
- 864
|
||||
- 19
|
||||
- name: 'DigitalOcean, LLC'
|
||||
asn: 14061
|
||||
bulletproof: false
|
||||
total: 498
|
||||
display: '498'
|
||||
series:
|
||||
- 120
|
||||
- 378
|
||||
- name: Hurricane Electric LLC
|
||||
asn: 6939
|
||||
bulletproof: false
|
||||
total: 452
|
||||
display: '452'
|
||||
series:
|
||||
- 126
|
||||
- 326
|
||||
- name: 'The Constant Company, LLC'
|
||||
asn: 20473
|
||||
bulletproof: false
|
||||
total: 357
|
||||
display: '357'
|
||||
series:
|
||||
- 164
|
||||
- 193
|
||||
- 0
|
||||
- 17
|
||||
- 1915
|
||||
- 1
|
||||
- name: Other
|
||||
asn: null
|
||||
bulletproof: false
|
||||
total: 4070
|
||||
display: '4,070'
|
||||
total: 9906
|
||||
display: '9,906'
|
||||
series:
|
||||
- 1276
|
||||
- 2794
|
||||
- 2550
|
||||
- 3681
|
||||
- 3337
|
||||
- 338
|
||||
asn_totals:
|
||||
- name: Data Campus Limited
|
||||
asn: 215929
|
||||
bulletproof: false
|
||||
events: 36484
|
||||
display: '36,484'
|
||||
- name: Emil Vitukhnovskii trading a
|
||||
asn: 202226
|
||||
bulletproof: false
|
||||
events: 4710
|
||||
display: '4,710'
|
||||
- name: H2NEXUS LTD
|
||||
asn: 215730
|
||||
bulletproof: false
|
||||
events: 3110
|
||||
display: '3,110'
|
||||
- name: Fast Servers (Pty) Ltd
|
||||
asn: 43444
|
||||
bulletproof: false
|
||||
events: 2193
|
||||
display: '2,193'
|
||||
- name: 'Amazon.com, Inc.'
|
||||
asn: 16509
|
||||
bulletproof: false
|
||||
events: 1049
|
||||
display: '1,049'
|
||||
- name: 'No.31,Jin-rong Street'
|
||||
asn: 4134
|
||||
events: 2083
|
||||
display: '2,083'
|
||||
- name: Omegatech LTD
|
||||
asn: 202412
|
||||
bulletproof: false
|
||||
events: 883
|
||||
display: '883'
|
||||
events: 1933
|
||||
display: '1,933'
|
||||
- name: 'DigitalOcean, LLC'
|
||||
asn: 14061
|
||||
bulletproof: false
|
||||
events: 498
|
||||
display: '498'
|
||||
events: 984
|
||||
display: '984'
|
||||
- name: 'No.31,Jin-rong Street'
|
||||
asn: 4134
|
||||
bulletproof: false
|
||||
events: 898
|
||||
display: '898'
|
||||
- name: Hurricane Electric LLC
|
||||
asn: 6939
|
||||
bulletproof: false
|
||||
events: 452
|
||||
display: '452'
|
||||
- name: 'The Constant Company, LLC'
|
||||
asn: 20473
|
||||
events: 713
|
||||
display: '713'
|
||||
- name: Google LLC
|
||||
asn: 396982
|
||||
bulletproof: false
|
||||
events: 357
|
||||
display: '357'
|
||||
- name: TechTies Inc.
|
||||
asn: 197170
|
||||
bulletproof: false
|
||||
events: 334
|
||||
display: '334'
|
||||
- name: VPSVAULT.HOST LTD
|
||||
asn: 215925
|
||||
bulletproof: false
|
||||
events: 253
|
||||
display: '253'
|
||||
- name: Tianfeng (Hong Kong) Communi
|
||||
asn: 213802
|
||||
bulletproof: false
|
||||
events: 245
|
||||
display: '245'
|
||||
- name: PacketHub S.A.
|
||||
asn: 147049
|
||||
bulletproof: false
|
||||
events: 209
|
||||
display: '209'
|
||||
events: 682
|
||||
display: '682'
|
||||
|
||||
@@ -33,7 +33,7 @@ import glob
|
||||
import os
|
||||
import re
|
||||
from collections import Counter
|
||||
from datetime import date
|
||||
from datetime import date, timedelta
|
||||
from pathlib import Path
|
||||
|
||||
import yaml
|
||||
@@ -66,6 +66,14 @@ HEADLINE = [
|
||||
# The 6-day hole between the two export windows; rendered as a visible gap.
|
||||
GAP_DAYS = ["2026-04-14", "2026-04-15", "2026-04-16", "2026-04-17", "2026-04-18"]
|
||||
|
||||
# Defused's console export appears to cap at 50,000 rows: the 2026-07-03 export hit
|
||||
# exactly 50,000 with a clean mid-record cutoff on its oldest day (sorted newest-first,
|
||||
# so the cap truncates the START of the window, not the end). unverified: no documented
|
||||
# limit found; inferred from one observation. When a file hits this, its oldest day is
|
||||
# an undercount -- flagged as partial rather than dropped, matching how the artifact day
|
||||
# (newest day, export-time cutoff) is already flagged rather than excluded.
|
||||
EXPORT_ROW_CAP = 50000
|
||||
|
||||
|
||||
class _QuoteCommaDumper(yaml.SafeDumper):
|
||||
"""SafeDumper that single-quotes strings containing a comma, so display
|
||||
@@ -86,6 +94,22 @@ def label_for(iso: str) -> str:
|
||||
return f"{MONTHS[m]} {d}"
|
||||
|
||||
|
||||
def _consecutive_ranges(isos):
|
||||
"""Sorted iso date strings -> list of (start, end) for each consecutive run.
|
||||
Used to collapse a list of missing days into human-readable gap ranges."""
|
||||
if not isos:
|
||||
return []
|
||||
isos = sorted(isos)
|
||||
ranges = [[isos[0], isos[0]]]
|
||||
for iso in isos[1:]:
|
||||
prev_end = date.fromisoformat(ranges[-1][1])
|
||||
if date.fromisoformat(iso) == prev_end + timedelta(days=1):
|
||||
ranges[-1][1] = iso
|
||||
else:
|
||||
ranges.append([iso, iso])
|
||||
return [(r[0], r[1]) for r in ranges]
|
||||
|
||||
|
||||
def human(n: int) -> str:
|
||||
return f"{n / 1000:.1f}k" if n >= 1000 else str(n)
|
||||
|
||||
@@ -100,14 +124,17 @@ def classify(alert: str) -> str:
|
||||
|
||||
|
||||
def aggregate_file(path):
|
||||
"""One export CSV -> {iso_date: {total, ips:set, cve:Counter, decoy:Counter}}.
|
||||
"""One export CSV -> ({iso_date: {total, ips:set, cve:Counter, decoy:Counter}}, row_count).
|
||||
|
||||
Counts every row -- see module docstring on why there is no row-level dedup.
|
||||
Cross-export overlap is resolved at the day level in build() (newest wins).
|
||||
row_count lets build() detect a row-capped (truncated) export.
|
||||
"""
|
||||
days = {}
|
||||
n = 0
|
||||
with open(path, encoding="utf-8", newline="") as f:
|
||||
for r in csv.DictReader(f):
|
||||
n += 1
|
||||
iso = (r.get("Datetime") or "")[:10]
|
||||
if not iso:
|
||||
continue
|
||||
@@ -127,7 +154,7 @@ def aggregate_file(path):
|
||||
if m:
|
||||
rec["cve"][m.group(0)] += 1
|
||||
rec["cve_cls"][(m.group(0), cls)] += 1
|
||||
return days
|
||||
return days, n
|
||||
|
||||
|
||||
def build(paths):
|
||||
@@ -137,17 +164,35 @@ def build(paths):
|
||||
# one (newest is most complete). Disjoint windows simply union.
|
||||
live_days = {}
|
||||
seen_days = set()
|
||||
# (path, oldest_date, that_file's_count_for_oldest_date) for every capped export --
|
||||
# resolved to a final partial-day set AFTER the merge, since a later (uncapped)
|
||||
# export covering the same day would overwrite it with a complete count.
|
||||
capped_candidates = []
|
||||
for p in sorted(paths):
|
||||
fdays = aggregate_file(p)
|
||||
fdays, row_count = aggregate_file(p)
|
||||
overlap = seen_days & set(fdays)
|
||||
if overlap:
|
||||
print(f" WARN {p.name}: {len(overlap)} day(s) overlap an earlier "
|
||||
"export; replaced with this (newer) export's counts.")
|
||||
if row_count >= EXPORT_ROW_CAP and fdays:
|
||||
oldest = min(fdays)
|
||||
capped_candidates.append((p, oldest, fdays[oldest]["total"]))
|
||||
live_days.update(fdays)
|
||||
seen_days |= set(fdays)
|
||||
if not live_days:
|
||||
raise SystemExit("No dated rows parsed from the export(s).")
|
||||
|
||||
partial_old_days = set()
|
||||
for p, oldest, day_total in capped_candidates:
|
||||
if live_days[oldest]["total"] == day_total:
|
||||
partial_old_days.add(oldest)
|
||||
print(f" WARN {p.name}: hit the {EXPORT_ROW_CAP}-row export cap -- "
|
||||
f"oldest day {oldest} is likely PARTIAL (undercounts; flagged "
|
||||
"on the page, not excluded).")
|
||||
else:
|
||||
print(f" {p.name}: oldest day {oldest} was capped in this export but "
|
||||
"a later export supplied a complete count for that day -- not flagged.")
|
||||
|
||||
live_total = sum(d["total"] for d in live_days.values())
|
||||
live_cve, live_decoy, live_ips = Counter(), Counter(), set()
|
||||
for d in live_days.values():
|
||||
@@ -197,25 +242,62 @@ def build(paths):
|
||||
"count": count, "display": f"{count:,}"})
|
||||
|
||||
artifact_day = max(live_days)
|
||||
live_min, live_max = min(live_days), max(live_days)
|
||||
|
||||
# Any day between the earliest and latest live-window date with no export
|
||||
# covering it is a genuine gap -- distinct from GAP_DAYS (the one-time, frozen
|
||||
# baseline-to-live seam). Detected fresh every run so a new gap (e.g. exports
|
||||
# not taken for weeks) shows up automatically instead of needing a code edit.
|
||||
full_range = []
|
||||
d = date.fromisoformat(live_min)
|
||||
end = date.fromisoformat(live_max)
|
||||
while d <= end:
|
||||
full_range.append(d.isoformat())
|
||||
d += timedelta(days=1)
|
||||
missing_days = [iso for iso in full_range if iso not in live_days]
|
||||
if missing_days:
|
||||
print(f" WARN: {len(missing_days)} day(s) in the live window have no export "
|
||||
f"coverage ({missing_days[0]} to {missing_days[-1]}) -- rendered as a gap.")
|
||||
|
||||
daily = []
|
||||
for row in baseline["daily"]:
|
||||
daily.append({"date": row["date"], "label": label_for(row["date"]),
|
||||
"total": row["total"]})
|
||||
for iso in GAP_DAYS:
|
||||
daily.append({"date": iso, "label": "", "total": None})
|
||||
for iso in sorted(live_days):
|
||||
for iso in full_range:
|
||||
if iso in missing_days:
|
||||
daily.append({"date": iso, "label": "", "total": None})
|
||||
continue
|
||||
d = live_days[iso]
|
||||
entry = {"date": iso,
|
||||
"label": label_for(iso) + ("*" if iso == artifact_day else ""),
|
||||
flags = ""
|
||||
if iso == artifact_day:
|
||||
flags += "*"
|
||||
if iso in partial_old_days:
|
||||
flags += "†"
|
||||
entry = {"date": iso, "label": label_for(iso) + flags,
|
||||
"total": d["total"], "unique_ips": len(d["ips"])}
|
||||
if iso == artifact_day:
|
||||
entry["artifact"] = True
|
||||
if iso in partial_old_days:
|
||||
entry["partial"] = True
|
||||
daily.append(entry)
|
||||
|
||||
total_events = baseline["total_events"] + live_total
|
||||
live_min, live_max = min(live_days), max(live_days)
|
||||
base_min = baseline["daily"][0]["date"]
|
||||
|
||||
notes = ["two export windows, 6-day gap Apr 14-18"]
|
||||
for gap_start, gap_end in _consecutive_ranges(missing_days):
|
||||
notes.append(
|
||||
f"gap {label_for(gap_start)}" +
|
||||
(f"-{label_for(gap_end)}" if gap_end != gap_start else "") +
|
||||
" (no export covers this period)")
|
||||
if partial_old_days:
|
||||
partial_label = ", ".join(label_for(iso) for iso in sorted(partial_old_days))
|
||||
notes.append(f"{partial_label} partial (export hit the row cap; "
|
||||
"data begins partway through the day)")
|
||||
date_range_note = "; ".join(notes)
|
||||
|
||||
out = {
|
||||
"meta": {
|
||||
"source": "Defused Cyber honeypot telemetry",
|
||||
@@ -224,7 +306,7 @@ def build(paths):
|
||||
"baseline_window": baseline["window"],
|
||||
"live_window": f"{label_for(live_min)} - {label_for(live_max)}, {live_max[:4]}",
|
||||
"date_range": f"{label_for(base_min)} - {label_for(live_max)}, {live_max[:4]}",
|
||||
"date_range_note": "two export windows, 6-day gap Apr 14-18",
|
||||
"date_range_note": date_range_note,
|
||||
"total_events": total_events,
|
||||
"total_display": human(total_events),
|
||||
"total_events_display": f"{total_events:,}",
|
||||
|
||||
@@ -355,11 +355,11 @@ permalink: /trends/edge-exploits/
|
||||
|
||||
<!-- ===== VOLUME ANALYSIS ===== -->
|
||||
<h2 id="volume">Monthly Volume: Daily Exploit Attempts</h2>
|
||||
<p>Daily hit volume across 22 decoy types. The spikes aren't gradual trends. They're specific campaigns lighting up.</p>
|
||||
<p>Daily hit volume across {{ site.data.edge_exploits.meta.live_decoy_count }} decoy types. The spikes aren't gradual trends. They're specific campaigns lighting up.</p>
|
||||
|
||||
<div class="chart-container">
|
||||
<canvas id="dailyChart" height="200"></canvas>
|
||||
<div class="chart-label">Daily exploit attempts. Mar 14 – May 19, 2026 (gap Apr 14–18 = no export data; May 19* = export cutoff artifact)</div>
|
||||
<div class="chart-label">Daily exploit attempts. {{ site.data.edge_exploits.meta.date_range }} ({{ site.data.edge_exploits.meta.date_range_note }})</div>
|
||||
</div>
|
||||
|
||||
<div class="callout callout-red">
|
||||
@@ -1079,6 +1079,7 @@ Chart.defaults.font.family = 'ui-monospace, monospace';
|
||||
Chart.defaults.font.size = 11;
|
||||
var edgeDaily = {{ site.data.edge_exploits.daily | jsonify | replace: '</', '<\/' }};
|
||||
var edgeArtifact = edgeDaily.map(function(d) { return !!d.artifact; });
|
||||
var edgePartial = edgeDaily.map(function(d) { return !!d.partial; });
|
||||
const dailyData = {
|
||||
labels: edgeDaily.map(function(d) { return d.label; }),
|
||||
datasets: [{
|
||||
@@ -1087,6 +1088,7 @@ const dailyData = {
|
||||
backgroundColor: function(ctx) {
|
||||
if (ctx.raw === null) return 'transparent';
|
||||
if (edgeArtifact[ctx.dataIndex]) return 'rgba(107,114,128,0.5)'; // export-cutoff artifact
|
||||
if (edgePartial[ctx.dataIndex]) return 'rgba(139,92,246,0.5)'; // export row-cap truncation
|
||||
var v = ctx.raw;
|
||||
if (v > 1000) return 'rgba(218,54,51,0.8)';
|
||||
if (v > 500) return 'rgba(240,136,62,0.7)';
|
||||
@@ -1112,9 +1114,9 @@ new Chart(document.getElementById('dailyChart'), {
|
||||
callbacks: {
|
||||
label: function(ctx) {
|
||||
if (ctx.raw === null) return null;
|
||||
return edgeArtifact[ctx.dataIndex]
|
||||
? ctx.raw + ' (export cutoff - likely artifact)'
|
||||
: ctx.raw + ' attempts';
|
||||
if (edgeArtifact[ctx.dataIndex]) return ctx.raw + ' (export cutoff - likely artifact)';
|
||||
if (edgePartial[ctx.dataIndex]) return ctx.raw + ' (partial day - export hit the row cap)';
|
||||
return ctx.raw + ' attempts';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user