Evooo1Bot zerlegt

Als Fortinet Evooo1Bot beschrieb, las sich die Featureliste wie ein ziemlich komplettes Linux-Angriffsframework: Ein beobachtetes Loader-Skript lieferte zwölf Architekturvarianten aus; hinzu kamen 28 Kommandos, SSH-Scanning, SOCKS5, Reverse Relay, Credential-Sniffer, Persistenz, 16 Flood-Methoden und 26 Exploit-Records.

Die Liste stimmt. Sie erzählt nur nicht, wie gut die einzelnen Teile funktionieren. Genau das wollten wir wissen. Deshalb haben wir zwei ELF-Builds statisch zerlegt: ein offline aus einem MIPS-Wrapper dekodiertes MIPS-ELF und einen Renesas-SH4-Build.

Der wichtigste Befund steht nicht bei den Floods oder CVEs. Evooo1Bot meldet ein gültiges SSH-Passwort, bevor der Bot überhaupt versucht, eine Payload nachzuladen. Der Credential-Diebstahl kann also erfolgreich sein, obwohl die anschließende Infektion scheitert. Der Rest des Codes passt zu diesem Bild: einige brauchbare Werkzeuge, einige grobe Abkürzungen und eine Exploit-Sammlung, die deutlich größer aussieht, als sie technisch ist.

Das passt zu der bereits beschriebenen Kombination aus alter Security und schnellen Angreifern: Der Angreifer muss nicht elegant sein, wenn irgendwo weiterhin root:123456 akzeptiert wird.

Was wir tatsächlich untersucht haben

Die drei relevanten Artefakte lassen sich über ihre Hashes eindeutig zuordnen:

  • MIPS-Wrapper, SHA-256 f13cb360768363d3424e2192c7805b8c8015eb8706dbbbcdead6aed8cf390109
  • daraus ausschließlich offline dekodiertes inneres MIPS-ELF, SHA-256 c72b1e6be5ac42894d5cbc3695eccb03bfabaf7c517098034efdc427114ea9c9
  • Renesas-SH4-ELF, SHA-256 4c0886349e9d348569fffe1b7a31e474d514508bf0cd6f1e5dd99c2a73525e4d

Wir haben nichts ausgeführt oder emuliert und keine Verbindung zu C2- oder Loader-Infrastruktur aufgebaut. Es gab auch keine Credential-Tests und keine Exploitversuche. Die Analyse zeigt, welche Pfade im Code vorhanden und erreichbar sind. Über reale Opferzahlen, Erfolgsraten oder die Stabilität im Betrieb sagt sie nichts.

Trotz der unterschiedlichen Architekturen stimmen die Builds in den malware-spezifischen Teilen ungewöhnlich eng überein:

  • 28 von 28 erreichbaren Command-Dispatches
  • 16 von 16 Flood-Methoden in derselben Reihenfolge
  • 26 von 26 CVE-Records mit jeweils acht identischen Feldern
  • 15 von 15 Honeypot-Indikatoren
  • 188 von 188 gespeicherten SSH-Credential-Records in derselben Reihenfolge, davon 181 eindeutige Paare
  • dieselben Persistenzwerte, dieselbe SSH-Taskgrammatik, dasselbe Scanner-Reporting und dieselben Relay-Protokollmarker

Das geht weit über ein paar gemeinsame Strings hinaus. MIPS und SH4 stammen mit hoher Wahrscheinlichkeit aus derselben oder einer unmittelbar benachbarten Source- und Konfigurationslinie. Autorenschaft oder Kampagnenidentität folgen daraus nicht. Der gemeinsame Codekern ist aber klar erkennbar.

Der erreichbare Kommandosatz lautet:

!persist !reinstall !kill !exit !info !download !upload
!shell !exec !stream !detach !bg
!sniff !stopsniff
!socks !socksauth !stopsocks
!ssh !stopssh !enableautossh !disableautossh
!attack !stopattack
!cve !stopcve !cveall
!http !stophttp

Evooo1Bot ist damit kein reines Router-Botnet. Der Bot bringt eine PTY-Shell, Dateiübertragung, Linux-Persistenz, Credential-Erfassung, Proxy- und Relay-Funktionen sowie Angriffslogik für IoT-Geräte, Appliances und Server mit.

