initial commit
This commit is contained in:
292
MOD4.5_SIEM_Operations.md
Normal file
292
MOD4.5_SIEM_Operations.md
Normal file
@@ -0,0 +1,292 @@
|
||||
# FILE: MOD4.5_SIEM_Operations.md
|
||||
# MODULE 4.5: SIEM OPERATIONS & LOG ANALYSIS
|
||||
|
||||
## Learning Objectives
|
||||
- Master KQL (Kibana Query Language) for Security Onion
|
||||
- Build custom dashboards for threat visualization
|
||||
- Perform log correlation across multiple data sources
|
||||
- Tune alerts to reduce false positives
|
||||
- Export data for integration with custom SOC dashboard (React)
|
||||
|
||||
---
|
||||
|
||||
## LAB 4.5.1: KIBANA QUERY LANGUAGE (KQL) FUNDAMENTALS
|
||||
|
||||
### Basic KQL Syntax
|
||||
```
|
||||
# Search for specific field value
|
||||
event.module: "suricata"
|
||||
source.ip: "10.10.2.50"
|
||||
|
||||
# Multiple conditions (AND)
|
||||
event.module: "suricata" AND alert.signature: "GPL EXPLOIT"
|
||||
|
||||
# OR condition
|
||||
source.ip: ("10.10.2.50" OR "10.10.2.51")
|
||||
|
||||
# Wildcards
|
||||
alert.signature: *nmap*
|
||||
|
||||
# NOT operator
|
||||
event.module: "suricata" NOT alert.severity: 3
|
||||
|
||||
# Field exists
|
||||
_exists_: alert.signature
|
||||
|
||||
# Range queries
|
||||
event.duration: >=1000000
|
||||
@timestamp: >= "2026-02-11T00:00:00"
|
||||
|
||||
# Nested field
|
||||
dns.question.name: "evil.com"
|
||||
```
|
||||
|
||||
### Common SOC Queries
|
||||
|
||||
**Find failed SSH logins:**
|
||||
```
|
||||
event.dataset: "system.auth" AND system.auth.ssh.event: "Failed"
|
||||
```
|
||||
|
||||
**Detect port scans (high SYN packet count):**
|
||||
```
|
||||
event.module: "suricata" AND network.transport: "tcp" AND suricata.eve.flow.pkts_toserver: >100
|
||||
```
|
||||
|
||||
**Find DNS queries to suspicious domains:**
|
||||
```
|
||||
dns.question.name: (*malware* OR *phishing* OR *bad*)
|
||||
```
|
||||
|
||||
**High-severity alerts:**
|
||||
```
|
||||
alert.severity: (1 OR 2) AND event.module: "suricata"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## LAB 4.5.2: BUILDING CUSTOM DASHBOARDS
|
||||
|
||||
### Create Attack Detection Dashboard
|
||||
|
||||
```
|
||||
1. Navigate to: Kibana > Dashboard > Create new dashboard
|
||||
|
||||
2. Add Visualization: Top Attack Signatures
|
||||
- Click "Create visualization"
|
||||
- Type: Vertical bar chart
|
||||
- Index pattern: so-*
|
||||
- Metrics: Count
|
||||
- Buckets: Terms → alert.signature.keyword
|
||||
- Top 10
|
||||
- Save: "Top Attack Signatures"
|
||||
|
||||
3. Add Visualization: Alert Timeline
|
||||
- Type: Line chart
|
||||
- X-axis: Date Histogram → @timestamp
|
||||
- Y-axis: Count
|
||||
- Save: "Alert Timeline"
|
||||
|
||||
4. Add Visualization: Source IP Geo Map
|
||||
- Type: Maps
|
||||
- Add layer: Documents
|
||||
- Index: so-*
|
||||
- Geospatial field: source.geo.location
|
||||
- Save: "Attack Source Map"
|
||||
|
||||
5. Add Visualization: Alert Severity Breakdown
|
||||
- Type: Pie chart
|
||||
- Slice: Terms → alert.severity
|
||||
- Save: "Severity Distribution"
|
||||
|
||||
6. Save Dashboard: "Apophis SOC - Attack Overview"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## LAB 4.5.3: DASHBOARD INTEGRATION WITH REACT SOC
|
||||
|
||||
### Export Data for Mock Dashboard
|
||||
|
||||
```bash
|
||||
# Query Security Onion for last 24h alerts
|
||||
# In Kibana Dev Tools:
|
||||
|
||||
POST /so-*/_search
|
||||
{
|
||||
"size": 100,
|
||||
"query": {
|
||||
"bool": {
|
||||
"must": [
|
||||
{ "range": { "@timestamp": { "gte": "now-24h" } } }
|
||||
]
|
||||
}
|
||||
},
|
||||
"sort": [
|
||||
{ "@timestamp": { "order": "desc" } }
|
||||
]
|
||||
}
|
||||
|
||||
# Export to JSON, then process for React dashboard:
|
||||
|
||||
# On Security Onion, create export script:
|
||||
cat > /home/analyst/export_dashboard_data.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
# Export SOC data for dashboard integration
|
||||
|
||||
# Export alert counts
|
||||
curl -X GET "localhost:9200/so-*/_search?pretty" -H 'Content-Type: application/json' -d'
|
||||
{
|
||||
"size": 0,
|
||||
"aggs": {
|
||||
"severity_count": {
|
||||
"terms": { "field": "alert.severity" }
|
||||
}
|
||||
}
|
||||
}
|
||||
' > /tmp/severity_data.json
|
||||
|
||||
# Export top threats
|
||||
curl -X GET "localhost:9200/so-*/_search?pretty" -H 'Content-Type: application/json' -d'
|
||||
{
|
||||
"size": 0,
|
||||
"aggs": {
|
||||
"top_signatures": {
|
||||
"terms": { "field": "alert.signature.keyword", "size": 10 }
|
||||
}
|
||||
}
|
||||
}
|
||||
' > /tmp/top_threats.json
|
||||
|
||||
echo "Data exported to /tmp/"
|
||||
EOF
|
||||
|
||||
chmod +x /home/analyst/export_dashboard_data.sh
|
||||
./export_dashboard_data.sh
|
||||
|
||||
# Transfer to dashboard development environment
|
||||
scp /tmp/*.json user@dashboard-host:~/seclab/dashboard/src/data/live/
|
||||
```
|
||||
|
||||
### Convert to React Mock Data Format
|
||||
|
||||
```javascript
|
||||
// In dashboard/src/data/mockData.js, add real data integration:
|
||||
|
||||
export const importSecurityOnionData = async () => {
|
||||
// In production, this would fetch from Security Onion API
|
||||
// For now, use exported JSON files
|
||||
|
||||
const severityData = {
|
||||
critical: 45,
|
||||
high: 128,
|
||||
medium: 312,
|
||||
low: 891
|
||||
};
|
||||
|
||||
const topThreats = [
|
||||
{ ip: "203.0.113.50", count: 1247, country: "CN", severity: "critical" },
|
||||
{ ip: "198.51.100.23", count: 892, country: "RU", severity: "high" },
|
||||
// ... from exported data
|
||||
];
|
||||
|
||||
return { severityData, topThreats };
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## LAB 4.5.4: ALERT TUNING & FALSE POSITIVE REDUCTION
|
||||
|
||||
### Identify Noisy Rules
|
||||
|
||||
```
|
||||
# In Kibana, find most frequent alerts:
|
||||
POST /so-*/_search
|
||||
{
|
||||
"size": 0,
|
||||
"aggs": {
|
||||
"signatures": {
|
||||
"terms": {
|
||||
"field": "alert.signature.keyword",
|
||||
"size": 20,
|
||||
"order": { "_count": "desc" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Common false positives:
|
||||
# - Internal vulnerability scanners (Nessus, OpenVAS)
|
||||
# - Legitimate admin tools (Nmap from IT)
|
||||
# - Noisy signatures (DNS ANY query, etc.)
|
||||
```
|
||||
|
||||
### Suppress False Positives
|
||||
|
||||
```bash
|
||||
# Edit Suricata threshold.config
|
||||
sudo nano /etc/suricata/threshold.config
|
||||
|
||||
# Suppress specific signature for specific IP
|
||||
suppress gen_id 1, sig_id 2100498, track by_src, ip 10.10.3.50
|
||||
# Signature 2100498 from source 10.10.3.50 will be suppressed
|
||||
|
||||
# Rate limit alerts (max 5 per 60 seconds)
|
||||
threshold gen_id 1, sig_id 2010937, type threshold, track by_src, count 5, seconds 60
|
||||
|
||||
# Restart Suricata
|
||||
sudo so-suricata-restart
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## LAB 4.5.5: LOG CORRELATION
|
||||
|
||||
### Multi-Source Event Correlation
|
||||
|
||||
**Scenario:** Detect full attack chain (scan → exploit → command execution)
|
||||
|
||||
```
|
||||
# Step 1: Find nmap scan in Suricata
|
||||
alert.signature: "GPL SCAN nmap*" AND source.ip: "10.10.2.50"
|
||||
# Note timestamp: 2026-02-11T14:30:00
|
||||
|
||||
# Step 2: Find exploit attempt within 10 minutes
|
||||
@timestamp: ["2026-02-11T14:30:00" TO "2026-02-11T14:40:00"]
|
||||
AND alert.signature: *exploit*
|
||||
AND destination.ip: "10.10.4.10"
|
||||
|
||||
# Step 3: Find Zeek connection logs showing data transfer
|
||||
event.dataset: "zeek.conn"
|
||||
AND source.ip: "10.10.2.50"
|
||||
AND destination.ip: "10.10.4.10"
|
||||
AND zeek.conn.orig_bytes: >10000
|
||||
AND @timestamp: ["2026-02-11T14:35:00" TO "2026-02-11T14:45:00"]
|
||||
|
||||
# Step 4: Build correlation rule (in Kibana detection rules)
|
||||
{
|
||||
"name": "Attack Chain: Scan to Exploit",
|
||||
"description": "Detects nmap scan followed by exploit attempt",
|
||||
"index": ["so-*"],
|
||||
"query": "sequence by source.ip with maxspan=15m
|
||||
[alert.signature: \"GPL SCAN nmap*\"]
|
||||
[alert.signature: *exploit*]"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
##DELIVERABLES
|
||||
|
||||
- [ ] Custom Kibana dashboard with 5+ visualizations
|
||||
- [ ] KQL query library (saved searches for common threats)
|
||||
- [ ] Alert tuning configuration (threshold.config)
|
||||
- [ ] Correlation rule for attack chain detection
|
||||
- [ ] Data export script for React dashboard integration
|
||||
|
||||
---
|
||||
|
||||
**END OF MODULE 4.5**
|
||||
|
||||
Proceed to **MOD5: Active Directory Threat Emulation** after mastering SIEM query skills.
|
||||
Reference in New Issue
Block a user