Detect Stored Data Manipulation — Unauthorized Bulk Modification of Production Database Records in Microsoft Sentinel
Unlike destruction or encryption, stored data manipulation (T1565.001) is a stealthy Impact objective: the adversary alters records in place — falsifying financial transactions, backdating timestamps, adjusting inventory or pricing data, or planting false log entries — specifically so the tampering is not immediately obvious and can influence downstream business decisions, financial reporting, or an investigation. Because the goal is integrity compromise rather than availability loss, the data remains accessible and the application keeps functioning normally, which means traditional outage-based monitoring never fires. The most reliable detection surface is the database's own audit log: a spike in UPDATE/DELETE statement volume from a single principal against production tables, especially when that principal is a service account not normally used for ad hoc interactive queries, or when the activity occurs outside any tracked change-management window. A second useful signal is direct execution of interactive query tools (ssms.exe, azuredatastudio.exe, mysql.exe, psql.exe) by a service account that should only ever connect programmatically — a strong indicator that stolen service-account credentials are being used for manual, off-process data tampering rather than application logic performing routine writes.
MITRE ATT&CK
- Tactic
- Impact
KQL Detection Query
// THREAT: Stored data manipulation - anomalous bulk UPDATE/DELETE volume + service-account interactive tooling (T1565.001)
// Requires Azure SQL Database Auditing ingested into AzureDiagnostics (category SQLSecurityAuditEvents)
let LookbackWindow = 1h;
let BulkWriteThreshold = 100; // UPDATE/DELETE statements from one principal in the window
let KnownServiceAccounts = dynamic(["svc_appserver", "svc_etl", "svc_reporting"]); // populate with legitimate application/ETL service principals
// Signal 1: bulk UPDATE/DELETE volume spike from a single principal against production tables
let BulkWriteSpike = AzureDiagnostics
| where Category == "SQLSecurityAuditEvents"
| where TimeGenerated > ago(LookbackWindow)
| where action_name_s in ("UPDATE", "DELETE", "BATCH UPDATE", "BATCH DELETE")
| summarize WriteCount=count(), TablesTouched=make_set(object_name_s, 20) by server_principal_name_s, database_name_s, bin(TimeGenerated, 15m)
| where WriteCount >= BulkWriteThreshold
| extend Indicator = "BulkUpdateDeleteVolumeSpike"
| extend RiskScore = iff(server_principal_name_s !in~ (KnownServiceAccounts), 90, 70)
| project TimeGenerated, server_principal_name_s, database_name_s, WriteCount, TablesTouched, Indicator, RiskScore;
// Signal 2: service account launching an interactive DB query tool (indicates manual, off-process access)
let ServiceAccountInteractiveTool = DeviceProcessEvents
| where Timestamp > ago(LookbackWindow)
| where FileName in~ ("ssms.exe", "azuredatastudio.exe", "mysql.exe", "psql.exe", "dbeaver.exe")
| where AccountName in~ (KnownServiceAccounts)
| extend Indicator = "ServiceAccountLaunchedInteractiveQueryTool"
| extend RiskScore = 85
| project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine, Indicator, RiskScore;
union BulkWriteSpike, ServiceAccountInteractiveTool
| sort by RiskScore desc, TimeGenerated desc Two-signal detection for stored data manipulation. Signal 1 aggregates Azure SQL Database audit events (SQLSecurityAuditEvents) by principal and database in 15-minute bins, flagging any principal issuing 100+ UPDATE/DELETE/BATCH statements — a volume anomaly inconsistent with normal application write patterns — with elevated risk when the principal is not on the known-service-account allowlist. Signal 2 flags a known service account launching an interactive database query GUI/CLI tool, which application service accounts have no legitimate reason to do, indicating the credential is being used manually rather than by its owning application.
Data Sources
Required Tables
False Positives & Tuning
- Legitimate bulk data operations: month-end batch jobs, data migrations, ETL reprocessing, or scheduled cleanup jobs — exclude known batch-job service principals and their documented execution windows
- Database administrators using SSMS/Azure Data Studio for legitimate maintenance under their own named account rather than a service account (this detection specifically targets service-account use of interactive tools, not DBA activity under personal accounts)
- Application deployment/migration tooling that legitimately runs large schema or data updates during a release window
- Reporting or analytics service accounts with unusually high but legitimate read-heavy query volume (this detection targets write volume, not reads, to minimize this overlap)
Other platforms for THREAT-Impact-ProductionDatabaseRecordTampering
Testing Methodology
Validate this detection against 2 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1Simulate Bulk UPDATE Volume Spike
Expected signal: Azure SQL/SQL Server audit log shows 120 UPDATE statements from the svc_test principal against TestTable within a 15-minute window.
- Test 2Simulate Service Account Launching Interactive Query Tool
Expected signal: DeviceProcessEvents shows ssms.exe launched with AccountName=svc_appserver.
Response Playbook
Triage
- Identify exactly which tables and rows were touched by the flagged principal, and cross-reference against any open change-management ticket or scheduled batch job for that time window.
- For the bulk-write signal: determine whether the principal is a genuine application service account or has been recently reported as compromised (check for related credential-theft or phishing alerts on the same account).
- For the interactive-tool signal: confirm whether the service account credential is stored in a way that could plausibly have been extracted (config file, CI/CD secret, password manager) and check for any recent access to that credential store.
- Compare the modified records against the most recent known-good backup or transaction log to identify the specific values that were changed (before/after diff).
- Assess business impact: does the affected table hold financial, inventory, pricing, or audit-log data where tampering could materially affect reporting, fraud detection, or a concurrent investigation?
Containment
- Suspend or rotate credentials for the implicated service account immediately, and revoke any active sessions/tokens.
- If tampering is confirmed, restore the affected rows/tables from the most recent known-good backup or point-in-time restore rather than attempting manual row-by-row correction.
- Temporarily restrict the account's database permissions to read-only or the minimum required scope while investigation continues.
- If an interactive tool was used from an unexpected host, isolate that host and review it for other signs of compromise (credential theft, malware, unauthorized remote access).
- Notify finance/compliance stakeholders early if the affected data feeds financial reporting, billing, or regulatory audit trails — tampering here can have disclosure obligations.
Evidence Collection
- Full database audit trail for the implicated principal covering the affected time window: every statement, target table, and row count
- Before/after values for the modified records, reconstructed from transaction logs or point-in-time backups
- Authentication logs for the service account: source IP, host, and method of connection (application connection string vs. interactive tool)
- Endpoint process history for any host from which an interactive query tool was launched using the service account
- Change-management/ticketing system records for the affected time window to confirm or rule out an authorized batch operation
Escalation Criteria
- !Confirmed unauthorized modification of financial, billing, or regulatory audit-trail data
- !The service account credential appears to have been used from a host or location inconsistent with its normal application deployment topology
- !Modified records appear to correspond with an ongoing fraud, insider-threat, or law-enforcement investigation (tampering with evidence)
- !Evidence that the same credential was also used to access other systems, indicating broader compromise beyond the single database
Investigation Guide
Related Techniques
Forensic Artifacts
- >
SQL Server Audit / Azure SQL Auditing / MySQL general or audit log entries for the affected time window - >
Database transaction log (for point-in-time analysis of exact before/after row values) - >
Endpoint process creation logs (Sysmon Event ID 1) showing the service account launching an interactive query tool - >
Application connection logs correlating expected vs. observed connection sources for the service account - >
Change-management ticket history for the affected database/table
Tuning Guidance
Build the KnownServiceAccounts allowlist from your actual application connection-string inventory, and separately track each account's normal write-volume baseline — a reporting service account with legitimate high write volume needs a different threshold than a low-volume microservice account. Exclude documented batch-job/ETL windows by time rather than disabling the detection for the whole account, so an anomalous write burst outside the scheduled window still alerts. The interactive-tool signal has very few legitimate false positives once the service-account list is accurate; treat any hit as high-priority.
Hunting Queries
30-day hunt for daily UPDATE/DELETE volume by principal to establish a per-account baseline, making it easier to right-size the BulkWriteThreshold and identify accounts whose write volume has crept upward gradually rather than spiking abruptly.
AzureDiagnostics
| where Category == "SQLSecurityAuditEvents"
| where TimeGenerated > ago(30d)
| where action_name_s in ("UPDATE", "DELETE")
| summarize WriteCount=count() by server_principal_name_s, database_name_s, bin(TimeGenerated, 1d)
| where WriteCount > 500
| sort by WriteCount desc index=azure sourcetype="azure:diagnostics" Category="SQLSecurityAuditEvents" earliest=-30d action_name IN ("UPDATE","DELETE")
| bucket _time span=1d
| stats count AS WriteCount by server_principal_name, database_name, _time
| where WriteCount > 500
| sort - WriteCount Atomic Red Team Tests
Issues a large number of UPDATE statements against a disposable test table using a designated test service account, simulating the bulk-write volume anomaly. Run only against a test/staging database, never production.
Command
sqlcmd -S test-sql-server -d TestDB -U svc_test -Q "DECLARE @i INT = 0; WHILE @i < 120 BEGIN UPDATE dbo.TestTable SET Value = Value + 1 WHERE Id = @i; SET @i = @i + 1; END" Cleanup
sqlcmd -S test-sql-server -d TestDB -U svc_test -Q "UPDATE dbo.TestTable SET Value = 0 WHERE Id < 120" Expected Telemetry
Azure SQL/SQL Server audit log shows 120 UPDATE statements from the svc_test principal against TestTable within a 15-minute window.
Expected Detection
Alert fires on BulkUpdateDeleteVolumeSpike indicator; RiskScore depends on whether svc_test is on the KnownServiceAccounts allowlist.
Launches SQL Server Management Studio under a service account's credentials rather than an application context, simulating manual off-process database access using a stolen or misused service credential.
Command
runas /user:svc_appserver "C:\Program Files (x86)\Microsoft SQL Server Management Studio 19\Common7\IDE\ssms.exe" Cleanup
taskkill /IM ssms.exe /F Expected Telemetry
DeviceProcessEvents shows ssms.exe launched with AccountName=svc_appserver.
Expected Detection
Alert fires on ServiceAccountLaunchedInteractiveQueryTool indicator with RiskScore=85.
Related Detections
Tactic Hub
Detection Variants (1)
Different telemetry and tradecraft for the same technique — pick the one that matches the data you collect.