Response playbooks, investigation guides, and Atomic Red Team tests are Pro-only. Upgrade to unlock the full detection package for THREAT-Impact-FinancialLedgerTampering.

Upgrade to Pro
THREAT-Impact-FinancialLedgerTampering Splunk · SPL

Detect Financial Ledger and Transaction Record Tampering via Direct Database Manipulation in Splunk

An insider with legitimate database credentials, or an attacker who has obtained them, can bypass an application's business logic entirely and manipulate financial data at the source: connecting directly to the ledger, invoice, or transaction database with an interactive client (SQL Server Management Studio, Azure Data Studio, DBeaver, psql, mysql CLI) instead of through the application's service account, then issuing UPDATE or DELETE statements against tables such as general_ledger, invoices, journal_entries, gl_entries, ap_transactions, or account_balances. This is functionally identical to APT38's DYEPACK tool altering SWIFT transaction records to conceal fraudulent transfers, and to the classic 'ghost employee' or 'check kiting' fraud pattern where a trusted insider edits posted transactions after the fact rather than through a reversing journal entry (which would leave the expected audit trail). Three behaviors distinguish malicious tampering from legitimate maintenance: (1) the write originates from an ad-hoc/interactive client tool or an identity other than the application's own connection pool account — legitimate corrections almost always flow back through the application, which posts compensating entries rather than editing history in place; (2) the activity clusters off-hours or on weekends, when fewer people are watching and reconciliation staff are not online; and (3) the write is preceded by disabling the database's own audit trail for that table or database — SQL Server 'ALTER SERVER AUDIT ... WITH (STATE = OFF)', temporal-table system-versioning disablement, change-tracking disablement, or a DISABLE TRIGGER on an audit trigger — which is a strong signal since audit trails exist specifically to survive this kind of tampering and disabling one immediately before writing to financial tables has essentially no legitimate business justification. This detection watches SQL platform audit logs (Azure SQL Auditing / SQL Server Audit, or equivalent extended-events output) for the write pattern, the audit-disablement pattern, and the two-step sequence where disablement precedes writes within a short window.

MITRE ATT&CK

Tactic
Impact

SPL Detection Query

Splunk (SPL)
spl
index=azure sourcetype="azure:sql:diagnosticlogs" category="SQLSecurityAuditEvents" (action_name="UPDATE" OR action_name="DELETE")
| where match(object_name, "(?i)(ledger|invoice|transaction|payment|journal_entr|gl_entr|account_balance|^ap_|^ar_|general_ledger)") AND succeeded="true"
| eval Hour=strftime(_time, "%H"), DOW=strftime(_time, "%a")
| eval IsOffHours=if(Hour<6 OR Hour>=20 OR DOW IN ("Sat","Sun"), 1, 0)
| eval IsInteractiveClient=if(match(application_name, "(?i)(Management Studio|Azure Data Studio|DBeaver|HeidiSQL|psql|pgAdmin|DataGrip|TablePlus|mysql\.exe|sqlcmd)") OR NOT match(application_name, "(?i)(LedgerApp-Prod|ERPService|AccountingSvc|BillingAPI|GLPostingService)"), 1, 0)
| bin _time span=15m
| stats count as WriteCount, dc(object_name) as ObjectsTouched, values(object_name) as Objects, values(action_name) as Actions, sum(IsOffHours) as OffHoursCount, sum(IsInteractiveClient) as InteractiveCount, earliest(_time) as FirstSeen, latest(_time) as LastSeen by server_principal_name, database_name, application_name, _time
| where InteractiveCount>0 AND (WriteCount>=5 OR OffHoursCount>0)
| join type=left server_principal_name, database_name
    [ search index=azure sourcetype="azure:sql:diagnosticlogs" category="SQLSecurityAuditEvents" (match(action_name, "AUDIT_CHANGE_GROUP|SERVER_OBJECT_CHANGE_GROUP") OR match(statement, "(?i)(DISABLE TRIGGER|SET CHANGE_TRACKING\s*=\s*OFF|ALTER SERVER AUDIT|SYSTEM_VERSIONING\s*=\s*OFF)"))
      | stats earliest(_time) as AuditDisabledAt by server_principal_name, database_name ]
| eval AuditTamperPrecursor=if(isnotnull(AuditDisabledAt) AND AuditDisabledAt<FirstSeen AND (FirstSeen-AuditDisabledAt)<21600, 1, 0)
| eval RiskScore=case(
    AuditTamperPrecursor=1 AND InteractiveCount>0, 95,
    InteractiveCount>0 AND OffHoursCount>0 AND WriteCount>=10, 85,
    InteractiveCount>0 AND OffHoursCount>0, 70,
    InteractiveCount>0 AND WriteCount>=10, 65,
    true(), 50)
| table FirstSeen, LastSeen, server_principal_name, database_name, application_name, WriteCount, ObjectsTouched, Objects, Actions, OffHoursCount, InteractiveCount, AuditTamperPrecursor, AuditDisabledAt, RiskScore
| sort - RiskScore, WriteCount
high severity medium confidence

SPL detection over Azure SQL diagnostic audit logs (azure:sql:diagnosticlogs, SQLSecurityAuditEvents category) that flags UPDATE/DELETE activity against financial-sounding tables from interactive database clients or non-allowlisted application identities, bucketed into 15-minute windows per principal/database. A subsearch join pulls in the most recent audit-disablement event (audit change group toggle, disabled trigger, disabled change tracking, disabled server audit) for the same principal/database, and flags a precursor relationship when disablement occurred within 6 hours before the writes — the single highest-confidence pattern for deliberate ledger tampering.

Data Sources

Azure SQL Database Auditing via Splunk Add-on for Microsoft Cloud ServicesSQL Server Audit / Extended Events forwarded to the same sourcetype

Required Sourcetypes

azure:sql:diagnosticlogs

False Positives & Tuning

  • DBAs running approved off-hours data-correction scripts via SSMS/Azure Data Studio with a documented change ticket
  • Newly deployed application versions connecting under an application_name not yet added to the allowlist
  • Scheduled overnight batch reconciliation or month-end close jobs issuing bulk updates from an ETL/reporting service account
  • Legitimate schema-migration maintenance windows that disable change tracking or temporal versioning ahead of a bulk data load
  • QA/staging testers using interactive clients against a non-production copy of the financial schema

Other platforms for THREAT-Impact-FinancialLedgerTampering


Testing Methodology

Validate this detection against 3 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.

  1. Test 1Disable SQL Server Audit Then Update Ledger Table

    Expected signal: SQL Server Audit / Azure SQL Auditing records: an AUDIT_CHANGE_GROUP event for test_ledger_audit_spec followed within minutes by an UPDATE action_name event against object_name dbo.general_ledger, both attributed to the same server_principal_name with application_name 'sqlcmd'.

  2. Test 2Off-Hours Bulk Update of Invoice Table via Interactive Client

    Expected signal: SQL Server Audit / Azure SQL Auditing records: 10 UPDATE action_name events against object_name dbo.invoices within a single 15-minute window, application_name 'Azure Data Studio', succeeded = true.

  3. Test 3Direct Deletion of Journal Entry Rows via psql

    Expected signal: Database audit log (pgaudit or equivalent forwarded into the SQLSecurityAuditEvents-equivalent schema): DELETE action_name events against object_name journal_entries, application_name 'psql', server_principal_name dbadmin, succeeded = true.

Unlock playbooks & atomic tests with Pro

Get the full detection package for THREAT-Impact-FinancialLedgerTampering — response playbook and atomic red team tests, plus investigation guidance and hunting queries.

df00tech Pro — £29/user/month

Response PlaybookInvestigation GuideHunting QueriesAtomic Red Team TestsTuning Guidance

Related Detections

Tactic Hub

Detection Variants (1)

Different telemetry and tradecraft for the same technique — pick the one that matches the data you collect.