Back to Intelligence

University of Copenhagen Data Breach: 520,000 Records Exposed — Detection and Response Playbook for Defenders

SA
Security Arsenal Team
October 28, 2026
13 min read

The University of Copenhagen — Denmark's largest university — has confirmed a data breach in which hackers stole personal information belonging to more than 520,000 individuals. That's not a rounding error. That's a population-scale exposure affecting students, staff, alumni, applicants, and research partners whose records lived in the university's systems.

For defenders, the headline number matters less than the pattern. Higher education institutions remain one of the most reliably compromised verticals we see in incident response engagements: sprawling attack surfaces, legacy student information systems, federated identity environments, thousands of semi-autonomous departments running their own infrastructure, and security budgets that rarely match the sensitivity of the data held. Universities store everything attackers monetize — national ID numbers, passport data, health-adjacent records, financial aid details, research data subject to export controls, and credentials that pivot cleanly into corporate and government networks through alumni reuse.

Public reporting on this incident has not yet disclosed a specific CVE or initial access vector. That doesn't diminish the defensive lesson — it sharpens it. When a half-million records walk out the door, the failure is almost never a single bug. It is a detection gap: bulk data movement that nobody was watching for. This post gives you the telemetry, queries, and hardening steps to close that gap in your own environment.

Technical Analysis: How These Breaches Actually Unfold

In the absence of a confirmed root cause from the university, the responsible thing for a practitioner to do is work from the attack chains we actually see in large-scale PII exfiltration from academic and public-sector environments. The overwhelming majority of these incidents trace to one of four initial access patterns:

1. Web application exploitation against student-facing portals. Student information systems (SIS), admissions portals, and course management platforms are internet-facing by design and frequently run unpatched frameworks or custom code with SQL injection and broken access control. Insecure direct object reference (IDOR) flaws — where incrementing a record ID in a URL returns someone else's data — are endemic in bespoke academic applications.

2. Stolen credentials against federated identity. Universities run SSO across hundreds of services. A single phished staff credential, combined with weak or inconsistently enforced MFA, yields access to HR systems, shared drives, and research repositories. MFA fatigue (push bombing) and adversary-in-the-middle phishing kits that steal session cookies remain the dominant credential-theft techniques in 2025–2026.

3. Compromised third-party or departmental infrastructure. A poorly maintained departmental WordPress instance, an exposed research database, or a managed service provider with shared credentials becomes the beachhead. Lateral movement from there into central identity or student records is often trivially easy because flat network trust is the norm in academia.

4. Direct database exposure. Misconfigured cloud storage, Elasticsearch or MongoDB instances without authentication, and backup files left on web-accessible paths continue to account for a significant share of mass-exposure events.

The Common Denominator: Bulk Access Without an Alarm

Regardless of entry point, the post-compromise phase of a 520,000-record breach looks the same and — critically — is highly observable:

  • A single account or service principal querying or exporting records at a volume far outside its baseline
  • Sequential enumeration of records (IDOR-style scraping) visible in web server logs
  • Database exports, mysqldump/pg_dump execution, or SELECT ... INTO OUTFILE patterns
  • Staging of large archives (zip/7z/rar) in web roots, temp directories, or user profiles
  • Outbound transfer of abnormally large data volumes to unfamiliar destinations, often over HTTPS to cloud storage or file-sharing services
  • Compression utilities and archive tools executed by accounts that have never run them before

If your monitoring stack would not fire on any of the above, that is your exposure — and it is fixable today.

Exploitation Status

No CVE has been publicly attributed to this incident, and none appears in the source reporting. We will not speculate with an identifier. Treat this as a confirmed, completed data exfiltration event. The defensive priority is validating that your own environment would detect and contain the same attack chain.

Detection & Response

The detections below target the post-compromise behaviors common to mass PII theft — bulk data access, archive staging, and anomalous egress. They are tuned to fire on genuinely suspicious patterns, not routine administration. Deploy them against your web tier, database tier, and endpoints hosting sensitive records.

Sigma Rules

YAML
---
title: Mass Archive Creation in Web-Accessible or Temp Directories
id: 9c4e2b17-6a3d-4f58-b291-7d8e5c0a1f34
status: experimental
description: Detects compression utilities creating archives in web roots, temp, or staging directories — a common data staging behavior prior to exfiltration of bulk records.
references:
  - https://attack.mitre.org/techniques/T1560/001/
author: Security Arsenal
date: 2026/04/06
tags:
  - attack.collection
  - attack.t1560.001
logsource:
  category: process_creation
  product: windows
