Introduction
Microsoft Sentinel is a cloud-native Security Information and Event Management (SIEM) and Security Orchestration, Automation, and Response (SOAR) solution. In this post, we’ll explore how to build an effective Security Operations Center (SOC) using Sentinel.
Why Microsoft Sentinel?
Key Advantages
- Cloud-Native Scale - Ingest and analyze petabytes of data
- AI and Machine Learning - Built-in intelligence for threat detection
- Cost-Effective - Pay only for what you ingest
- Integrated - Native integration with Microsoft ecosystem
- Extensible - 100+ out-of-the-box connectors
Architecture Overview
Data Sources → Data Connectors → Log Analytics → Sentinel
↓ ↓ ↓ ↓
Azure Office 365 Analytics Incidents
AWS Azure AD Workbooks Playbooks
GCP Defender Hunting Automation
On-Prem 3rd Party Notebooks Response
Getting Started
Step 1: Create Sentinel Workspace
# Create Log Analytics workspace
az monitor log-analytics workspace create \
--resource-group sentinel-rg \
--workspace-name sentinel-workspace \
--location eastus \
--sku PerGB2018
# Enable Sentinel on the workspace
az sentinel onboard \
--resource-group sentinel-rg \
--workspace-name sentinel-workspace
Step 2: Configure Data Retention
# Set retention to 90 days
Set-AzOperationalInsightsWorkspace `
-ResourceGroupName "sentinel-rg" `
-Name "sentinel-workspace" `
-RetentionInDays 90
Step 3: Enable Data Connectors
Key connectors to enable first:
- Azure Activity
- Azure Active Directory
- Microsoft 365 Defender
- Microsoft Defender for Cloud
- Office 365
# Enable Azure Activity connector
az sentinel data-connector create \
--resource-group sentinel-rg \
--workspace-name sentinel-workspace \
--name "AzureActivity" \
--kind "AzureActivity"
Essential Analytics Rules
1. Failed Login Attempts
Detect potential brute force attacks:
SigninLogs
| where ResultType != 0
| summarize FailedAttempts = count() by UserPrincipalName, IPAddress, bin(TimeGenerated, 5m)
| where FailedAttempts > 5
| project TimeGenerated, UserPrincipalName, IPAddress, FailedAttempts
2. Suspicious Resource Deletion
Monitor for unusual deletion patterns:
AzureActivity
| where OperationNameValue endswith "DELETE"
| where ActivityStatusValue == "Success"
| extend ResourceType = tostring(split(ResourceId, "/")[6])
| summarize DeletionCount = count() by Caller, ResourceType, bin(TimeGenerated, 1h)
| where DeletionCount > 3
3. Anomalous Login Location
Detect impossible travel scenarios:
let timeframe = 1h;
let threshold = 500; // miles per hour
SigninLogs
| where TimeGenerated >= ago(24h)
| where ResultType == 0
| project TimeGenerated, UserPrincipalName, Location, IPAddress
| order by UserPrincipalName, TimeGenerated asc
| serialize
| extend NextLocation = next(Location, 1), NextTime = next(TimeGenerated, 1)
| where UserPrincipalName == next(UserPrincipalName, 1)
| where Location != NextLocation
| extend TimeDiff = datetime_diff('hour', NextTime, TimeGenerated)
| where TimeDiff <= timeframe
Workbook Templates
Security Operations Dashboard
Create a comprehensive SOC dashboard:
{
"version": "Notebook/1.0",
"items": [
{
"type": 1,
"content": {
"json": "## Security Operations Overview"
}
},
{
"type": 3,
"content": {
"version": "KqlItem/1.0",
"query": "SecurityIncident | summarize count() by Severity | render piechart",
"size": 0,
"title": "Incidents by Severity",
"timeContext": {
"durationMs": 86400000
}
}
},
{
"type": 3,
"content": {
"version": "KqlItem/1.0",
"query": "SecurityAlert | summarize count() by AlertName | top 10 by count_",
"size": 0,
"title": "Top 10 Alerts",
"timeContext": {
"durationMs": 86400000
}
}
}
]
}
Automation with Playbooks
Auto-Respond to High-Severity Incidents
Create a Logic App for automatic response:
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"triggers": {
"When_Azure_Sentinel_incident_creation_rule_was_triggered": {
"type": "ApiConnectionWebhook",
"inputs": {
"host": {
"connection": {
"name": "@parameters('$connections')['azuresentinel']['connectionId']"
}
},
"body": {
"callback_url": "@{listCallbackUrl()}"
},
"path": "/incident-creation"
}
}
},
"actions": {
"Condition": {
"type": "If",
"expression": {
"and": [
{
"equals": [
"@triggerBody()?['object']?['properties']?['severity']",
"High"
]
}
]
},
"actions": {
"Send_email": {
"type": "ApiConnection",
"inputs": {
"host": {
"connection": {
"name": "@parameters('$connections')['office365']['connectionId']"
}
},
"method": "post",
"path": "/v2/Mail",
"body": {
"To": "soc@company.com",
"Subject": "High Severity Incident: @{triggerBody()?['object']?['properties']?['title']}",
"Body": "Incident Details: @{triggerBody()?['object']?['properties']?['description']}"
}
}
},
"Create_ServiceNow_ticket": {
"type": "ApiConnection",
"inputs": {
"host": {
"connection": {
"name": "@parameters('$connections')['servicenow']['connectionId']"
}
},
"method": "post",
"path": "/api/now/table/incident",
"body": {
"short_description": "@{triggerBody()?['object']?['properties']?['title']}",
"description": "@{triggerBody()?['object']?['properties']?['description']}",
"urgency": "1",
"priority": "1"
}
}
}
}
}
}
}
}
Threat Hunting
Proactive Hunting Queries
Hunt for Crypto Mining
let SuspiciousProcesses = dynamic(["xmrig", "cgminer", "bfgminer", "cpuminer"]);
SecurityEvent
| where EventID == 4688 // Process Creation
| where ProcessName has_any (SuspiciousProcesses)
| project TimeGenerated, Computer, Account, ProcessName, CommandLine
Detect Lateral Movement
SecurityEvent
| where EventID == 4648 // Logon with explicit credentials
| where LogonType == 3 // Network logon
| summarize count() by Account, IpAddress, Computer, bin(TimeGenerated, 5m)
| where count_ > 3
Identify Data Exfiltration
AzureActivity
| where OperationNameValue has "Microsoft.Storage/storageAccounts/listKeys/action"
| where ActivityStatusValue == "Success"
| summarize count() by Caller, ResourceGroup, bin(TimeGenerated, 1h)
| where count_ > 1
Building Detection Rules
Rule Creation Best Practices
- Start with Templates - Use built-in templates
- Tune for Your Environment - Reduce false positives
- Document Thoroughly - Include triage steps
- Version Control - Track rule changes
- Regular Review - Update based on effectiveness
Sample Detection Rule
name: Suspicious PowerShell Execution
description: Detects suspicious PowerShell command execution
severity: Medium
queryFrequency: 5m
queryPeriod: 5m
triggerOperator: GreaterThan
triggerThreshold: 0
query: |
SecurityEvent
| where EventID == 4688
| where Process has "powershell.exe"
| where CommandLine has_any ("DownloadString", "IEX", "Invoke-Expression", "EncodedCommand")
| project TimeGenerated, Computer, Account, CommandLine
tactics:
- Execution
- DefenseEvasion
relevantTechniques:
- T1059.001
- T1027
Integration Scenarios
1. Sentinel + Defender for Cloud
Unified security posture and threat protection:
# Configure Defender alerts to flow to Sentinel
az security workspace-setting create \
--name default \
--target-workspace "/subscriptions/{sub-id}/resourceGroups/sentinel-rg/providers/Microsoft.OperationalInsights/workspaces/sentinel-workspace"
2. Sentinel + Azure AD Identity Protection
Correlation of identity and cloud threats:
SigninLogs
| join kind=inner (
SecurityAlert
| where ProviderName == "IPC"
) on $left.UserPrincipalName == $right.CompromisedEntity
3. Multi-Cloud Coverage
Extend to AWS and GCP:
# AWS CloudTrail connector
az sentinel data-connector create \
--resource-group sentinel-rg \
--workspace-name sentinel-workspace \
--name "AWSCloudTrail" \
--kind "AWSCloudTrail" \
--aws-role-arn "arn:aws:iam::123456789012:role/SentinelRole"
Cost Optimization
Understanding Costs
Sentinel charges for:
- Data Ingestion - Per GB ingested
- Data Retention - Beyond free tier (90 days)
- Automation - Playbook executions (Logic Apps cost)
Cost Saving Strategies
- Use Commitment Tiers - Save up to 65%
- Filter Unnecessary Data - Transform before ingestion
- Optimize Retention - Archive cold data to storage
- Use Basic Logs - For low-value data sources
// Sample: Filter verbose logs before ingestion
AzureDiagnostics
| where Category != "AuditLogs" or ResultType != "Success"
SOC Metrics and KPIs
Track these key metrics:
- Mean Time to Detect (MTTD) - Average time to detect threats
- Mean Time to Respond (MTTR) - Average time to respond
- Mean Time to Resolve (MTTR) - Average time to resolve incidents
- False Positive Rate - Percentage of false alerts
- Incident Volume Trend - Track over time
- Alert Tuning Effectiveness - Reduction in noise
Query for SOC Metrics
SecurityIncident
| where TimeGenerated >= ago(30d)
| extend TimeToDetect = datetime_diff('minute', FirstActivityTime, TimeGenerated)
| extend TimeToClose = datetime_diff('hour', ClosedTime, CreatedTime)
| summarize
AvgTimeToDetect = avg(TimeToDetect),
AvgTimeToClose = avg(TimeToClose),
IncidentCount = count()
by Severity
Maturity Roadmap
Level 1: Foundation (Months 1-3)
- Deploy Sentinel workspace
- Enable core connectors
- Implement built-in analytics rules
- Create basic workbooks
Level 2: Operational (Months 4-6)
- Custom detection rules
- Incident response playbooks
- Regular threat hunting
- SOC process documentation
Level 3: Advanced (Months 7-12)
- Advanced hunting queries
- Custom integrations
- Machine learning models
- Proactive threat intelligence
Level 4: Optimized (Year 2+)
- Full automation
- Predictive analytics
- Continuous improvement
- Industry collaboration
Conclusion
Microsoft Sentinel provides a powerful platform for building a modern SOC. Success depends on proper configuration, continuous tuning, and integration with your broader security ecosystem. Start with the fundamentals, measure your progress, and continuously improve your detection and response capabilities.
Remember: A SOC is not just technology—it’s people, processes, and technology working together.
Resources
Next in the series: Advanced Threat Hunting Techniques with Sentinel and Jupyter Notebooks.