Direkt zum Inhalt
09.03.2021 - Fachbeitrag

# Emotet mit Rspamd und Oletools bekämpfen - Heinlein Default (Teil 7)

Der Extended Mode von Oletools ist eine tolle Möglichkeit auf spezialisierte Anforderungen zu reagieren. Aber ehrlich gesagt kommt dieser bei uns selten zum Einsatz. Oft werden schädliche Makros bei eingehenden externen E-Mails vor der Annahme abgelehnt. Interner Versand von Office-Dokumenten mit Makros bleibt meist erlaubt und wird dann nur geloggt. Irgendwo verstecken sich doch immer noch ein paar Formulare oder eine besondere Software, die nicht auf bestimmte Makros verzichten kann. Daher verwenden wir in den meisten Fällen den einfachen Modus der Oletools.

Nach und nach haben wir immer mehr Office-Formate gefunden, die theoretisch von Microsoft Office geöffnet werden könnten, auch wenn sie in der Öffentlichkeit quasi unbekannt sind. Außerdem scheint es so, dass MS Office beim Öffnen eine Formaterkennung durchführt und auch eine virus.rtf Datei als .doc ausführt, wenn das .doc Format erkannt wird. Es gab wahrscheinlich einige Spam-Wellen, die eben mit diesen in .rtf umbenannten .doc Dateien arbeiteten. Daher haben wir uns entschieden, sämtliche potenzielle Office-Dokumente durch Oletools prüfen zu lassen. Glücklicherweise gibt uns Oletools recht schnell einen Fehler zurück, wenn das Format nicht geprüft werden kann. Daher ist unsere Standard-Config etwas länger ;)

# /etc/rspamd/local.d/external_services.conf
oletools {
  symbol = "OLETOOLS";
  type = "oletools";
  log_clean = true;
  cache_expire = 86400;
  scan_mime_parts = true;
  servers = "127.0.0.1";
  default_port = "10050";

  # mime_parts_filter_ext and mime_parts_filter_regex limit the mime_parts
  # send to oletools to matching regex or extensions configured below
  #
  # As MS Office maybe processes renamed or faked extension as vulnerable type
  # we will send many mime_parts which oletools cannot open - that's expected
  mime_parts_filter_regex {
      # symbol_name = "pattern";
    # Generic
    #GEN1 = "application/octet-stream";
    GEN2 = "application/vnd.ms-office.*"
    GEN3 = "application/vnd.openxmlformats-officedocument.*";
    GEN4 = "application/x-mimearchive";
    GEN5 = "application/xml";
    # MS Word
    DOC = "application/vnd.ms-word.*";
    DOC2 = "application/msword";
    RTF = "application/rtf";
    RTF2 = "text/rtf";
    RTF3 = "text/richtext";
    WRI = "application/mswrite";
    CDFV2 = "application/CDFV2-unknown";
    # MS Excel
    XLS = "application/vnd.ms-excel.*";
    XLS2 = "application/msexcel.*";
    # MS Powerpoint
    PPT = "application/vnd.ms-powerpoint.*";
    PPT2 = "application/mspowerpoint"
    # MS Visio
    VSD = "application/vnd.ms-visio.*";
    VSD2 = "application/vnd.visio.*";
    # MS Works (legacy)
    WKS = "application/vnd.ms-works.*"
    # Visual Basic
    VB1 = "text/x-vbasic";
    VB2 = "text/x-vbscript";
    VB3 = "text/x-vb";
    VB4 = "text/vbscript";
  }

  mime_parts_filter_ext {
      # symbol_name = "pattern";
    # Generic
    slk = "slk";
    mht = "mht";
    mhtml = "mhtml";
    xml = "xml";
    xps = "xps"
    # MS Word
    doc = "doc";
    dot = "dot";
    docx = "docx";
    dotx = "dotx";
    docm = "docm";
    dotm = "dotm";
    dotb = "dotb";
    word = "word";
    w6w = "w6w";
    wkb = "wbk";
    rtf = "rtf";
    wri = "wri";
    wps = "wps";
    # MS Excel
    xls = "xls";
    xlt = "xlt";
    xla = "xla";
    xlm = "xlm";
    xll = "xll";
    xlw = "xlw";
    xlsx = "xlsx";
    xltx = "xltx";
    xlsm = "xlsm";
    xltm = "xltm";
    xlam = "xlam";
    xlsb = "xlsb";
    # MS Word Powerpoint
    ppt = "ppt";
    pot = "pot";
    pps = "pps";
    ppa = "ppa";
    pptx = "pptx";
    potx = "potx";
    ppsx = "ppsx";
    ppam = "ppam";
    pptm = "pptm";
    potm = "potm";
    ppsm = "ppsm";
    sldx = "sldx";
    sldm = "sldm";
    # MS Visio
    vsd = "vsd";
    vsdx = "vsdx";
    vsdm = "vsdm";
    vssx = "vssx";
    vstx = "vstx";
    vstm = "vstm";
    # MS Publisher
    pub = "pub";
    # Visual Basic
    vbs = "vbs";
    vba = "vba";
    bas = "bas";
    cls = "cls";
    frm = "frm";
    frx = "frx";
  }

  patterns_fail {
    OLETOOLS_TIMEOUT = ".*err: (Socket error detected|IO read error while trying to read data): .*";
    OLETOOLS_OPEN_ERROR = ".*RETURN_OPEN_ERROR.*";
  }
}

