Microsoft Defender hält Synology-Backups für einen Trojaner (3.8.2026)

BugIch stelle mal eine Beobachtung eines Blog-Lesers hier ein, die mich heute erreicht hat. Der Microsoft Defender hält Synology-Backups auf den Server des Betroffenen für einen Trojaner. Dadurch laufen die Sicherungen nicht mehr durch. Diesen Prozess "Zulassen" schaltet die ganze Erkennungsregel ab, schrieb mir der Leser. Und noch krasser ist die Analyse des Lesers, was den Microsoft Defender reagieren lässt

Ein Leserhinweis auf Defender Fehlalarm

Blog-Leser Stefan M. hat mich am heutigen 3. August 2026 per E-Mail unter dem Betreff "Defender hält Synology-Backups für einen Trojaner – und „Zulassen" schaltet die ganze Erkennungsregel ab" kontaktiert (danke dafür). Der Leser setzt den Microsoft Defender auf seinen Windows Servern ein und verwendet Synology-Backups zur Sicherung.

Stefan schrieb mir, dass der Microsoft Defender auf seinen Servern zuverlässig verhindert hat, dass die Sicherungen durchlaufen. Nicht wegen eines Fehlers im Backup, sondern der Defender das Synology-Sicherungsprogramm für einen Trojaner gehalten und entfernt. Seitdem sind die virtuellen Maschinen des Lesers vor allem eines: ungesichert.

Zur Einordnung: Mehrere betroffene Systeme

Betroffen ist Synology Active Backup for Business (ABB). Zur ersten Einordnung beschrieb mir der Leser folgendes Fehlerbild:

  • Das Problem trat nahezu gleichzeitig auf allen Windows-Hypervisoren auf, die ich bei verschiedenen Kunden betreue – verschiedene Standorte, verschiedene Netze, verschiedene Windows-Server-Varianten.
  • Parallel dazu bei einem Kollegen, in einer von mir völlig unabhängigen Umgebung.
    Active Backup for Business ist überall auf dem aktuellen Stand.
  • Auf allen betroffenen Systemen läuft der Defender im Auslieferungszustand: keine Härtung, keine erhöhte Cloud-Blockstufe, keine zusätzlichen Regeln.

Lokale Konfiguration, eine bestimmte Server-Version, ein bestimmter ABB-Stand und Zufall scheiden damit laut Leser aus. "Es lag ausnahmsweise nicht an mir – in unserem Beruf ein so seltener Moment, dass ich ihn hiermit aktenkundig mache", merkte der Leser in seiner Mai an.

Der "Fund" des Defender

Stefan schrieb mir, dass der Defender einen Fund: "Trojan:Win32/Commando.A!ml" erkannt haben will. Der Schweregrad ist "Schwerwiegend", der Status "Entfernt". Sprich: Das Synology-Backup-Programm wurde in Quarantäne geschoben.

Defender Schutzverlauf
Meldung des Defender, zum Vergrößern klicken

Dazu die Einschätzung des Defenders, die der Leser wörtlich übermittelt hat, weil sie im späteren Kontext noch komisch wird:

"Dieses Programm ist gefährlich. Es führt Befehle eines Angreifers aus."

Als betroffenes Element nennt der Schutzverlauf eine Kommandozeile, keine Datei sondern diesen Befehl:

C:\Windows\System32\cmd.exe /C powershell -encodedcommand <langer Base64-Block>

Auf einem der betroffenen Server liefen laut Leser so binnen zwei Tagen 15 Meldungen in das Protokoll, und das im Stundentakt. Denn der Verbindungstest läuft als geplante Aufgabe. Der "Angreifer", den er Defender erkannt haben will, sei vor allem eines: pünktlich, schrieb der Leser.

Analyse: Was der "Angreifer" tatsächlich tut

Der Blog-Leser hat dann eine Analyse gestartet und schrieb: "Der wirklich interessante Teil kommt allerdings erst, wenn man den Fehlalarm auf dem naheliegenden Weg abstellt".

Ein Verbindungstest als Ursache

Der Leser hat den vom Defender gemeldeten Base64-Block genauer angeschaut und schrieb: "Dekodiert man den Base64-Block (UTF-16LE), entpuppt sich der Angriff als Verbindungstest":

$ip = '<NAS-IP>'
$port = 5510
$secret = '<Token>'
$b64 = "QhAABmFjdGlvbhAAD3Rlc3RfY29ubmVjdGlvbkA="
$data = [System.Convert]::FromBase64String($b64)
$client = New-Object System.Net.Sockets.TcpClient
$client.Connect($ip, $port)
$stream = $client.GetStream()
$stream.Write($data, 0, $data.Length)
...
if ([System.Text.Encoding]::ASCII.GetString($response) -eq $secret) {
@{Connected = $true}
}

Der innere Base64-String ergibt 29 Byte, die im Klartext { action: "test_connection" } bedeuten. Das ist der komplette Schadcode:

  • TCP-Verbindung zur NAS auf Port 5510, 29 Byte hin,
  • Antwort gegen ein Shared Secret prüfen,
  • {"Connected": true} zurück.

Kein Nachladen von Code, kein Invoke-Expression, keine Persistenz, keine Datei- oder Registry-Zugriffe, schrieb der Leser. Ziel sei eine private Adresse im selben Netz ("der Angreifer sitzt also im Serverschrank nebenan" unkte der Leser in seiner Mail).

Und dann ist da noch diese Zeile in der Analyse aufgefallen, wo es dann arg kryptisch wird:

raise "fail"

Denn "raise" ist eine Anweisung in Python. In der PowerShell-Syntax gibt es das nicht, dort heißt es "throw". Die PowerShell sucht also gewissenhaft nach einem Befehl namens "raise", findet keinen und wirft eine CommandNotFoundException. Die landet im umgebenden Catch und liefert am Ende {"Connected": false}. Der Fehlerpfad tut damit exakt das Richtige – allerdings nicht, weil dort ein Fehler geworfen wird, sondern weil die Zeile schlicht kaputt ist.

Damit kommt der Leser zurück zum Defender und seiner Einschätzung, dieses Programm führe Befehle eines Angreifers aus. "Ein Angreifer, der seinen Rückkanal in der falschen Programmiersprache abbricht, wäre mir neu. Für maschinell erzeugten Hersteller-Klebe-Code ist es dagegen ein vertrauter Anblick."

Es geht vermutlich gar nicht um Synology

Der Leser schrieb dann in seiner Analyse: "Derselbe Erkennungsname – intern ThreatID 2147840094 – hat auf meiner Arbeitsstation bereits am 27.07.2026 zugeschlagen, gegen ein völlig unbeteiligtes, selbst geschriebenes PowerShell-Skript. Anderer Rechner, anderer Code, kein Synology in Sichtweite. Gemeinsam war beiden Fällen nur der Parameter -EncodedCommand". Auf einem betroffenen Server lösten laut Leser sogar drei verschiedene Programme dieselbe Signatur aus: cmd.exe, powershell.exe und pwsh.exe.

Die Signatur erkennt also kein Programm, sondern ein Verhaltensmuster: kodierter Befehl, Netzwerkverbindung, Base64-Nutzlast. Synology fällt laut Analyse des Lesers nur deshalb so auf, weil dort ein produktiver Backup-Dienst daran hängt.

Vergleichbare Fehlalarme sind derzeit auch bei anderen Werkzeugen dokumentiert, die ihre PowerShell-Aufrufe maschinell zusammenbauen, etwa in den Issues 15423 und 26218 des OpenAI-Codex-Projekts.

Und jetzt der eigentliche Punkt: Zulassen führt ins Desaster

Nach der fünfzehnten Meldung in den logs hat der Nutzer das getan, was Administratoren um diese Uhrzeit tun: Er hat im Schutzverlauf des Microsoft Defender auf "Zulassen" geklickt. Die Meldungen hörten auf, der Administrator war im ersten Augenblick zufrieden.

