Skip to content

feat: map IOC scores to Sigma-aligned log levels#11

Merged
Neo23x0 merged 5 commits intoNextron-Labs:masterfrom
RuneCode14:feature/ioc-score-levels
Mar 27, 2026
Merged

feat: map IOC scores to Sigma-aligned log levels#11
Neo23x0 merged 5 commits intoNextron-Labs:masterfrom
RuneCode14:feature/ioc-score-levels

Conversation

@RuneCode14
Copy link
Copy Markdown

@RuneCode14 RuneCode14 commented Mar 25, 2026

Summary

Map IOC scores (0–100) to Sigma-aligned log levels for both filename and C2 IOCs, so downstream consumers (SIEM, dashboards) can filter IOC matches the same way they filter Sigma alerts.

Score-to-Level Mapping

Score Level Log Level
0–39 info log.Info
40–59 low log.Info
60–74 medium log.Warn
75–89 high log.Error
90–100 critical log.Error

Changes

C2 IOCs (c2.go)

  • Parse optional ;SCORE suffix (e.g., evil.com;65)
  • Default to score 80 (high) when no score is specified
  • Reject indicators with invalid FQDN characters (whitelist: [a-zA-Z0-9.-])
  • Specific warning when : is used instead of ; (common typo)
  • Emit ioc_score and ioc_level fields in match logs

Unified scoreToLevel() (iocconsumer.go)

  • Single mapping function used by both filename and C2 IOC consumers
  • Returns both log.Level and human-readable level name
  • Replaces old logLevelForFilenameScore() (kept as backwards-compat wrapper)

Example Log Output

{
  "ioc_type": "c2",
  "ioc_field": "DestinationIp",
  "ioc_value": "176.123.5.126",
  "ioc_indicator": "176.123.5.126",
  "ioc_score": 65,
  "ioc_level": "medium",
  "level": "warning",
  "message": "IOC match"
}

Tests

  • TestC2IOCWithScoreParsing — scored + unscored C2 entries, correct level mapping
  • TestLoadC2IOCsWithScores — score parsing at load time
  • TestLoadC2IOCsRejectsMalformedEntries — colon typo, whitespace, underscores, empty indicator, non-numeric score
  • TestLoadFilenameIOCsThreeFieldFormat — REGEX;SCORE;FP_REGEX format with FP exclusion validation
  • TestLoadFilenameIOCsRejectsMalformedEntries — missing score, invalid regex, bad FP regex
  • TestScoreToLevel — boundary tests for all level transitions
  • TestFilenameIOCLevelFieldioc_level emitted at all 5 severity tiers
  • TestValidateRealC2IOCs / TestValidateRealFilenameIOCs — integration tests against production IOC files

Production IOC Validation

Tested against /opt/aurora-linux/resources/iocs/:

  • C2: 1,773 IOCs (1,655 domains, 118 IPs) — 100% accepted ✅
  • Filename: 3,732 entries (30 with FP exclusions) — 100% accepted ✅

Backwards Compatibility

  • Unscored C2 entries default to score 80 → error level (same as before)
  • Filename IOC scoring unchanged (already had scores)
  • logLevelForFilenameScore() preserved as wrapper for any external callers

RuneBot14 added 5 commits March 25, 2026 20:37
- Parse optional ;SCORE suffix in C2 IOC files (e.g. 176.123.5.126;65)
- Introduce unified scoreToLevel() mapping IOC scores (0-100) onto
  Sigma severity levels: info/low/medium/high/critical
- Emit ioc_level and ioc_score fields in all IOC match log entries
  (both filename and C2) for consistent downstream filtering
- C2 entries without explicit score default to 80 (high), preserving
  previous behaviour where all C2 matches logged at error level
- Score-to-level mapping:
    0-39  → info     (log.Info)
   40-59  → low      (log.Info)
   60-74  → medium   (log.Warn)
   75-89  → high     (log.Error)
   90-100 → critical (log.Error)
- Add comprehensive tests for C2 score parsing, level mapping,
  and ioc_level field presence in output
- Reject C2 indicators with invalid FQDN characters (specific hint for ':' typo)
- Test colon-vs-semicolon, whitespace, underscores, empty indicators
- Test three-field filename IOC format (REGEX;SCORE;FP_REGEX)
- Test malformed filename IOCs (missing score, bad regex, invalid FP regex)
- Add integration tests validating all production IOCs load correctly
- Verified: 1,773 C2 IOCs + 3,732 filename IOCs load with zero rejects
@Neo23x0 Neo23x0 marked this pull request as ready for review March 26, 2026 22:14
@Neo23x0 Neo23x0 merged commit 8fb77a1 into Nextron-Labs:master Mar 27, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants