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:
CyberMind-FR 2026-02-02 10:34:20 +01:00
parent 4a8975f436
commit 77e572a787
2 changed files with 70 additions and 30 deletions

View File

@ -57,6 +57,28 @@ get_crowdsec_alerts() {
$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
# ==============================================================================
@ -493,39 +515,28 @@ case "$1" in
;;
get_active_threats)
# Main correlation workflow
local netifyd_data=$(get_netifyd_flows)
local risky_flows=$(filter_risky_flows "$netifyd_data")
# Get mitmproxy threats from threats.log (primary source for WAN protection)
_log_file="/srv/mitmproxy/threats.log"
_threats_json="[]"
# Only fetch CrowdSec data if available
local decisions='[]'
local alerts='[]'
if [ -x "$CSCLI" ]; then
decisions=$(get_crowdsec_decisions)
alerts=$(get_crowdsec_alerts)
if [ -f "$_log_file" ]; then
_threats_json=$(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, cve: .cve, response_code: .response_code}
}) | unique_by(.ip) | sort_by(.risk_score) | reverse
' 2>/dev/null || echo "[]")
fi
# Correlate threats
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
printf '{"threats":%s}\n' "$_threats_json"
;;
get_threat_history)

View File

@ -308,8 +308,25 @@ CVE_PATTERNS = {
'screenconnect': [r'/SetupWizard\.aspx'],
# CVE-2024-27198 (TeamCity)
'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:
def __init__(self):
self.geoip = None
@ -543,6 +560,18 @@ class SecuBoxAnalytics:
'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
for pattern in LDAP_INJECTION_PATTERNS:
if re.search(pattern, combined, re.IGNORECASE):