Der Fehler war dann, mal nachzusehen, was dieser Klick eigentlich bewirkt. Das Ergebnis hat den Leser dann deutlich mehr beunruhigt als der Fehlalarm. Der Klickt auf "Zulassen" bewirkt, dass der Defender einen einzigen Registry-Wert schreibt. DasEreignis 5007 hält ihn fest:

HKLM\SOFTWARE\Microsoft\Windows Defender\Threats\ThreatIDDefaultAction\2147840094 = 0x6

Der Wert 2147840094 ist die Signaturnummer, 0x6 bedeutet Allow. Nicht der Pfad des Werkzeugs, nicht sein Hash, nicht die Kommandozeile, sondern die Erkennungsregel selbst wird stummgeschaltet. Geräteweit, für jedes Programm, das dieses Muster künftig zeigt. Der Leser merkt dazu an, dass man nicht "mein Skript" erlaubt, sondern der Nutzer erlaubt "kodierte PowerShell mit Netzwerkverbindung". Das !ml im Namen steht für Machine Learning gibt der Leser an. Solche Signaturen seien absichtlich großzügig gefasst, merkt Stefan an. Beim Zulassen sei diese Großzügigkeit dann leider inbegriffen.

Aus Sicht des Blog-Lesers machen drei Eigenschaften diesen gesamten Ansatz äußerst heikel. Er beschrieb diese folgendermaßen:

  1. Es erlaubt die Technik, nicht das Werkzeug. Die Signatur existiert, weil Angreifer dieses Muster benutzen. Wer sie stummschaltet, damit das eigene Backup wieder läuft, schaltet sie auch für jeden anderen stumm, der mit demselben Muster vorbeikommt.
  2. Es ist praktisch unsichtbar. Der Eintrag steht nicht bei den Ausschlüssen, wo jeder Administrator nachsieht. Er taucht auch in Get-MpPreference nicht auf – gemessen: ThreatIDDefaultAction_Ids bleibt leer. Er lebt drei Klicks tief unter Schutzverlauf, Zulässige Bedrohungen, einer Ansicht, die man nur öffnet, wenn man bereits weiß, dass es sie gibt. Ein Nachfolger im Amt findet ihn nie und wird sich irgendwann fragen, warum dieser Defender bei kodierter PowerShell so bemerkenswert entspannt bleibt.
  3. Es ist unbefristet. Keine Frist, keine Wiedervorlage, kein Ablaufdatum. Ein Klick um 09:39 Uhr wirkt jahrelang weiter, über Betriebssystem-Upgrades hinweg.

Die Oberfläche des Microsoft Defender begünstigt den Denkfehler nach Kräften, merkt der Leser an. Denn der Defender-Dialog zeigt eine konkrete Kommandozeile mit einem konkreten Zeitstempel. Der Administrator entscheidet also gefühlt über einen Einzelfall. Und die Schaltfläche heißt "Zulassen", nicht "Diese Erkennungsregel dauerhaft abschalten" – was insofern bedauerlich ist, als Letzteres die zutreffendere Beschriftung wäre.

Was funktioniert

"Damit ABB wieder sichert, braucht es zwei Schritte, und der zweite wird gern übersehen", teilte mir der Leser mit: Erstens gilt es, den Fund zu entschärfen. Und zweitens muss man auf dem Windows-Host den Dienst "Synology Active Backup for Business Service" neu starten.

Ohne den zweiten Schritt passiert nämlich gar nichts. Der Dienst hat den abgeschossenen Verbindungstest als "NAS nicht erreichbar" verbucht und beharrt darauf. Skalieren lässt sich das schlecht, beides muss lokal am jeweiligen Host erledigt werden – bei mehreren Kundenumgebungen ist das ein Vormittag, merkt der Leser an.

Stefan ergänzte in seiner Mail: "Für den ersten Schritt halte ich inzwischen einen engen Pfad- oder Prozess-Ausschluss für den besseren Weg als die Signatur-Zulassung. Er bleibt sichtbar und beim nächsten Audit auffindbar. Sauberer wäre allerdings, wenn Synology den Verbindungstest nicht als Base64-verpackte Kommandozeile abfeuern würde. Ein Skript als signierte Datei auf der Platte löst die Signatur gar nicht erst aus – und sieht nebenbei auch weniger nach Lösegeldforderung aus."