Wie wir im Teil 2 gezeigt haben, schränken wir durch die Optionen scan_mime_parts, mime_parts_filter_regex und mime_parts_filter_ext die zu analysierenden Anhänge auf Office-Erweiterungen ein. Ein Caching von 86400 entspricht 1 Tag und ist für eine Analyse völlig in Ordnung, denn im Gegensatz zu Anti-Virus Signaturen laufen wir hier nicht Gefahr, dass sich die Einschätzung kurzfristig ändern könnte. Bei Oletools wirkt ja auch der dynamic_scan Mechanismus, so dass ein Anhang nur analysiert wird, wenn die Erkenntnisse anderer Plugins nicht schon sicher zur Ablehnung oder Annahme der E-Mail führen.

Außerdem kommt eine noch nicht erwähnte Option vor. Ähnlich wie bei patterns, ist es mit patterns_fail möglich aus Fehlern beim Scannen neue Symbole zu erzeugen. Normalerweise würde Rspamd bei einem Fehler das Symbol OLETOOLS_FAIL setzen. Um hier differenzieren zu können nutzen wir patterns_fail.

Dazu definieren wir zur besseren Kontrolle die neuen Symbole auch in external_services_group.conf

# /etc/rspamd/local.d/external_services_group.conf
symbols {
  ...
  "OLETOOLS" {
    weight = 10;
    description = "OLETOOLS triggered";
    one_shot = true;
    groups = ["virus_reject"]
  }
  "OLETOOLS_ENCRYPTED" {
    weight = 0;
    description = "OLETOOLS triggered - encrypted";
    groups = ["encrypted_attachment"]
  }
  "OLETOOLS_TIMEOUT" {
    weight = 0;
    description = "OLETOOLS connection timeout";
  }
  "OLETOOLS_OPEN_ERROR" {
    weight = 0;
    description = "OLETOOLS could not open file";
  }
}

OLETOOLS_ENCRYPTED wird übrigens direkt vom Plugin gesetzt, ohne dass hier etwas konfiguriert werden muss. Während wir das Symbol OLETOOLS nun als Virus einschätzen und direkt rejecten, kommt es bei OLETOOLS_ENCRYPTED, also Office Dateien mit Passwort, auf die lokale Mail Policy an. OLETOOLS_OPEN_ERROR sind Scans von Dateien mit denen Oletools nicht umgehen kann. OLETOOLS_TIMEOUT wird gesetzt, wenn olefy nicht durch Rspamd erreicht werden kann, oder wenn die Analyse zu lange dauert und Rspamd die Abfrage via Timeout abbricht. Das Symbol verknüpfen wir mit der Makro Erkennung von ClamAV. Das heißt, wenn ClamAV ein Makro erkennt (patterns), Oletools die Datei aber nicht analysieren konnte, lehnen wir die Mail temporär ab.

rules {
  ...
  OLETOOLS_TIMEOUT {
      action = "soft reject";
      message = "security scanner failure Ref#7365 support-id: ${queueid}";
      expression = "CLAM_HEUR_OLE2_VBA_MACRO & OLETOOLS_TIMEOUT";
      require_action = ["no action", "soft reject", "greylist", "add header", "rewrite subject"];
  }
  ...
}

Für interne Systeme, wo erkannte, potenziell schädliche Makros nicht blockiert werden sollen, kann Oletools komplett abgeschaltet werden - oder sinnvoller - nicht weiter in die Bewertung einfließen. Dann könnte mensch nämlich aus den Logs einen Report über die interne Verwendung erstellen.

# /etc/rspamd/local.d/settings.conf