detection:
  selection_tool:
    Image|endswith:
      - '\7z.exe'
      - '\7za.exe'
      - '\rar.exe'
      - '\winzip.exe'
      - '\tar.exe'
      - '\makecab.exe'
  selection_path:
    CommandLine|contains:
      - '\inetpub\'
      - '\wwwroot\'
      - '\Temp\'
      - '\tmp\'
      - 'AppData\Local\Temp'
  condition: selection_tool and selection_path
falsepositives:
  - Legitimate backup jobs — whitelist known service accounts and scheduled task paths
level: high
---
title: Database Dump Utility Execution by Non-Service Account
id: 3f8a1d54-2e7b-4c96-a835-9b1d4e6f2a07
status: experimental
description: Detects execution of database export/dump utilities by interactive or unusual accounts, indicating potential bulk extraction of student, HR, or citizen records.
references:
  - https://attack.mitre.org/techniques/T1005/
author: Security Arsenal
date: 2026/04/06
tags:
  - attack.collection
  - attack.t1005
  - attack.exfiltration
logsource:
  category: process_creation
  product: windows
detection:
  selection:
    Image|endswith:
      - '\mysqldump.exe'
      - '\pg_dump.exe'
      - '\sqlcmd.exe'
      - '\bcp.exe'
      - '\osql.exe'
      - '\mongoexport.exe'
  filter_backup:
    CommandLine|contains:
      - 'maintenance'
      - 'backup'
  condition: selection and not filter_backup
falsepositives:
  - DBA activity and scheduled maintenance — baseline authorized accounts and tighten the filter
level: high
---
title: Web Server Process Spawning Command Shell
id: 61b7f4a2-8d3e-4c19-b542-e0a6d3c81f95
status: experimental
description: Detects a web server or database service process spawning a command shell, a strong indicator of web shell deployment or SQL injection leading to command execution — a frequent entry vector in university and public-sector breaches.
references:
  - https://attack.mitre.org/techniques/T1505/003/
  - https://attack.mitre.org/techniques/T1190/
author: Security Arsenal
date: 2026/04/06
tags:
  - attack.persistence
  - attack.t1505.003
  - attack.initial_access
  - attack.t1190
logsource:
  category: process_creation
  product: windows
detection:
  selection_parent:
    ParentImage|endswith:
      - '\w3wp.exe'
      - '\httpd.exe'
      - '\nginx.exe'
      - '\tomcat.exe'
      - '\sqlservr.exe'
      - '\php.exe'
      - '\php-cgi.exe'
  selection_child:
    Image|endswith:
      - '\cmd.exe'
      - '\powershell.exe'
      - '\pwsh.exe'
      - '\net.exe'
      - '\whoami.exe'
  condition: selection_parent and selection_child
falsepositives:
  - Rare; some legacy applications shell out for report generation — investigate every hit
level: critical

KQL Hunt — Anomalous Data Egress and Process Behavior (Microsoft Sentinel / Defender)

KQL — Microsoft Sentinel / Defender
// Hunt 1: Endpoints sending abnormally large volumes to rare external destinations
let baseline = DeviceNetworkEvents
| where TimeGenerated > ago(30d) and TimeGenerated <= ago(1d)
| summarize AvgBytes = avg(tolong(0)), Destinations = dcount(RemoteIP) by DeviceName;
DeviceNetworkEvents
| where TimeGenerated > ago(24h)
| where ActionType == "ConnectionSuccess"
| summarize RecentConnections = count(), UniqueRemoteIPs = dcount(RemoteIP), RemoteUrls = make_set(RemoteUrl, 50) by DeviceName, InitiatingProcessAccountName
| join kind=leftouter baseline on DeviceName
| where UniqueRemoteIPs > 3 * Destinations or isnull(Destinations)
| project DeviceName, InitiatingProcessAccountName, RecentConnections, UniqueRemoteIPs, RemoteUrls
| order by UniqueRemoteIPs desc;

// Hunt 2: Archive/dump tool execution clustered on servers (Syslog ingestion for Linux DB/web tier)
Syslog
| where TimeGenerated > ago(7d)
| where ProcessName has_any ("mysqldump", "pg_dump", "mongoexport", "tar", "zip")
| summarize Executions = count(), DistinctUsers = dcount(SyslogMessage), SampleCmd = any(SyslogMessage) by Computer, ProcessName, bin(TimeGenerated, 1h)
| order by Executions desc;

// Hunt 3: Single account authenticating to an unusual number of servers (post-credential-theft lateral movement)
SecurityEvent
| where TimeGenerated > ago(24h)
| where EventID == 4624 and LogonType in (3, 10)
| summarize ServerCount = dcount(Computer), Servers = make_set(Computer, 40) by Account
| where ServerCount > 15
| order by ServerCount desc;