Kaum möglich, das Problem zu melden

Melden lässt sich der Fehlalarm laut Leser übrigens nur umständlich: Es gibt keine Datei zum Einreichen bei Microsoft. Und eine Datei mit exakt dieser oben aufgeführten bzw. bemängelten Kommandozeile wird bei einem Suchlauf nicht beanstandet. Der Leser hat dies ausprobiert.

Microsoft sieht für solche Fälle die Route "Submit a fileless detection for analysis" mit dem Diagnosepaket MpSupportFiles.cab vor, schrieb Stefan. Dokumentiert ist das durchaus, allerdings an einer Stelle, die man ebenfalls nur findet, wenn man schon weiß, dass es sie gibt. Der Leser vermutet, dass die meisten Betroffenen den Fund wegklicken und ihn nie an Microsoft melden.

Noch einige Informationen

Der Blog-Leser hat mir das dekodierte Skript als Textdatei samt Analyse der Nutzlast zukommen lassen. Hier der betreffende Quellcode des Scripts:

# ============================================================================
# Synology Active Backup for Business - interner Verbindungstest
# Dekodierter Klartext des von Windows Defender als
#
#     Trojan:Win32/Commando.A!ml
#
# gemeldeten Befehls. Fund vom 02.08.2026, 07:20 Uhr, auf einem
# Windows-Server mit Hyper-V. Defender im Auslieferungszustand
# (keine Haertung, keine erhoehte Cloud-Blockstufe).
#
# Original-Aufruf laut Defender-Schutzverlauf:
#     C:\Windows\System32\cmd.exe /C powershell -encodedcommand 
#
# Dekodiert mit:  base64 -d | iconv -f UTF-16LE
# Der Code wurde zur Analyse NICHT ausgefuehrt, nur dekodiert.
#
# ANONYMISIERT: Es handelt sich um eine Kundenumgebung. Die NAS-Adresse
# und das Shared Secret wurden durch  bzw.  ersetzt.
# Alles Uebrige ist unveraendert.
# ============================================================================

$ErrorActionPreference = "Stop"
Try {
$(try{
$ip = ''
$port = 5510
$secret = ''
$b64 = "QhAABmFjdGlvbhAAD3Rlc3RfY29ubmVjdGlvbkA="
$data = [System.Convert]::FromBase64String($b64)
$client = New-Object System.Net.Sockets.TcpClient
$client.ReceiveTimeout = 30000
$client.Connect($ip, $port)
if (-not $client.Connected) {
raise "fail"
}
$stream = $client.GetStream()
$stream.Write($data, 0, $data.Length)
$buffer = New-Object byte[] 128
$bytesRead = $stream.Read($buffer, 0, $buffer.Length)
$response = $buffer[0..($bytesRead-1)]
if ([System.Text.Encoding]::ASCII.GetString($response) -eq $secret) {
@{Connected = $true}
} else {
raise "fail"
}
} Catch {
@{Connected = $false}
})| ConvertTo-Json -Depth 10
} Catch {
$host.ui.WriteErrorLine(($_ | Select CategoryInfo,FullyQualifiedErrorId,@{N="Exception";E={,@($_.Exception | Select Message)}} |ConvertTo-Json))
exit 1
}