internal_systems {
  id = "internal_systems";
  priority = high;
  # remote client ip
  ip = "172.16.0.0/24";
  
  apply {
    OLETOOLS = 0.0;
    symbols_disabled = [
      # "OLETOOLS",
      "OLETOOLS_TIMEOUT",
      # ...
    ];
    groups_disabled = [
    ];
  }
  symbols [
    "INTERNAL_SYSTEMS"
  ]
}

Mit diesem Weg müsste die force_action für OLETOOLS aber noch angepasst werden:

rules {
  ...
  OLETOOLS_REJECT {
    action = "reject";
    expression = "OLETOOLS and not INTERNAL_SYSTEMS";
    message = "REJECT - Bad Office Macro found - Ref#7362 id: ${queueid}";
    require_action = ["no action", "greylist", "soft reject", "add header", "rewrite subject", "reject"];
  }
  ...
}

Kurz noch etwas zu diesem ominösen dynamic_scan. Diesen Mechanismus haben wir geschaffen, um langlaufende externe Scans nur auszuführen, wenn es notwendig erscheint, bei Rspamd bedeutet sowas ca. 300ms+. Dazu lassen wir Plugins wie Oletools oder Spamassassin in external_services als Postfilter laufen. Rspamd kennt je nach Zählweise 3-7 Processing Stages. Die Wichtigsten sind dabei Prefilter, All Plugins, Postfilter. Pre-Filter sind vor allem Funktionen wie Settings (Profile), die früh zur Verfügung stehen müssen oder wie die Greylisting Prüfung, die evaluiert,ob die 5 Minuten Soft-Reject-Zeit schon abgelaufen ist. Führt ein Pre-Filter zu einem Reject, müssen alle anderen Plugins nicht mehr ausgeführt werden. Bei All Filters werden alle normalen Funktionen ausgeführt. Sind diese alle abgeschlossen, werden die Postfilter aufgerufen, die die bisher ausgewerteten Funktionen dann gut auswerten können. Als Postfilter kann Oletools also prüfen, ob die E-Mail nicht schon sicher abgelehnt wird. dynamic_scan ist nun eine Funktion, die genau dafür genutzt wird. Wenn ein Scan als Aktion schon auf reject steht oder der Score schon das Doppelte des Reject Limits erreicht hat, wird das betreffende Plugin gar nicht mehr ausgeführt. Das heißt für sicher erkannten Spam oder erkannte Viren brauchen wir nicht auf das "langsame" Oletools zu warten und rejecten früher.

Wenn Ihr möchtet könnt ihr dynamic_scan auch abschalten und Oletools immer
prüfen lassen:

```
# /etc/rspamd/local.d/external_services.conf

oletools {
  ...
  dynamic_scan = false;
  symbol_type = "normal";
  ...
}
```

dynamic_scan könnte mensch einfach auf false setzen. Damit würde Oletools aber immer noch als Postfilter laufen. Das wäre jetzt ja kontraproduktiv. Daher sollte auch der symbol_type auf "normal" gesetzt werden, um in der "All Plugins" Processing Stage ausgeführt zu werden.

Zwei Optionen der Rules in Antivirus bzw. External Services setzen wir bewusst nicht ein - "action" und das damit zusammenhängende "message". Action kann auf reject gesetzt werden und führt auch ohne force_actions gleich zu einer Ablehnung der Mail. Das passiert unserer Meinung aber zu unspezifisch. Denn auch wenn via Patterns neue Symbole erzeugt werden, wird die action reject gesetzt. Reject ist übrigens auch die einzige Einstellung, die für action möglich ist. Wir verwenden zum Rejecten bei allen Rules in Antivirus und External Services lieber die Force Actions, Composites und Settings. Das ist weit aus flexibler.

Autor: Carsten Rosenberg, Linux-Consultant, Heinlein Support

Hier nochmal alle bisher erschienenen Artikel aus unserer Reihe "Emotet mit Rspamd und Oletools bekämpfen" zum Nachlesen:

Emotet mit Rspamd und Oletools bekämpfen (Teil 1)
Emotet mit Rspamd und Oletools bekämpfen (Teil 2)
Emotet mit Rspamd und Oletools bekämpfen – Emotet 2020 (Teil 3)
Emotet mit Rspamd und Oletools bekämpfen – die vielen kleinen Tricks (Teil 4)
Emotet mit Rspamd und Oletools bekämpfen - Extended Mode (Teil 5)
Emotet mit Rspamd und Oletools bekämpfen - Ein Anwendungsbeispiel (Teil 6)