Hunt 2 and 3 thresholds must be baselined to your environment — an SIS batch job legitimately exports nightly, and service accounts legitimately touch many servers. Tune against known-good accounts first, then alert on everything outside the allowlist.

Velociraptor VQL — Endpoint Triage for Staging Artifacts

VQL — Velociraptor
-- Hunt for recently created large archives outside known backup paths (data staging indicator)
SELECT FullPath, Size, Mtime, Atime,
       basename(path=FullPath) AS FileName
FROM glob(globs='C:/Users/*/AppData/Local/Temp/*.zip',
          accessor='ntfs')
WHERE Size > 10000000
ORDER BY Mtime DESC
VQL — Velociraptor
-- Check for dump/export processes currently running on database servers
SELECT Pid, Name, CommandLine, Exe, Username, CreateTime
FROM pslist()
WHERE Name =~ '(?i)mysqldump|pg_dump|mongoexport|sqlcmd|bcp'
   OR CommandLine =~ '(?i)into outfile|backup database|\.dump'
VQL — Velociraptor
-- Netstat sweep for established sessions to rare external IPs from server VLANs
SELECT Pid, Name, Status, Laddr, Lport, Raddr, Rport
FROM netstat()
WHERE Status =~ 'ESTAB'
  AND Raddr !~ '^(10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[01])\.|127\.)'
ORDER BY Raddr

Hardening & Verification Script

The following PowerShell runbook audits a Windows-based application/database tier for the exact conditions that turn an intrusion into a 520,000-record breach: interactive dump-tool usage, archives in web roots, and web servers with shell-spawning capability. Run it on SIS/HR application and database servers.

PowerShell
# Security Arsenal — Mass-Exfiltration Exposure Audit (Windows app/DB tier)
# Run elevated. Produces a findings report; remediates nothing automatically — review first.

$report = @()

# 1) Detect database dump/export tooling accessible outside the DB install path
$dumpTools = Get-ChildItem -Path 'C:\' -Include 'mysqldump.exe','pg_dump.exe','mongoexport.exe','bcp.exe' -Recurse -ErrorAction SilentlyContinue |
  Where-Object { $_.FullName -notmatch 'Program Files.*(MySQL|PostgreSQL|MongoDB|Microsoft SQL Server)' }
foreach ($t in $dumpTools) { $report += "[HIGH] Dump tool in unexpected location: $($t.FullName)" }

# 2) Find large archives staged in web roots or temp (last 30 days)
$paths = @('C:\inetpub\wwwroot', "$env:SystemDrive\Windows\Temp", "$env:TEMP")
foreach ($p in $paths) {
  if (Test-Path $p) {
    Get-ChildItem $p -Recurse -Include *.zip,*.7z,*.rar,*.tar,*.gz -ErrorAction SilentlyContinue |
      Where-Object { $_.Length -gt 10MB -and $_.LastWriteTime -gt (Get-Date).AddDays(-30) } |
      ForEach-Object { $report += "[HIGH] Large recent archive staged: $($_.FullName) ($([math]::Round($_.Length/1MB)) MB)" }
  }
}

# 3) Audit process creation with command line (required for Sigma rules above to function)
$audit = auditpol /get /subcategory:"Process Creation" 2>$null
if ($audit -notmatch 'Success') {
  auditpol /set /subcategory:"Process Creation" /success:enable | Out-Null
  $report += "[FIXED] Enabled 'Audit Process Creation' (Success)"
}
$cmdline = Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit' -Name ProcessCreationIncludeCmdLine_Enabled -ErrorAction SilentlyContinue
if (-not $cmdline -or $cmdline.ProcessCreationIncludeCmdLine_Enabled -ne 1) {
  Set-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit' -Name ProcessCreationIncludeCmdLine_Enabled -Value 1
  $report += "[FIXED] Enabled command-line capture in process creation events"
}

# 4) Verify outbound egress filtering exists for server VLANs (defender must confirm firewall-side)
$report += "[ACTION] Confirm firewall egress rules: DB/app servers should reach ONLY approved update/mgmt destinations. Deny-by-default outbound on the server VLAN stops most exfil cold."

# 5) Check MFA enforcement indicator: NPS/ADFS not directly auditable here — flag for review
$report += "[ACTION] Verify MFA is enforced (not optional) on all SSO-federated apps, VPN, and admin portals. Review legacy-protocol exclusions (IMAP/SMTP/basic auth) — disable them."

$report | Out-File "$env:USERPROFILE\Desktop\ExfilExposure-Audit.txt"
$report
Bash / Shell
#!/bin/bash
# Security Arsenal — Linux DB/web tier exposure audit
# Run as root on student-records/HR database and web servers.

echo "=== [1] Dump utilities in web-accessible or temp paths ==="
find /var/www /srv/www /tmp /var/tmp -type f \( -name 'mysqldump' -o -name 'pg_dump' \) 2>/dev/null

echo "=== [2] Large archives staged in web roots or temp (last 30 days) ==="
find /var/www /srv/www /tmp /var/tmp -type f \( -name '*.zip' -o -name '*.tar*' -o -name '*.gz' -o -name '*.7z' \) -size +10M -mtime -30 2>/dev/null -exec ls -lh {} \;

echo "=== [3] World-readable database exports or SQL dumps on disk ==="
find / -type f \( -name '*.sql' -o -name '*.dump' \) -perm -o+r -size +1M 2>/dev/null | head -20

echo "=== [4] Web server processes with shell children RIGHT NOW ==="
for pid in $(pgrep -x apache2; pgrep -x nginx; pgrep -x httpd; pgrep -x php-fpm); do
  children=$(ps --ppid "$pid" -o comm= 2>/dev/null | grep -E 'bash|sh|dash|zsh|nc|curl|wget')
  [ -n "$children" ] && echo "ALERT: web PID $pid spawned: $children"
done

echo "=== [5] Egress check: can this server reach arbitrary internet hosts on 443? ==="
timeout 5 curl -s -o /dev/null -w "Outbound 443 reachable (should FAIL on a DB server): %{http_code}\n" https://example.com || echo "OK: outbound blocked or filtered"

echo "=== [6] Recent sequential-record scraping pattern in web access logs ==="
# Fires when one IP pulls an abnormal volume of record-detail pages (IDOR-style scraping)
awk '{print $1}' /var/log/apache2/access.log 2>/dev/null | sort | uniq -c | sort -rn | head -10

Remediation & Defensive Actions

Because no CVE has been disclosed for this incident, remediation is architectural, not a patch number. Prioritize in this order:

  1. Egress filtering on server VLANs — do this first. Database and application servers holding PII have no business initiating arbitrary outbound HTTPS. Deny-by-default egress with an explicit allowlist (patch repos, AV/EDR telemetry, approved SaaS) is the single highest-yield control against bulk exfiltration. It converts a catastrophic breach into a contained intrusion.

  2. Enforce phishing-resistant MFA across federated identity. Universities live on SSO; so do their attackers. Mandate FIDO2/passkeys or at minimum number-matching push for staff, disable legacy authentication protocols (basic auth, IMAP/POP against cloud mail), and monitor for MFA fatigue patterns — repeated push requests followed by an approval is a critical-severity alert, not a helpdesk ticket.

  3. Inventory and constrain your student-facing applications. Run authenticated scans and manual IDOR testing against admissions, enrollment, and records portals. Any endpoint that returns records based on a user-supplied identifier must enforce object-level authorization. If you cannot fix the app this quarter, put a WAF rule in front of it that rate-limits per-session record retrieval — sequential enumeration of 500,000 records is not subtle and should trip a volumetric control within minutes.

  4. Deploy database activity monitoring on PII stores. Alert on: exports exceeding baseline row counts, dump-tool execution outside maintenance windows, and queries from service accounts at unusual hours. Baseline first, alert second — an untuned DAM gets disabled in a week.

  5. Segment ruthlessly. The departmental WordPress box must not be able to reach the student records database. Flat trust networks are why one compromised department server becomes a university-wide breach.

  6. Prepare the notification machine now. A breach of this scale triggers GDPR obligations (72-hour supervisory authority notification for EU institutions) and potentially cross-border requirements. Pre-draft notification templates, pre-stage your records-count methodology, and rehearse with counsel. The organizations that handle disclosure well decided how they would handle it a year before the incident.

  7. If you are potentially affected as an individual: assume national ID, contact, and academic records are exposed. Enroll in any offered credit/identity monitoring, treat university-branded emails and SMS with heightened suspicion (breach-follow-on phishing is a certainty), and reset any password reused from university systems.

For Higher-Ed Security Teams Specifically

If this story feels uncomfortably close to home, treat it as a tabletop exercise this month. Pull your own logs and answer three questions: Could we see a single account exporting 500,000 records? Could we see a web server spawning a shell? Could we see 10 GB leaving the database VLAN? If any answer is no, that is your roadmap — and the detections in this post are your starting point.

Related Resources

Security Arsenal Incident Response Services AlertMonitor Platform Book a SOC Assessment incident-response Intel Hub

Is your security operations ready?

Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.