# ============================================================================
# ANALYSE
# ============================================================================
#
# 1) DER INNERE BASE64-PAYLOAD
#
#    QhAABmFjdGlvbhAAD3Rlc3RfY29ubmVjdGlvbkA=
#
#    HEX  : 42 10 00 06 61 63 74 69 6f 6e 10 00 0f 74 65 73 74 5f 63 6f 6e
#           6e 65 63 74 69 6f 6e 40
#    ASCII: B...action...test_connection@
#    Laenge: 29 Byte
#
#    Struktur (schlichtes TLV-Format, Type-Length-Value):
#      0x42 'B'      = Start-Marker
#      0x10 0x0006   = Typ String, Laenge 6   -> "action"
#      0x10 0x000F   = Typ String, Laenge 15  -> "test_connection"
#      0x40 '@'      = End-Marker
#
#    Im Klartext also:   { action: "test_connection" }
#
#
# 2) WAS DAS SKRIPT TUT
#
#    - baut eine TCP-Verbindung zur NAS auf Port 5510 auf
#      (Kommunikationsport zwischen ABB-Agent und ABB-Server)
#    - sendet die 29 Byte oben
#    - vergleicht die Antwort mit einem Shared Secret
#    - gibt {"Connected": true} bzw. false als JSON zurueck
#
#    NICHT enthalten: Nachladen von Code, Invoke-Expression, Persistenz,
#    Datei- oder Registry-Zugriffe, Verschluesselung, Exfiltration.
#    Ziel ist eine private RFC1918-Adresse im selben LAN.
#
#
# 3) WARUM DER DEFENDER TROTZDEM ANSCHLAEGT
#
#    Vier Merkmale eines C2-Beacons treffen zusammen:
#      a) cmd.exe /C powershell -encodedcommand  (Base64-verschleierter Befehl)
#      b) roher Socket ueber System.Net.Sockets.TcpClient statt HTTP
#      c) fest hinterlegtes Shared Secret zur Pruefung der Antwort
#      d) weiterer Base64-Blob, zur Laufzeit dekodiert und verschickt
#
#    Das Suffix !ml kennzeichnet einen Machine-Learning-Treffer,
#    keinen Signaturtreffer.
#
#
# 4) NEBENBEFUND
#
#    'raise "fail"' ist kein gueltiges PowerShell, sondern Python-Syntax.
#    In PowerShell laeuft es ins Leere und wird vom umgebenden Catch
#    eingefangen - der Fehlerpfad funktioniert eher zufaellig.
#    Deutet auf maschinell erzeugten Klebe-Code hin.
#
#
# 5) LOESUNG
#
#    a) Defender -> Schutzverlauf -> Fund aufklappen -> "Zulassen"
#    b) Auf dem Windows-Host den Dienst neu starten:
#         Restart-Service "Synology Active Backup for Business Service"
#
#    Ohne Schritt b) bleibt es beim fehlgeschlagenen Backup: Der Dienst hat
#    den abgeschossenen Verbindungstest als "NAS nicht erreichbar" verbucht
#    und verharrt in diesem Zustand.
# ============================================================================

Es handelt sich um Kundenumgebungen, deshalb sind NAS-Adresse und Shared Secret in obigem Code ersetzt. Alles Übrige ist im Original. Danke an den Leser – und die Frage an Mitleser: Noch jemand davon betroffen?

Dieser Beitrag wurde unter Problemlösung, Virenschutz, Windows abgelegt und mit , , , verschlagwortet. Setze ein Lesezeichen für den Permalink.

Ein Kommentar zu Microsoft Defender hält Synology-Backups für einen Trojaner (3.8.2026)

  1. Hobbycoder sagt:

    Wie umständlich und verdächtig verpackt will man einen Verbindungstest programmieren? Oh Synology, was für ein Frickelcode…

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Hinweis: Bitte beachtet die Regeln zum Kommentieren im Blog (Erstkommentare und Verlinktes landet in der Moderation, gebe ich alle paar Stunden frei, SEO-Posts/SPAM lösche ich rigoros. Kommentare abseits des Themas bitte unter Diskussion. Kommentare, die gegen die Regeln verstoßen, werden rigoros gelöscht. Wegen Missbrauchs bin ich gezwungen, Name und E-Mail als Pflichtfelder beim Kommentieren zu aktivieren. Wählt ggf. einen (noch nicht benutzten) Alias-Namen und verwendet ggf. eine Dummy-Mail-Adresse (z.B. t@hotkev.com).

Du findest den Blog gut, hast aber Werbung geblockt? Du kannst diesen Blog auch durch eine Spende unterstützen.