Anfang März 2019 wurde ein neues macOS-Malware-Sample der OceanLotus-Gruppe bei VirusTotal – einem beliebten Online-Multi-Scanner-Service – hochgeladen. Die Backdoor wartet mit denselben Funktionen auf, wie die von uns bereits zu einem früheren Zeitpunkt betrachtete macOS-Variante. Allerdings hat sich die Architektur der Malware etwas verändert und die Tarnung ist verbessert worden. Ohne passenden Dropper zum Malware-Sample, können wir nicht sagen, wie eine initiale Kompromittierung zustande kommt.

Erst vor kurzem veröffentlichten wir detaillierte Updates über OceanLotus. Darin beschreiben wir, wie die Malware-Entwickler auf eine Vielzahl von Techniken zugreifen, um Schadcode auszuführen, Persistenz zu erreichen oder auf Windows-Betriebssystemen so wenig Spuren wie möglich zu hinterlassen. OceanLotus verfügt aber auch über bösartige macOS-Bausteine.

Dieser Beitrag erläutert die Unterschiede zum Malware-Sample, welches vor einiger Zeit von Trend Micro analysiert wurde. Außerdem wird beschrieben, wie man während der Analyse des Codes, die String-Entschlüsselung mithilfe der IDA Hex-Rays-API automatisieren kann.

Analyse der neuen OceanLotus macOS Malware-Variante

In den folgenden drei Abschnitten des Beitrags bezieht sich die Analyse auf das Malware-Sample mit dem SHA-1-Hash: E615632C9998E4D3E5ACD8851864ED09B02C77D2. Die Datei trägt den Namen flashlightd und wird von ESET-Produkten als OSX/OceanLotus.D erkannt.

Anti-Debug und Anti-Sandbox

Wie üblich, ist das macOS Malware-Sample mit Hilfe von UPX gepackt – allerdings erkennen es die meisten „Packer-Erkennungs-Tools“ nicht als solches. Wahrscheinlich, weil sie meistens eine Signatur enthalten, die auf dem Vorhandensein einer „UPX“-String beruht. Außerdem sind Mach-O-Signaturen weniger verbreitet und werden nicht so regelmäßig aktualisiert. Diese besondere Eigenschaft erschwert die statische Erkennung. Nach dem Entpacken offenbart sich der Einstiegspunkt, der sich am Anfang der __cfstring-Section des .TEXT-Segments befindet. Dieser Abschnitt enthält die in Abbildung 1 gezeigten Flag-Attribute.

Abbildung 1: MACH-O __cfstring Section-Attribute

Abbildung 1: MACH-O __cfstring Section-Attribute

Wie in Abbildung 2 zu sehen, trickst der Code in der __cfstring-Section einige Disassembly-Tools durch Tarnung als Zeichenkette aus.

Abbildung 2: Der Backdoor-Code wird von der IDA als Daten interpretiert.

Abbildung 2: Der Backdoor-Code wird von der IDA als Daten interpretiert.

Bei der Ausführung erstellt die Binärdatei zunächst einen Thread als Anti-Debugging-Funktionsüberwacher. Dessen einziger Zweck besteht darin, das System fortlaufend auf einen Debugger hin zu überprüfen. Dazu muss der Thread in der Lage sein:

  • den Debugger abzukapseln, in dem ptrace mit Hilfe von PT_DENY_ATTACH als Request Parameter aufgerufen wird.
  • zu überprüfen, ob Ausnahmeports geöffnet sind. Dazu wird die Funktion task_get_exception_ports
  • zu überprüfen, ob ein Debugger anhängt. Das ist der Fall, wenn ein P_TRACED Marker im aktuellen Prozess gesetzt ist, wie in Abbildung 3 zu sehen.

Abbildung 3: Überprüfung, ob ein Debugger über die sysctl-Funktion angehangen ist.

Abbildung 3: Überprüfung, ob ein Debugger über die sysctl-Funktion angehangen ist.

Bemerkt der Funktionswächter einen Debugger, ruft er die exit-Funktion auf. Außerdem überprüft die Malware die Umgebung, indem sie zwei Befehle ausführt:
ioreg -l | grep -e “Manufacturer” und sysctl hw.model. Der Rückgabewert wird mit einer hardcodierten Liste bekannter Strings der VMs Oracle, VMware, Virtualbox und anderen abgeglichen. Schließlich checkt system_profiler SPHardwareDataType 2>/dev/null | awk ‘/Boot ROM Version/ {split($0, line, “:”);printf(“%s”, line[2]);} um welches Apple-Produkt es sich handelt – beispielsweise “MBP”, “MBA”, “MB”, “MM”, “IM”, “MP” und “XS”. Das Akronym “MBP” steht für MacBook Pro, “MBA”für MacBook Air usw.

Updates gegenüber des alten OceanLotus Samples

Selbst wenn sich die Backdoor-Befehle seit der Erscheinung des Trend Micro Artikels nicht geändert haben, beobachteten wir ein paar andere Modifikationen. Die für dieses Malware-Sample verwendeten C&C-Server sind relativ neu, da sie erst Ende Oktober 2018 aufgesetzt wurden.

  • faybilodeau[.]com
  • onteagleroad[.]com
  • charlineopkesston[.]com

Die verwendete URL-Ressource hat sich geändert in: /dp/B074WC4NHW/ref=gbps_img_m-9_62c3_750e6b35.

Das erste Paket, das an den C&C-Server gesendet wird, enthält weitere Informationen zum Host-Computer. Die Informationen beinhalten alle Daten, die durch die folgenden Befehle bezogen werden:

Commands Description
    system_profiler SPHardwareDataType 2>/dev/null

  • awk '/Processor / {split($0,line,":"); printf("%s",line[2]);}'
  • machdep.cpu.brand_string

Gather processor information
    system_profiler SPHardwareDataType 2>/dev/null

  • awk '/Memory/ {split($0,line, ":"); printf("%s", line[2]);}'
Gather memory information
ifconfig -l Gather network interface MAC addresses
    ioreg -rd1 -c IOPlatformExpertDevice

  • awk '/IOPlatformSerialNumber/ { split($0, line, "\""); printf("%s", line[4]); }'
Retrieves the serial number of the device

Zu dieser Konfigurationsänderung kommt hinzu, dass unser analysiertes Sample nicht die libcurl-Bibliothek für die Network-Exfiltration benutzt. Stattdessen ziehen die Malware-Entwickler hierfür eine externe Bibliothek heran. Um diese zu finden, versucht die Backdoor jede im aktuellen Ordner befindliche Datei mit Hilfe von AES-256-CBC zu entschlüsseln. Der Schlüssel gFjMXBgyXWULmVVVzyxy wird am Ende mit Nullen aufgefüllt.

Jede Datei wird „entschlüsselt“ und als /tmp/store abgespeichert. Es wird versucht, sie mit der dlopen-Funktion als Bibliothek zu laden. Folgt einem Entschlüsselungsversuch ein erfolgreicher Aufruf dlopen, ruft die Backdoor die exporten Funktionen Boriry und ChadylonV auf, welche für die Server-Netzwerkkommunikation verantwortlich zu sein scheinen.

Da uns weder die Dropper-Datei noch andere Dateien vom Ursprung des Samples vorliegen, konnten wir die Bibliothek nicht analysieren. Außerdem ist die Komponente verschlüsselt, sodass eine auf diesen Strings basierende YARA-Regel nicht funktioniert.

Wie schon in der Analyse der vorherigen macOS Backdoor der OceanLotus-Gruppe beschrieben, erschafft die Malware eine clientID. Dieses Identifizierungszeichen ist der MD5-Hash des zurückgegebenen Werts von einem der folgenden Befehle:

  • ioreg -rd1 -c IOPlatformExpertDevice | awk ‘/IOPlatformSerialNumber/ { split($0, line, “\””); printf(“%s”, line[4]); }’
  • ioreg -rd1 -c IOPlatformExpertDevice | awk ‘/IOPlatformUUID/ { split($0, line, “\””); printf(“%s”, line[4]); }’
  • ifconfig en0 | awk \’/ether /{print $2}\’ (abrufen der MAC-Adresse)
  • Uns unbekannter Befehl („\ x1e \ x72 \ x0a“), der in den vorherigen Samples unter „uuidgen“ bekannt war.

Vor dem Hashing wird das Zeichen "0" oder "1" an den Rückgabewert angehängt, der die Root-Berechtigung angibt. Diese clientID liegt in /Library/Storage/File System/HFS/25cf5d02-e50b-4288-870a-528d56c3cf6e/pivtoken.appex gespeichert, wenn der Code als Root ausgeführt wird, ansonsten in ~/Library/SmartCardsServices/Technology/PlugIns/drivers/snippets.ecgML. Die Datei wird normalerweise über die _chflags-Funktion ausgeblendet und deren Zeitstempel mit Hilfe des Befehls „touch –t“ mit einem willkürlichen Wert modifiziert.

String Decryption

Wie bei den vorangegangenen Varianten werden die Strings mit der CCCrypt-Funktion AES-256-CDC verschlüsselt (Hex-codierter Schlüssel: 9D7274AD7BCEF0DED29BDBB428C251DF8B350B92 mit Nullen aufgefüllt wie auch der Initialization Vector). Der Schlüssel veränderte sich gegenüber früheren Versionen. Allerdings verwendet die OceanLotus-Gruppe immer denselben Algorithmus zum Verschlüsseln von Zeichenketten, weshalb man die Entschlüsselung automatisieren kann.

Mit diesem Artikel veröffentlichen wir ein IDA-Script, das die Hex-Rays-API verwendet, um die in der Binärdatei vorhandenen Zeichenfolgen zu entschlüsseln. Das Script unterstützt zukünftige Analysen von OceanLotus Malware-Samples, die wir bis jetzt noch nicht gesehen haben. Der Kern des Scripts besteht aus einer generischen Methode, um die an eine Funktion übergebenen Argumente abzufangen. Außerdem sucht es nach Parameterzuweisungen und deren Werte. Die Methode eignet sich auch dazu, eine Liste von Argumenten einer Funktion abzurufen und diese an eine Rückruffunktion zu übergeben.

Kennt man den Prototyp der Entschlüsselungsfunktion, dann findet das Script alle Querverweise auf diese Funktion und alle Argumente. Das Script entschlüsselt die Daten und fügt den Klartext in einen Kommentar an der Adresse des Querverweises ein. Damit das Script ordnungsgemäß funktioniert, muss das von der base64-Decodierungsfunktion verwendete benutzerdefinierte Alphabet im Script festgelegt und die globale Variable, welche die Länge des Schlüssels enthält, definiert sein (in diesem Fall als DWORD; siehe Abbildung 4).

Abbildung 4: Definierung der globalen Variable "key_len"

Abbildung 4: Definierung der globalen Variable "key_len"

Im Function-Fenster kann man auf die Entschlüsselungsfunktion rechtsklicken und “Extract and decrypt arguments” auswählen. Das Script sollte die entschlüsselten Zeichenfolgen als Kommentare einfügen, ähnlich wie in Abbildung 5.

Abbildung 5: Entschlüsselter Text als Kommentare angezeigt

Abbildung 5: Entschlüsselter Text als Kommentare angezeigt

Praktischerweise werden die entschlüsselten Zeichenketten zusammen in IDAs „xrefs to“-Fenster für die f_decrypt-Funktion angezeigt, wie Abbildung 6 zeigt.

Abbildung 6: Xrefs to der f_decrypt-Funktion

Abbildung 6: Xrefs to der f_decrypt-Funktion

Das ganze Script ist in der ESET GitHub-Repository zu finden.

Fazit

Wie im erst kürzlich veröffentlichen OceanLotus-Artikel kann man festhalten, dass die Gruppe ihr Toolset stets auf dem Laufenden hält. Und einmal mehr haben sie gezeigt, dass sich auch macOS-User vor OceanLotus in Acht nehmen müssen. Am Malware-Code brauchten die Cyberkriminellen gar nicht viel zu verändern, da viele macOS-User keine Antiviren-Software installiert haben. ESET-Sicherheitsprodukte erkennen die Bedrohung bereits und eliminieren sie. Die für die C&C-Server-Kommunikation verwendete Netzwerkbibliothek wird auf der Festplatte verschlüsselt. Deshalb sind die Netzwerkprotokolle aus diesem Grund nicht näher bekannt.

Indicators of Compromise (IoCs)

Die IoCs in diesem Blogpost sowie die MITRE ATT&CK-Attribute sind auch in der GitHub-Repository verfügbar.

Domain names

  • daff.faybilodeau[.]com
  • sarc.onteagleroad[.]com
  • au.charlineopkesston[.]com

URL resource

  • /dp/B074WC4NHW/ref=gbps_img_m-9_62c3_750e6b35

File paths

  • ~/Library/SmartCardsServices/Technology/PlugIns/drivers/snippets.ecgML
  • /Library/Storage/File System/HFS/25cf5d02-e50b-4288-870a-528d56c3cf6e/pivtoken.appex
  • /tmp/store

Sample analyzed SHA-1 hash ESET detection name
fleshlightd E615632C9998E4D3E5ACD8851864ED09B02C77D2 OSX/OceanLotus.D

MITRE ATT&CK techniques

Tactic ID Name Description
Defense Evasion T1158 Hidden Files and Directories The backdoor hides the clientID file via chflags function.
T1107 File Deletion The backdoor can receive a “delete” command.
T1222 File Permissions Modification The backdoor changes the permission of the file it wants to execute to 755.
T1027 Obfuscated Files or Information The library used for network exfiltration is encrypted with AES-256 in CBC mode.
T1099 (macOS) Timestomp The timestamp of the file storing the clientID is modified with a random value.
Discovery T1082 System Information Discovery The backdoor performs a fingerprint of the machine on its first connection to the C&C server.
Exfiltration T1022 Data Encrypted The backdoor encrypts the data before exfiltration.
Command and Control T1094 Custom Command and Control Protocol The backdoor implements a specific format for the packet involving random values. See Trend Micro article.