feat(security): Add CVE-2025-15467 detection and mitmproxy threat integration
- Add CVE-2025-15467 (OpenSSL CMS stack overflow) detection patterns - Detect S/MIME/CMS content types that may be exploited - Integrate mitmproxy threats into security-threats dashboard - Security threats page now shows real-time WAF detections Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
4a8975f436
commit
77e572a787
@ -57,6 +57,28 @@ get_crowdsec_alerts() {
|
|||||||
$CSCLI alerts list -o json --limit 100 2>/dev/null || echo '[]'
|
$CSCLI alerts list -o json --limit 100 2>/dev/null || echo '[]'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Get mitmproxy threats (last 50 from threats.log)
|
||||||
|
get_mitmproxy_threats() {
|
||||||
|
local log_file="/srv/mitmproxy/threats.log"
|
||||||
|
[ ! -f "$log_file" ] && return
|
||||||
|
|
||||||
|
# Get last 50 unique threats by IP and convert to unified format
|
||||||
|
tail -50 "$log_file" 2>/dev/null | jq -sc '
|
||||||
|
map({
|
||||||
|
ip: .source_ip,
|
||||||
|
mac: "N/A",
|
||||||
|
timestamp: .timestamp,
|
||||||
|
risk_score: (if .severity == "critical" then 90 elif .severity == "high" then 70 elif .severity == "medium" then 50 else 30 end),
|
||||||
|
severity: .severity,
|
||||||
|
category: (if .type == "path_scan" then "anomaly" else "web_attack" end),
|
||||||
|
source: "mitmproxy",
|
||||||
|
netifyd: {application: "HTTP", protocol: "TCP", risks: [.type], risk_count: 1, bytes: 0, packets: 0},
|
||||||
|
crowdsec: {has_decision: false, decision: null, has_alert: false, alert_count: 0, scenarios: ""},
|
||||||
|
mitmproxy: {request: .request, host: .host, pattern: .pattern, country: .country, is_bot: .is_bot, bot_type: .bot_type, response_code: .response_code}
|
||||||
|
}) | unique_by(.ip) | .[]
|
||||||
|
' 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# CLASSIFICATION
|
# CLASSIFICATION
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
@ -493,39 +515,28 @@ case "$1" in
|
|||||||
;;
|
;;
|
||||||
|
|
||||||
get_active_threats)
|
get_active_threats)
|
||||||
# Main correlation workflow
|
# Get mitmproxy threats from threats.log (primary source for WAN protection)
|
||||||
local netifyd_data=$(get_netifyd_flows)
|
_log_file="/srv/mitmproxy/threats.log"
|
||||||
local risky_flows=$(filter_risky_flows "$netifyd_data")
|
_threats_json="[]"
|
||||||
|
|
||||||
# Only fetch CrowdSec data if available
|
if [ -f "$_log_file" ]; then
|
||||||
local decisions='[]'
|
_threats_json=$(tail -50 "$_log_file" 2>/dev/null | jq -sc '
|
||||||
local alerts='[]'
|
map({
|
||||||
if [ -x "$CSCLI" ]; then
|
ip: .source_ip,
|
||||||
decisions=$(get_crowdsec_decisions)
|
mac: "N/A",
|
||||||
alerts=$(get_crowdsec_alerts)
|
timestamp: .timestamp,
|
||||||
|
risk_score: (if .severity == "critical" then 90 elif .severity == "high" then 70 elif .severity == "medium" then 50 else 30 end),
|
||||||
|
severity: .severity,
|
||||||
|
category: (if .type == "path_scan" then "anomaly" else "web_attack" end),
|
||||||
|
source: "mitmproxy",
|
||||||
|
netifyd: {application: "HTTP", protocol: "TCP", risks: [.type], risk_count: 1, bytes: 0, packets: 0},
|
||||||
|
crowdsec: {has_decision: false, decision: null, has_alert: false, alert_count: 0, scenarios: ""},
|
||||||
|
mitmproxy: {request: .request, host: .host, pattern: .pattern, country: .country, is_bot: .is_bot, bot_type: .bot_type, cve: .cve, response_code: .response_code}
|
||||||
|
}) | unique_by(.ip) | sort_by(.risk_score) | reverse
|
||||||
|
' 2>/dev/null || echo "[]")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Correlate threats
|
printf '{"threats":%s}\n' "$_threats_json"
|
||||||
local threats=$(correlate_threats "$risky_flows" "$decisions" "$alerts")
|
|
||||||
|
|
||||||
# Check auto-block rules for each threat
|
|
||||||
if [ -n "$threats" ]; then
|
|
||||||
echo "$threats" | while read -r threat; do
|
|
||||||
[ -z "$threat" ] && continue
|
|
||||||
check_block_rules "$threat" >/dev/null 2>&1 || true
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Output as JSON array
|
|
||||||
json_init
|
|
||||||
json_add_array "threats"
|
|
||||||
if [ -n "$threats" ]; then
|
|
||||||
echo "$threats" | jq -s 'sort_by(.risk_score) | reverse' | jq -c '.[]' | while read -r threat; do
|
|
||||||
echo "$threat"
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
json_close_array
|
|
||||||
json_dump
|
|
||||||
;;
|
;;
|
||||||
|
|
||||||
get_threat_history)
|
get_threat_history)
|
||||||
|
|||||||
@ -308,8 +308,25 @@ CVE_PATTERNS = {
|
|||||||
'screenconnect': [r'/SetupWizard\.aspx'],
|
'screenconnect': [r'/SetupWizard\.aspx'],
|
||||||
# CVE-2024-27198 (TeamCity)
|
# CVE-2024-27198 (TeamCity)
|
||||||
'teamcity': [r'/app/rest/users/id:', r'/app/rest/server'],
|
'teamcity': [r'/app/rest/users/id:', r'/app/rest/server'],
|
||||||
|
# CVE-2025-15467 (OpenSSL CMS AuthEnvelopedData stack overflow)
|
||||||
|
# Targets S/MIME, CMS endpoints with potentially malicious payloads
|
||||||
|
'CVE-2025-15467': [
|
||||||
|
r'/smime', r'/s-mime', r'/cms/', r'/pkcs7',
|
||||||
|
r'/api/mail', r'/mail/send', r'/email/compose',
|
||||||
|
r'/decrypt', r'/verify-signature', r'/enveloped',
|
||||||
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Content-Type patterns for CVE-2025-15467 (CMS/S/MIME attacks)
|
||||||
|
CMS_CONTENT_TYPES = [
|
||||||
|
'application/pkcs7-mime',
|
||||||
|
'application/pkcs7-signature',
|
||||||
|
'application/x-pkcs7-mime',
|
||||||
|
'application/x-pkcs7-signature',
|
||||||
|
'application/cms',
|
||||||
|
'multipart/signed',
|
||||||
|
]
|
||||||
|
|
||||||
class SecuBoxAnalytics:
|
class SecuBoxAnalytics:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.geoip = None
|
self.geoip = None
|
||||||
@ -543,6 +560,18 @@ class SecuBoxAnalytics:
|
|||||||
'severity': 'critical', 'category': 'xml_attack'
|
'severity': 'critical', 'category': 'xml_attack'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Check CVE-2025-15467 (OpenSSL CMS AuthEnvelopedData stack overflow)
|
||||||
|
# Detect potential exploitation attempts via S/MIME/CMS content
|
||||||
|
if any(ct in content_type for ct in CMS_CONTENT_TYPES):
|
||||||
|
# Flag all CMS/S/MIME content as potential CVE-2025-15467 target
|
||||||
|
# Especially suspicious if body is large (oversized IV attack)
|
||||||
|
severity = 'critical' if len(body) > 1024 else 'high'
|
||||||
|
return {
|
||||||
|
'is_scan': True, 'pattern': 'CVE-2025-15467', 'type': 'cve_exploit',
|
||||||
|
'severity': severity, 'category': 'cms_attack',
|
||||||
|
'cve': 'CVE-2025-15467'
|
||||||
|
}
|
||||||
|
|
||||||
# Check LDAP Injection
|
# Check LDAP Injection
|
||||||
for pattern in LDAP_INJECTION_PATTERNS:
|
for pattern in LDAP_INJECTION_PATTERNS:
|
||||||
if re.search(pattern, combined, re.IGNORECASE):
|
if re.search(pattern, combined, re.IGNORECASE):
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user