Das Passwort kommt vor der Payload

Nach erfolgreicher SSH-Authentisierung folgt optional eine Post-Auth-Prüfung. Akzeptiert sie das Ziel – oder wurde sie mit NOHPCHECK:1 abgeschaltet –, erzeugt der Scanner sofort einen Credential-Record. Erst danach prüft der Code, ob überhaupt eine Payload eingereicht werden soll.

Im Code läuft es in dieser Reihenfolge:

SSH-Login erfolgreich
→ Honeypot-/Plausibilitätsprüfung
→ Credential-Record erzeugen
→ Payloadmodus prüfen
→ optional Loaderkommando einreichen

Der Typ-1-Record enthält Ziel-IPv4, Username und Passwort. Über eine interne Queue gelangt er in einer Base64-kodierten SR:-Zeile vom Scanner-Kindprozess zum Parent. Der Parent liest diesen Stream in Blöcken von höchstens 511 Byte; dabei können SR:-Zeilen fragmentiert oder zusammengefasst werden. Jeder ausgehende Klartextblock erhält einen auf 16 Byte gekürzten HMAC-SHA256-Tag und wird anschließend vollständig mit ChaCha20 verschlüsselt.

Eine persistente Queue, Record-IDs, Acknowledgements oder Replaylogik gibt es nicht. Bei Pipe- oder C2-Fehlern können Treffer verloren gehen. Der entscheidende Punkt bleibt trotzdem:

Evooo1Bot ist Credential-Sammler und Infektionsautomat. Ein gültiges Paar wird gemeldet, selbst wenn die nachfolgende Infektion nie stattfindet.

Die Statusmeldungen sind entsprechend eng zu lesen:

  • Typ 1: gültiges Credential nach akzeptierter Zielprüfung
  • Typ 2: Loaderkommando wurde lokal zur SSH-Submission angenommen
  • Typ 3: lokale Submission ist fehlgeschlagen
  • Typ 5: Scannerabschluss und Zähler

Typ 2 bedeutet ausdrücklich nicht, dass eine Datei heruntergeladen, als ELF erkannt, ausgeführt oder nachher entfernt wurde.

Der SSH-Scanner in der Praxis

Im Binary liegen 188 Username-/Passwort-Records, davon 181 eindeutige Paare. Der automatische Scanner benutzt aber nur die ersten 145. Ein Längengate lässt die Ordinals 0 bis 144 in den Taskbuffer und verwirft den Rest. Aus 188 gespeicherten Credentials werden bei diesen Builds also nicht 188 automatische Loginversuche pro Ziel.

Die 145 tatsächlich verwendeten Paare sind ein grober Katalog aus Defaults und naheliegenden Varianten:

  • 51 Einträge verwenden den Benutzernamen root
  • 33 Einträge verwenden admin
  • 21 Paare setzen Benutzername und Passwort gleich
  • 26 Passwörter bestehen nur aus Ziffern
  • bei 47 Paaren steckt der Benutzername im Passwort
  • alle 145 automatisch verwendeten Paare sind eindeutig

Der Anfang der Liste ist ungefähr so subtil, wie man es erwartet:

root:123456
root:password
root:admin
root:root
root:toor
root:alpine
root:changeme
root:raspberry
admin:admin
admin:password
admin:123456
admin:admin123
ubuntu:ubuntu
pi:raspberry
oracle:oracle
postgres:postgres
mysql:mysql
jenkins:jenkins
deploy:deploy
ubnt:ubnt

Hinzu kommen Varianten wie Passw@rd, P@ssw0rd, qwerty123, root123, admin@123, numerische Folgen und dienstbezogene Kombinationen. Das ist kein klassisches Password Spraying, sondern sequenzielles Credential Guessing mit einem fest eingebauten Dictionary. Es ist die automatisierte Hoffnung, dass irgendwo noch ein Herstellerdefault, ein Testsystem oder ein Administrator mit sehr überschaubarer Fantasie am Netz hängt.

Hinter der Puffergrenze liegen weitere Werte für Appliances und Kameras sowie Jahresvarianten wie admin2023, admin2024, root2023 und root2024. Der Bot trägt sie mit sich herum, erreicht sie im automatischen Modus aber nicht. Ein String im Binary ist noch keine ausgeführte Funktion.

Zielauswahl und Authentisierung

Ein automatischer Batch enthält 100 zufällig erzeugte IPv4-Ziele. Gefiltert wird nur das erste Oktett:

  • ausgeschlossen: 10/8, 127/8, das gesamte 192/8 und 224 bis 255
  • nicht generell ausgeschlossen: 0/8, 100.64/10, 169.254/16, 172.16/12, Dokumentations- und Benchmarknetze sowie eigene oder lokale Adressen

Die Filterung ist grob und teilweise missraten. Statt 192.168/16 wird gleich das gesamte 192/8 verworfen, während 172.16/12 und andere ungeeignete Bereiche erhalten bleiben.

Die Zufallsbytes kommen normalerweise aus /dev/urandom. Scheitert das, fällt der Bot auf time(NULL) XOR getpid() zurück – und reseedet bei jedem Fill erneut. In diesem Fehlerpfad können stark korrelierte Adressen bis hin zu x.x.x.x-artigen Mustern entstehen. Im Normalfall liefert der Kernel die Entropie. Auf kaputten oder stark eingeschränkten Geräten wird die Zielwahl schnell ziemlich dumm.

Der Scanner arbeitet Ziele und Credentials sequenziell in einem einzelnen Scanner-Kindprozess ab. Es gibt keinen festen Pool paralleler Target-Worker. Pro Verbindung gelten fünf Sekunden Send- und Receive-Timeout, aber kein universelles Fünf-Sekunden-Limit für den vollständigen Handshake. Innerhalb der Target-/Credential-Schleife gibt es keine Pause und keine Gewichtung.

Die Authentisierung versucht zunächst SSH-Passwortauthentisierung. Bietet der Server nach einem Fehlschlag keyboard-interactive an, wird dasselbe Paar darüber erneut versucht. Public-Key-Authentisierung spielt in diesem Pfad keine Rolle.

Die theoretische Obergrenze eines automatischen Tasks liegt damit bei 100 mal 145, also 14.500 Paarselektionen. Das ist keine beobachtete Versuchszahl: Verbindungsfehler, Disconnects, MaxAuthTries, Sperren und frühe Treffer reduzieren sie erheblich.

Manuell geht deutlich mehr

Über !ssh kann der Operator vollständigen Tasktext liefern:

<targets>
---
<username:password>
===
<payload/control text>

Der Parser akzeptiert bis zu 10.000 explizite Ziele und 500 Credential-Paare. Diese Ziele durchlaufen die automatische IP-Filterung nicht. Zusätzlich kennt der Task unter anderem:

MODE:
CLEAN:1
NOHPCHECK:1

NOHPCHECK:1 ist ein operatorseitiger Override. Er überspringt sowohl den Pre-Auth-Bannerfilter als auch die Post-Auth-Honeypotprüfung. Automatische Tasks enthalten ihn nicht. Bei manuellen Tasks kann der Operator beide Kontrollen bewusst abschalten.

Der Loader kennt die Zielarchitektur nicht

Der automatische Text nach === stammt aus einem lokal entschlüsselten Konfigurationsfeld. Im geschlossenen SSH-Loaderpfad gibt es:

  • keine lokale Zielarchitekturwahl
  • keine Architektur-Suffixe
  • keine Hash- oder Signaturprüfung
  • keine Größenprüfung
  • keine ELF-Magic- oder Endianness-Prüfung
  • keinen unabhängigen Marker für Download oder Payloadstart

Nach akzeptiertem Login kann Text vor der ersten http-Fundstelle als Shellkommando eingereicht werden. Danach baut der Bot eine Kette über mehrere Verzeichnisse:

/tmp
/var/run
/dev/shm
/root
/

Je Verzeichnis versucht er Download per wget, andernfalls curl, andernfalls TFTP, schreibt nach .d, setzt das Execute-Bit, startet die Datei, löscht Shell-History und entfernt .d bei gesetztem CLEAN:1. Die Versuche werden mit || verbunden.

Die Kette ist flexibel, aber sie trifft lokal keine Architekturentscheidung. Eine serverseitige Auswahl hinter der URL wäre möglich, ist im Botcode jedoch nicht belegt. Wenn dieselbe Payload blind auf MIPS, SH4, ARM oder x86 trifft, ist ein akzeptiertes SSH-Kommando noch lange keine erfolgreiche Infektion.

Honeypots: zweimal prüfen, auf Wunsch wegsehen

Vor der Authentisierung vergleicht Evooo1Bot das SSH-Banner mit 15 Indikatoren, darunter Cowrie, Kippo, HonSSH, OpenCanary, Twisted, Paramiko/libssh-Formen und weitere typische Banner. Ein einzelner Substring reicht zur Ablehnung.

Nach erfolgreichem Login folgt ohne Override ein zweiter Validator:

  1. uname -a muss plausibel nach Linux aussehen und darf keine offensichtlichen Cowrie-/Kippo-Marker enthalten.
  2. /proc/version, /proc/1/cmdline und typische Cowrie-/Kippo-Pfade werden geprüft.
  3. Ein BusyBox-Fallback erwartet eine bestimmte applet not found-Antwort.

Das ist keine allgemeine Sandbox- oder Debuggererkennung auf dem infizierten Host. Geprüft wird das per SSH erreichte Zielsystem. Mit NOHPCHECK:1 kann der Operator beide Stufen abschalten.

Die öffentlich beschriebene große Startup-Blacklist mit 68 Debugger-, VM-, Container- und Analysewerkzeugnamen wurde in beiden Builds unter vollständiger Plaintext- und XOR-0x43-Suche nicht gefunden. Belegt sind stattdessen normale Host-Discovery, Prozess- und Socketprüfung, OOM- und Watchdoglogik sowie die getrennten SSH-Honeypotgates.

Was nach einem Zugang möglich ist

Hat der Bot erst einmal Zugriff, wird der Code an einigen Stellen deutlich vollständiger. Sniffer, Proxy und Persistenz sind nicht gleich gut gebaut, aber sie sind mehr als Dekoration in der Stringtabelle.

Ein echter Sniffer, aber kein HTTPS-Zauberstab

Der MIPS-Build öffnet einen Raw Socket:

socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))

Das Modul liest Ethernet, IPv4 und TCP und interessiert sich für die Ports 80, 8080, 8443 und 8888. Es erkennt unter anderem GET, POST, PUT und HEAD sowie Basic Authorization, Cookies, URLs und POST-Felder.

Der Parser hat enge Grenzen:

  • keine TCP-Stream-Reassembly belegt
  • Verarbeitung paketlokaler Nutzdaten
  • keine TLS-Entschlüsselung
  • keine explizite Interfacebindung
  • typischerweise Root oder CAP_NET_RAW erforderlich
  • keine Logrotation oder Größenbegrenzung

Port 8443 in einer Filterliste entschlüsselt kein TLS. Was hier im Code steckt, ist kein „HTTPS-Credential-Stealer“, sondern ein Packet-Sniffer mit einem begrenzten, paketlokalen Klartext-HTTP-Parser.

Treffer landen standardmäßig in /tmp/.sniff.log, im Append-Modus und ohne Rotation. Counter und Treffer gehen zusätzlich auf eine Kind→Parent-Pipe. Ein geschlossener automatischer Pipe→C2-Abtransport wurde in den untersuchten Pfaden nicht gefunden. Der allgemeine !download-Befehl könnte die Logdatei natürlich separat abrufen.

SOCKS5 und Reverse Relay

Der direkte SOCKS5-Modus unterstützt:

  • wahlweise No-Auth oder, nach !socksauth, Username/Passwort-Authentisierung
  • CONNECT
  • IPv4
  • Domainnamen
  • IPv6
  • einen konfigurierbaren Port mit 1080 als Default beziehungsweise Fallback

Private und interne Zieladressen werden nicht gesperrt. Jeder Client läuft in einem eigenen Worker.

Das Reverse Relay trennt Steuerung und Daten:

Control-Verbindung
→ RELAY_AUTH
→ RELAY_OK
→ RELAY_NEW für eine Session
→ separate RELAY_DATA-TCP-Verbindung
→ SOCKS5 über den Datenkanal

Der Controlkanal signalisiert neue Sessions; jede Session erhält einen eigenen TCP-Datenkanal. Relay läuft nicht im Haupt-C2-Socket. Eine zusätzliche HMAC-/ChaCha-Schicht für den Relay-Traffic wurde nicht belegt.

Die Proxy- und Pivot-Funktionen bestehen damit nicht nur aus ein paar verdächtigen Strings. Die State-Machine ist in sich schlüssig. Durchsatz und Stabilität bleiben ohne dynamischen Test offen.

Persistenz mit der Schrotflinte

Bei der Persistenz probiert Evooo1Bot mehrere Wege nacheinander:

systemd
→ nur bei Fehler zusätzlich Cron
danach unabhängig davon profile.d
→ SysV-Skript
→ Eigenkopie
→ SysV-Aktivierung

profile.d, Eigenkopie und SysV-Pfade besitzen UID-0-Guards. Der Cronpfad hat keinen globalen Root-Guard und kann abhängig von der Umgebung auch als Benutzerpersistenz funktionieren.

Die Schreiblogik arbeitet überwiegend mit Replace, Truncate oder cp -f. Es gibt kein Backup, keinen atomaren Swap und kein globales Rollback. Ein teilweise gescheiterter Lauf kann Unit-Datei, Cronzeile, profile.d-Datei, Init-Skript oder Botkopie als Residuum hinterlassen.

Diese Schichtung ist vom Kommando !persist zu trennen: Es führt in einen separaten LD_PRELOAD-Rootkit-Zweig. !reinstall bildet wiederum einen eigenen argumentbasierten Download-/Replace-/Exit-Pfad. Der genaue Wartungs- beziehungsweise Self-Healing-Trigger bleibt offen.

Auch hier weichen die untersuchten Builds konkret vom öffentlichen Bericht ab:

  • Description=System Service Manager statt Description=Apache HTTPD Cache Manager
  • Restart=on-failure statt Restart=always
  • * * * * * statt */5 * * * *
  • /etc/rc.local wurde nicht gefunden

Wahrscheinlich sind das Versions- oder Konfigurationsunterschiede. Genau deshalb darf eine Familienbeschreibung nicht ungeprüft auf jedes Sample übertragen werden.

C2-Kryptografie: AES sitzt an anderer Stelle

Beide Builds enthalten erreichbare AES-Routinen. Eine AES-256/CTR-artige Funktion gehört zur Vorverarbeitung automatischer SSH-Tasks. Eine zweite AES-Familie ist dem gebündelten SSH-Stack zuzuordnen.

Im statisch rekonstruierten ausgehenden Custom-C2-Datenpfad wurde dagegen keine AES-Kante gefunden. Dieser Pfad verwendet HMAC-SHA256 und ChaCha20. Die pauschale Beschreibung „AES, dann ChaCha“ passt für diese beiden Builds nicht zum rekonstruierten ausgehenden Datenpfad.

Port 443 bedeutet ebenfalls nicht HTTPS. Die Marker REGISTER:, AUTH_CHALLENGE:, c2s, s2c und hmacs2c gehören zu einem eigenen authentisierten und verschlüsselten Protokoll. Der vollständige Handshake, Nonces, Counter und Replay-Eigenschaften sind noch nicht komplett rekonstruiert.

26 CVEs sind noch keine Exploitbibliothek

Der Dispatcher enthält 26 strukturierte Records. Jeder Record besitzt unter anderem CVE-ID, Port, URI, HTTP-Methode, Content-Type, Body, erwarteten Response-Substring und Timeout. Beide Builds enthalten dieselben 26 normalisierten Acht-Feld-Records in derselben Reihenfolge. Die Feldinhalte stimmen vollständig überein.

Die Tabelle ist ordentlich. Der gemeinsame HTTP-Helper ist es weniger:

  • spricht kein TLS, auch nicht auf Port 443
  • setzt keine Auth-, Cookie-, CSRF- oder Bearer-Header
  • führt keine belastbare Produkt- oder Versionsprüfung durch
  • wertet Erfolg nur über einen Response-Substring aus
  • bestätigt weder Payloaddownload noch Codeausführung

Vier Records zeigen, wo die Probleme liegen:

CVE-2021-36260

Die Route /SDK/webLanguage und das Command-Injection-Muster sind grundsätzlich plausibel. Es fehlen jedoch Modell-, Firmware-, Authentisierungs- und Endpointprüfungen. Der Body fordert keinen Reboot an; der erwartete Response-Substring reboot ist deshalb kein belastbarer und nicht einmal unmittelbar zum Payload passender Ausführungsnachweis.

CVE-2022-30525

Der Record sendet Klartext auf Port 443. Im JSON steckt außerdem eine verdächtige Kommandoform mit führendem Komma und URL-kodierten Leerzeichen, ohne dass ein passender zusätzlicher Decode-Schritt belegt wäre. Das Template ist wahrscheinlich fehlerhaft.

CVE-2025-1974

Der Record versucht ein Ingress-Objekt per POST auf einem Kubernetes-API-artigen Pfad. Es fehlen TLS, Bearer-Token oder Clientzertifikat, Namespace, API- und Versionsprüfung sowie weitere Voraussetzungen der eigentlichen Angriffskette. Ein HTTP-Status 201 würde lediglich die Annahme eines Objekts anzeigen, nicht dessen Ausführung.

CVE-2023-34362

Der Record behandelt /human2.aspx wie einen Erstendpunkt. In der bekannten MOVEit-Kette ist diese Ressource jedoch eine nachgelagerte Webshell. Upload-/Erststufe, Session, Authentisierung und Existenzprüfung fehlen. Das ist ein ID-, Template- und Stufenmismatch.

Evooo1Bot besitzt eine Sammlung unterschiedlich guter Requesttemplates, keine statisch verifizierte Exploitbibliothek.

Aus dem Kubernetes-Record wird auch keine größere Cloudgeschichte. Gefunden wurden keine Service-Account-Tokens, keine Bearer-Nutzung, keine Cloud-Metadaten, keine Docker- oder containerd-Sockets, kein Clusterpivot und kein Container Escape. Das Ingress-Template zielt lediglich auf einen generischen /init.sh-Loader. Es implementiert oder bestätigt weder die vollständige Angriffskette noch Codeausführung, Botinstallation, Clusterpivot oder Container Escape.

Was Verteidiger daraus mitnehmen sollten

SSH

  • Passwortauthentisierung auf exponierten Systemen abschalten, wenn sie nicht zwingend benötigt wird.
  • direkten Root-Login verbieten.
  • Hersteller- und Service-Defaults konsequent entfernen.
  • servicebezogene Konten wie jenkins, deploy, postgres, oracle, nagios oder ubnt nicht mit gleichnamigen oder trivial abgeleiteten Passwörtern betreiben.
  • fehlgeschlagene Sequenzen gegen root und admin sowie Wechsel von Passwort zu Keyboard-Interactive korrelieren.
  • Rate-Limits, Fail2ban-ähnliche Kontrollen und Netzwerk-Allowlisting nicht als Ersatz für starke Authentisierung behandeln, aber sinnvoll einsetzen.

Host-Telemetrie

  • unbekannte Prozesse mit AF_PACKET/SOCK_RAW beziehungsweise CAP_NET_RAW überwachen.
  • /tmp/.sniff.log, versteckte .d-Downloads und Ausführung aus /tmp, /var/run oder /dev/shm erkennen.
  • Änderungen an /etc/profile.d/, /etc/init.d/, Cronspools und verdächtigen systemd-Units korrelieren.
  • Änderungen an /proc/self/oom_score_adj und Zugriffe auf /dev/watchdog im Kontext unbekannter Prozesse prüfen.
  • Listener auf 0.0.0.0:1080 und unerwartete SOCKS5-Negotiation nicht ignorieren.

Netzwerk

  • ausgehende verschlüsselte Nicht-HTTPS-Verbindungen auf Port 443 anhand Protokollverhalten statt Portnummer klassifizieren.
  • neue Relay-Control- und per-Session-Datenverbindungen desselben Prozesses korrelieren.
  • ungewöhnliche SSH-Scans eines Linux-Geräts ernst nehmen, auch wenn das Gerät selbst nur als Appliance oder Router geführt wird.
  • ausgehende Verbindungen zu unbekannten Loaderzielen sowie generische wget-, curl- und TFTP-Downloads egress-seitig begrenzen.
  • Ausführung aus temporären Verzeichnissen durch Mount-Optionen, Application Control und Prozess-Telemetrie verhindern beziehungsweise erkennen.

Exploit-Telemetrie

  • betroffene Produkte patchen und ihre Managementoberflächen auf notwendige Quellnetze beschränken.
  • Requests auf /SDK/webLanguage, /ztp/cgi-bin/handler, Kubernetes-Ingress-API-Pfade und /human2.aspx korrelieren.
  • solche Treffer je nach Route als Scan-, Exploit- oder Follow-on-Versuch behandeln, nicht als automatischen Kompromittierungsbeweis.
  • mögliche Codeausführung separat über Prozess-, Datei- und Netzwerkspuren bestätigen; Responsewerte wie 200, 201, reboot oder Succeeded reichen dafür nicht.

Incident Response

Ein gültiger SSH-Login und eine gemeldete Infektion sind getrennte Ereignisse. Umgekehrt kann ein gescheiterter Payloaddownload bereits bedeuten, dass Credentials gestohlen wurden. Wer nur nach dem Botbinary oder einer erfolgreichen Persistenz sucht, kann den eigentlichen Schaden übersehen.

Bei einem bestätigten gültigen SSH-Login, einem Botfund oder anderweitiger Evidenz für erfolgreichen Zugriff gehören deshalb mindestens dazu:

  • Passwörter und SSH-Schlüssel der betroffenen Konten rotieren beziehungsweise widerrufen
  • Sessions und nachgelagerte Zugänge prüfen
  • erfolgreiche Authentisierungen zeitlich vor dem ersten Payloadartefakt untersuchen
  • Proxy-/Relay-Nutzung und interne Verbindungen prüfen
  • Cron, systemd, profile.d und SysV gemeinsam kontrollieren
  • /tmp/.sniff.log vor der Bereinigung forensisch sichern und auf HTTP-Basic-Credentials, Session-Cookies, URLs und Formularwerte prüfen
  • dadurch exponierte Passwörter rotieren und betroffene Websessions beziehungsweise Tokens widerrufen
  • temporäre Dateien und Shell-History nicht als zuverlässige Negativbelege behandeln

Breit gebaut, ungleich gut

Evooo1Bot ist mehr als ein weiteres Mirai-Etikett, aber weniger als das fertige Angriffsframework aus der Featureliste. Der Code trennt Credentialgewinn, Infektionsversuch, Proxying, Relay und C2. Damit könnte ein kompromittiertes Linux-System mehrere Rollen übernehmen. Beobachtet haben wir diese operative Nutzung nicht. Belegt ist nur, dass die Pfade im Code vorhanden sind.

Die Details nehmen der langen Featureliste einiges von ihrem Glanz. Der Scanner verwendet 145 statt 188 Credentials. Der Loader bestimmt die Zielarchitektur nicht. Der Sniffer sieht nur paketlokalen Klartext. AES liegt in SSH-bezogenen Pfaden, nicht im belegten Custom-C2-Ausgang. Die Persistenz hinterlässt bei Fehlern leicht Reste, und mehrere Exploittemplates sind unvollständig oder schlicht falsch.

Der brauchbare Befund ist deshalb unspektakulärer als die Featureliste: Ein String zeigt eine Idee. Ein erreichbarer Codepfad zeigt eine implementierte Fähigkeit. Ob sie fachlich stimmt und im Betrieb funktioniert, muss man trotzdem getrennt prüfen.

Quellen und öffentliche Artefakte

Die weitergehenden Aussagen dieses Beitrags stammen aus eigener statischer Analyse der beiden genannten Samples. Runtime-Erfolg, aktive Infrastruktur, Opferzahlen und Attribution wurden nicht untersucht beziehungsweise nicht aus der statischen Evidenz abgeleitet.