Skip Navigation
BlackBerry ThreatVector Blog

Threat Thursday: Jupyter Infostealer is a Master of Disguise

Summary

Jupyter infostealer is a master of deception, a highly modular malware that hides deep within legitimate installer packages. Once executed, it can receive further malicious components via its command-and control (C2) server to enhance its capabilities. These components can include executables and malicious PowerShell scripts.

One of the downloads is an information stealing module, designed to scoop up victim credentials like their computer name, user admin rights, workgroup, browser password database, and other useful information. It also targets popular browsers such as Google Chrome™, Microsoft Edge®, Opera, Brave, and Mozilla Firefox. Upon finding one of these browsers installed, it gathers and exfiltrates sensitive user data stored within these browsers, such as login data (usernames and passwords), cookies, and web data, including “autofill” information such as the user’s name, home address, and email address.

It also targets a large number of crypto wallets, including Atomic Wallet, MyMonero Wallet, and Ethereum Wallet, and additionally seeks to access several Remote Access Applications including OpenVPN and Remote Desktop Protocol (RDP).

This malware is particularly noxious, as it does not target specific organizations or business verticals, and it does not have a set goal or agenda. It targets all victims who inadvertently fall for its ploys.

Discovery and Execution

When Jupyter was first discovered at the end of 2020, it initially bundled itself with legitimate executables. When executed, it revealed an obfuscated PowerShell script hidden within. Throughout 2021, this threat group has focused its development efforts on increasing levels of stealth and obfuscation, including loading the Dynamic-Link Library (.DLL) of Jupyter reflectively into memory rather than writing the file to disk.

In its current form, Jupyter now tends to be bundled in large Windows® installer packages (.MSI), often exceeding 100 MB in size. These packages are still bundled with legitimate applications, and also signed with valid digital certificates to further hide their intentions.

On installation, the package will load and attempt to install the bundled legitimate application. However, deep within the code of these Trojan installers resides a relatively small, heavily obfuscated and encrypted PowerShell script that will run in the background.

Operating System

Risk & Impact

Technical Analysis

Many Faces, Many Names, Many labels

Over a short period of time, Jupyter has masqueraded as many different applications and installers. The malware has also changed its core file extension to .MSI, and it uses different operations to execute its obfuscated PowerShell script.

This flexibility has led various security research organizations to label the malware family differently, based on Jupyter’s core module naming functions, or downloaded components. Previous names include Polazert, Yellow Cockatoo, and more recently SolarMarker/Deimos. The malware has since abandoned the Indicators of Compromise (IoCs) that were the basis of these naming conventions, to thwart easy identification.

Infection Vector

Jupyter’s initial infection vector can vary widely. Typically, Jupyter is hosted on fake downloader websites that masquerade as legitimate hosts. These sites typically offer a free download for a PDF book or a simple application. These can either be visited by a victim unintentionally, or via a link in a malicious email.

Figure 1: Jupyter samples are often signed with digital certificates to appear trustworthy

Jupyter is often bundled with freeware applications and signed with un-revoked digital certificates as shown in Figure 1, making the download appear more legitimate.

In previous iterations, Jupyter had moved away from using Windows Portable Executables (.EXE files) in favor of large Windows Installer Packages (.MSI). This is likely because MSI is a file type that is less likely to be scanned by some antivirus (AV) programs, and because large files (beyond 100 MB) are less likely to be inspected by automated sandbox routines and other automated AV scanning solutions.

Installation

On execution, the Windows installer package will display an installer pop-up for the intended legitimate application, as shown in Figure 2, while loading its data and silently running in the background.

Figure 2: Trojanized MSI files appear to install the desired application as expected

Over the past campaign, Jupyter has used a wide range of methods to deploy itself. Typically, the malware contains two core files – an executable and a Windows PowerShell containing the malicious code – though it is not limited to this arrangement.

Some variants of Jupyter have also deployed a temporary file (.TMP) into the victim’s %AppData%\Roaming\Temp\ directory, and they have dropped an additional Microsoft PowerShell (.PS1) file, as shown in Figure 3, to generate the typical content of Jupyter’s core malicious PowerShell script.

Figure 3: Contents of Jupyter MSI installer

PowerShell

All samples of Jupyter have heavily relied on PowerShell. The malware uses PowerShell both to obfuscate its malicious code, and to execute that code without it ever writing itself to disk on the victim’s machine.

It avoids writing itself to disk by loading the DLL of Jupyter reflectively into memory. Normally, DLLs are injected into a process from a file that is written to disk. Reflective DLL injection is a technique that forcefully injects code into a victim process from memory rather than disk.

As the fully un-obfuscated malware does not reside on disk, it requires a persistence mechanism to be created, such as registry keys that reload the malware when the victim machine is started up. This makes Jupyter DLL difficult to both detect and analyze, unless dumped from memory.

Figure 4: Breakdown of Jupyter PowerShell

Jupyter’s core PowerShell typically can be broken down into six different steps or components, as shown in Figure 4 and the table below. Each step facilitates a specific goal, function, or ability. Though a lot of samples of Jupyter follow the same steps, variations are present in Jupyter’s PowerShell code, and some samples have been noted to operate in slightly different ways to achieve the same ends.

Step

Description/Functionality

Obfuscated DLL

This is the obfuscated variable that contains the core code of Jupyter DLL

Deobfuscated Routine

This is the routine where the code from “Obfuscated DLL” is passed to deobfuscate the malicious core code of Jupyter. Jupyter is often encoded in Base64 and XOR’d.

Added to Startup

Jupyter adds itself to startup to force re-execution of the malware, as a persistence mechanism.

Decoy File Creation

The malware hides itself in a commonly found directory within the victim’s %AppData%\Roaming\ folder. It drops a random number of “junk files” to hide the presence of one functional, malicious file. The malware randomizes the number of junk files created, often ranging between 100 and 300, in most variants of the PowerShell code.

DLL Reflection

The malware executes reflectively, to prevent the DLL from being dropped onto the user’s device.

Added to Registry

For further persistence, the malware adds a Registry Key to the victim machine.


Not all samples of Jupyter observed over its recent campaign have the same behavior. Some deploy their decoy files in different directories. Others opt not to XOR their DLL’s code, while still encoding themselves with Base64.

Decoy

To thwart analysis, one of the first actions of Jupyter’s PowerShell is to create hundreds of randomized “junk files” as decoys, as shown in Figure 5, while leaving a single file as the core component of the malware. These decoys are files that are created by the malware that serve no malicious use or purpose except to hide the single malicious file within their midst.  

Figure 5: Decoy Files dropped by Jupyter

Previously observed iterations of Jupyter would drop their core .DLL to disk. Though this ploy is still used by Jupyter, it does not deploy the DLL directly to disk anymore. The deobfuscated version of the malware is now only loaded into memory.

With each execution of the PowerShell script, the malware will generate a new directory for its randomized set of decoy files and core malware component. Over the course of this recent campaign, Jupyter has deployed itself in three distinct locations on a victim device:

  • %AppData%\Roaming\Adobe\ [Random 15 Char directory]\
  • %AppData%\Roaming\Microsoft\ [Random 15 Char directory]\
  • %AppData%\Roaming\Nvidia\ [Random 15 Char directory]\

Persistence

On execution, Jupyter will silently run its PowerShell script. This script can be modified to display its true intentions for analysis, as displayed in the image below.

Figure 6: Persistence-based mechanisms via registry keys

The sample used for this analysis of Jupyter creates a new directory in the folder C:\Users\%Admin%\AppData\Roaming\Microsoft. In this example, the directory was named kNPqHZeEjTuJAXRY, as seen in Figure 6. These locations are randomized by the malware and a new one is generated per execution.

The malware will add an additional shortcut file to the Windows\Start Menu directory via %AppData%\Roaming\Microsoft\Windows\Start Menu\Programs\Startup. This also uses a randomized name derived from a variable in its PowerShell code. This shortcut is deployed by the malware as a persistence mechanism, so it will execute the file on startup, as shown in Figure 7.

Figure 7: Example of Jupyter sample startup shortcut

Jupyter also generates two different registry keys during the execution of its PowerShell code. The first key is added to the victim’s machine in the following location, as seen in Figure 7: Computer\HKEY_CURRENT_USER\SOFTWARE\Classes\%.cwvynlbszymn%

This final part of the registry key is also randomized; each time the malware is executed, it will generate a new randomized sequence. This key points to the second registry key generated by the malware, as shown in Figure 8.

Figure 8: RegKey added by Jupyter

The data within the second registry key added by Jupyter contains a PowerShell command that will re-execute the malware, as shown in Figure 9. This is used as a further persistence mechanism by the malware.

Figure 9: Core registry key re-executing Jupyter

Once located, the contents of this registry key can be further analyzed and inspected. Like its initial PowerShell script, its intentions are to deobfuscate the malware’s main DLL and load it reflectively into memory.

This PowerShell command, as shown in Figure 10, is a truncated version of the original PowerShell code. Its purpose is to re-run, or execute the malware, on startup. This code is notably smaller in size, as it omits previously achieved steps and functionality, such as deploying the decoy files and adding registry keys.

Figure 10: PowerShell contents of registry keys

Core DLL

The core DLL related to Jupyter is .NET-compiled. Previous iterations of this DLL contained labelled functions, and it was not obfuscated, which gave clear indications of the malware’s intentions. In late 2021, newer iterations and versions of the malware became more sophisticated. The malware no longer uses identifiable labels for its functions, adding further obfuscation to its code’s contents. Despite this evolution, the functionality of this “core module” remains largely the same.

Figure 11: Differences between versions of Jupyter

The initial functionality of this module is to establish contact with the malware’s C2 infrastructure. The malware achieves this using the .NET WebRequest provider to send POST requests to a hard-coded IP address located within each sample of Jupyter.

During analysis, we noted that the C2 infrastructure for Jupyter appears to remain offline until it is required. The malware continues running in the background and awaits its infrastructure coming online. It will check for the availability of the C2 at regular intervals until successful connection is achieved.

The request to the C2 contains RSA-encrypted data, including a hard-coded RSA key as seen in Figure 12, that is used for future communications. Jupyter also uses Advance Encryption Standard (AES) encryption for its communications.

AES is a commonly used symmetric block cipher. Jupyter uses this encryption standard on its communication to prevent packet interception and inspection when communication, deployment of modules, and exfiltration of data is occurring between the malware core module and the C2.

Figure 12: Contents of Jupyter’s “configuration” function

If a successful connection is achieved, the core module begins its reconnaissance of the victim’s device to locate information such as:

  • Machine name
  • Windows version
  • CPU architecture (x86/x64)
  • User’s admin rights
  • Workgroup
  • DNS
  • Protocol version
  • Machine status (idle/active)

Jupyter contains a “ping” function that will attempt to send this information, along with following:

  • Version ID of the malware (version)
  • A unique hash derived from the victim device hardware (hwid)
  • A Base64 unique identifier hash per communication (uniq_hash)

Once communication has been established with its C2, Jupyter’s modular design allows the threat to receive further malicious components to enhance its capabilities, as seen in Figure 13. These components can include executables and further malicious PowerShell scripts.

Figure 13: C2 activity and download of additional components

Versions

Each sample of Jupyter has a “Version ID” (shown in Figure 12) that is used in C2 communication. A newly discovered Version ID often signifies a change, update, or the addition of further capabilities to the core malware module. Different variations of Jupyter can largely be identified by characteristics of these Version IDs.

OC-1:

Powershell payload seen embedded in MSI sample as .txt file

.TXT file is dropped to the AppData folder

Command to use the payload embedded in MSI launch action

Command reads .TXT file from AppData and decodes further commands

XORed

OC-8:

Base64 at the beginning

Wscript

AppData\Adobe folder

Imports user32.dll

Get-Process

Defines two functions

Reflective loading of Base64 DLL

No XOR

OC-9:

Base64 at the beginning

 WScript

AppData\Adobe folder

Imports user32.dll

Get-Process

Defines two functions

Reflective loading of Base64 DLL

XORed

3d8:

Base64 at the beginning

Wscript

AppData\Adobe folder

Imports user32.dll, this is further hidden in a sub obfuscated PowerShell command

Get-Process

Defines two functions

Reflective loading of Base64 DLL

XORed

Table 1: Jupyter versions

Modules

Once Jupyter has finished creating persistence, it begins checking a hard-coded C2 for the next module to download. Throughout our research, we observed a variety of different modules served by the C2. On examining this main Jupyter module and the capabilities of the code, it is possible to rename the obfuscated functions to estimate their name prior to obfuscation:

Figure 14 – Original function names versus renamed functions based on capabilities

One of the downloaded components is an information-stealing module, which includes a PowerShell script and payload. The payload is decoded by the PowerShell script and then reflectively loaded into memory.

Infostealer Module:

This module uses several functions to extract information from various sources on a victim’s computer. One of the functions used is the Data Protection API (DPAPI). Within this API, a class called ProtectedData contains two wrappers: “Protect” and “Unprotect.” The infostealing module makes use of the “Unprotect” wrapper, which is passed a byte array of encrypted data and returns a byte array of decrypted data.

As seen in Figure 15, the Unprotect wrapper is called via the method “a01e73a94eb4d2952c37caa645a74.”

Figure 15 – Extraction of Chrome password database and encryption key for database

The Chrome JSON configuration is stored in the local AppData directory in a file called “Local State,” which is parsed using a class starting with “a5f8…” Within this configuration is an entry called “os_crypt,” which has a further entry called “encrypted_key.” The “encrypted_key” is used to encrypt saved login data.

The infostealer module uses a utility class “a01e…” to read this encrypted key, and a static class function starting with “a671…” to call DPAPI Unprotect. As the key is prefixed with DPAPI signature bytes, a loop runs five times to omit this. Once the “encrypted_key” is formatted, it is then stored in a class field called “aes_key.” Further to this, a randomly named copy of the Chrome “Login Data” file is written to the temporary directory in Windows, which is then stored in the class field “pwds_db” and deleted from the temporary directory.

There is no decryption of the stored Chrome login data taking place in the function shown in Figure 15; the relevant data is read and stored into class member fields “aes_key” and “pwds_db.” The “pwds_db” and “aes_key” values are collected and converted to Base64. This indicates the malware authors are opting to perform credential decryption following data exfiltration. This makes sense from an efficiency perspective, as they have everything necessary to decrypt the login data after stealing the Chrome information.

The infostealer module targets the following browsers:

  • Google Chrome
  • Microsoft Edge
  • Opera
  • Brave
  • Mozilla Firefox

It also gathers the following browser data:

  • Login data (usernames/passwords)
  • Cookies
  • Web data (Autofill information such as names, addresses, emails)
Figure 16: Decrypting Firefox data
 

Figure 17: Decrpyting Chrome data

Jupyter targets the following crypto wallets:

  • Atomic Wallet
  • Guarda Wallet
  • SimplEOS Wallet
  • NEON Wallet
  • Wasabi Wallet
  • MyMonero Wallet
  • Jaxx Wallet
  • Electrum Wallet
  • Ethereum Wallet
  • Exodus Wallet
  • GreenAddress Wallet
  • Coin Wallet
  • Bither Wallet
  • Coinomi Wallet
  • Ledger Live Hardware wallet
  • Trinity Hardware wallet
  • Scatter Hardware wallet
  • Wildcard any file matching: *wallet*.dat
  • Wildcard any file matching: *.wallet

Remote Access Applications Targeted:

  • OpenVPN
  • Remote Desktop Protocol (RDP)

Conclusion

At the close of 2021, Jupyter saw rapid enhancements to prior iterations. This made the newer versions of malware harder to detect, scan and prevent, leading to a rise in devices affected by the malware.

Now that Jupyter is being bundled with legitimate, signed software, this ploy makes it difficult to detect the threat before it has been deployed onto a victim system. As the malware executes via DLL reflection, it gives little indication that it is running silently in the background. Once on a victim system, Jupyter will use multiple persistence mechanisms, and it will even install the legitimate software it’s bundled with to further deceive the victim.

To further conceal its activities, Jupyter’s C2 infrastructure tends to remain offline for large periods of time, operating in short bursts of activity rather than constant communication.

The modular nature of the malware keeps its core-module compact. Jupyter largely focuses on stealing information, deploying various modules to obtain passwords, credentials, and other data. However, the malware is not just limited to these activities. Once it gains a foothold on the system, it can download a wide variety of components, making it an extremely dangerous piece of malware.

YARA Rule

The following YARA rule was authored by the BlackBerry Research and Intelligence Team to catch the threat described in this document:

import "pe"
import "dotnet"

rule Mal_Infostealer_EXE_Jupyter_Cert_36ff
{
    meta:
        description = "Detects Jupter executables by certificate OOO Sistema (36ff)"
        author = "BlackBerry Research & Intelligence Team"
        date = "2021-10-14"
        license = "This Yara rule is provided under the Apache License 2.0 (https://www.apache.org/licenses/LICENSE-2.0) and open to any user or organization, as long as you use it under this license and ensure originator credit in any derivative to The BlackBerry Research & Intelligence Team"       

    condition:
        uint16(0) == 0x5a4d and
        for any i in (0 .. pe.number_of_signatures) : (
            pe.signatures[i].issuer contains "Certum Extended Validation Code Signing CA SHA2" and
            pe.signatures[i].serial == "36:ff:67:4e:b3:05:e9:9c:35:56:5f:a3:01:d5:c4:b0" // Serial variable must be lowercase
            )
}

rule Mal_Infostealer_MSI_EXE_Jupyter_Certificate
{
    meta:
        description = "Detects Jupter by certificate"
        author = "BlackBerry Threat Research Team"
        date = "2021-11-04"
        license = "This Yara rule is provided under the Apache License 2.0 (https://www.apache.org/licenses/LICENSE-2.0) and open to any user or organization, as long as you use it under this license and ensure originator credit in any derivative to The BlackBerry Research & Intelligence Team"

    strings:
        // MSI Installer
        $msi = { D0 CF 11 E0 A1 B1 1A E1 }

        // MSI Strings
        $a1 = "EMCO MSI Package Builder"

        // PowerShell execution strings
        $b1 = "powershell-ExecutionPolicy bypass -command \"iex([\\[]IO.File[\\]]::ReadAllText('[CurrentUserProfileFolder]" nocase
        $b2 = "powershell-ep bypass -file \"[AppDataFolder]" nocase
        $b3 = /powershell-ep bypass -windowstyle hidden -command \"\$xp=\'\[AppDataFolder\].{0,256}\.{0,256}\'/ nocase
        $b4 = /powershell-ep bypass -windowstyle hidden -command \"\$p=\'\[AppDataFolder\].{0,256}\.{0,256}\'/ nocase
        $b5 = /powershell-ExecutionPolicy bypass -command \"iex\(\[\\\[\]IO.File\[\\\]\]::ReadAllText\(\'\[CurrentUserProfileFolder\].{1,256}\..{1,256}\'\)\)/ nocase

        // Certificate Name
        $c1 = "OOO ENDI"
        $c2 = "OOO MVS"
        $c3 = "OOO LEVELAP"
        $c4 = "Soto Manufacturing SRL"
        $c5 = "Decapolis Consulting Inc."

        // Co-signers
        $f1 = "SSL.com EV Root Certification Authority RSA R2"
        $f2 = "SSL.com EV Code Signing Intermediate CA RSA R3"
        $f3 = "DigiCert Trusted G4 Code Signing RSA4096 SHA384 2021 CA1"
        $f4 = "DigiCert Trusted Root G40"

    condition:
        ($msi at 0 or uint16(0) == 0x5a4d) and
        all of ($a*) and
        1 of ($b*) and
        1 of ($c*) and
        2 of ($f*)
}

rule Mal_Infostealer_MSI_Jupyter_Embedded_PowerShell
{
    meta:
        description = "Detects Jupter by a specific PowerShell command present in the MSI Installer"
        author = "BlackBerry Threat Research Team"
        date = "2021-10-14"
        license = "This Yara rule is provided under the Apache License 2.0 (https://www.apache.org/licenses/LICENSE-2.0) and open to any user or organization, as long as you use it under this license and ensure originator credit in any derivative to The BlackBerry Research & Intelligence Team"

    strings:
        // MSI Installer
        $msi = { D0 CF 11 E0 A1 B1 1A E1 }

        // Embedded PowerShell Command
        $x1 = /powershell-ep bypass -windowstyle hidden -command \"\$xp=\'\[AppDataFolder\]pd\w*\.(log|txt)\';\$xk=\'[a-zA-Z]{52}\';\$xb=\[\\\[\]System\.Convert\[\\\]\]::FromBase64String\(\[\\\[\]System\.IO\.File\[\\\]\]::ReadAllText\(\$xp\)\);remove-item \$xp;for\(\$i=0;\$i -lt \$xb.count;\)\[\\\{\]for\(\$j=0;\$j -lt \$xk\.length;\$j\+\+\)\[\\\{\]\$xb\[\\\[\]\$i\[\\\]\]=\$xb\[\\\[\]\$i\[\\\]\] -bxor \$xk\[\\\[\]\$j\[\\\]\];\$i\+\+;if\(\$i -ge \$xb.count\)\[\\\{\]\$j=\$xk\.length;\[\\\}\]\[\\\}\]\[\\\}\];\$xb=\[\\\[\]System.Text.Encoding\[\\\]\]::UTF8\.GetString\(\$xb\);iex \$xb;/ nocase

    condition:
        $msi at 0 and
        all of ($x*)
}

rule Mal_Infostealer_PowerShell_Jupyter_Updated_Samples
{
    meta:
        description = "Detects Jupter powershell via common strings"
        author = "BlackBerry Threat Research Team"
        date = "2021-11-04"
        license = "This Yara rule is provided under the Apache License 2.0 (https://www.apache.org/licenses/LICENSE-2.0) and open to any user or organization, as long as you use it under this license and ensure originator credit in any derivative to The BlackBerry Research & Intelligence Team"

    strings:
        $c1 = /\.[T|t][O|o][L|l][O|o][W|w][E|e][R|r]\(\)\)?;[I|i][E|e][X|x]/
        $c2 = "get-random -minimum 50000 -maximum 200000" nocase
        $c3 = "ReaDALlBYTES" nocase
        $c4 = /createshortcut\(\$env\:appdata\+'\\m\'\+\'icr\'\+\'oso\'\+\'ft\'\+\'\\w\'\+\'ind\'\+\'ow\'\+\'s\\\'\+\'st\'\+\'art\'\+\' me\'\+\'nu\'\+\'\\pr\'\+\'ogr\'\+\'ams\\\'\+\'st\'\+\'art\'\+\'up\'\+\'\\.{29}\.lnk\'\)/ nocase

    condition:
        all of ($c*)
}

rule Mal_Infostealer_Win32_Jupyter_Main_Module
{
    meta:
        description = "Detects Jupter main module"
        author = "BlackBerry Threat Research Team"
        date = "2021-11-23"
        license = "This Yara rule is provided under the Apache License 2.0 (https://www.apache.org/licenses/LICENSE-2.0) and open to any user or organization, as long as you use it under this license and ensure originator credit in any derivative to The BlackBerry Research & Intelligence Team"

    strings:
        $g1 = { 68 00 74 00 74 00 70 00 3A 00 2F 00 2F 00 } // h.t.t.p.:././.
        $g2 = { 5C 00 41 00 50 00 50 00 44 00 41 00 54 00 41 00 5C 00 52 00 4F 00 41 00 4D 00 49 00 4E 00 47 } // \.A.P.P.D.A.T.A.\.R.O.A.M.I.N.G
        $g3 = { 63 00 68 00 61 00 6E 00 67 00 65 00 5F 00 73 00 74 00 61 00 74 00 75 00 73 } // c.h.a.n.g.e._.s.t.a.t.u.s
        $g4 = { 50 00 4F 00 53 00 54 } // P.O.S.T
        $g5 = { 69 00 73 00 5F 00 73 00 75 00 63 00 63 00 65 00 73 00 73 } // i.s._.s.u.c.c.e.s.s
        $g6 = { 75 00 73 00 65 00 72 00 70 00 72 00 6F 00 66 00 69 00 6C 00 65 } // u.s.e.r.p.r.o.f.i.l.e
        $g7 = { 44 00 45 00 53 00 4B 00 54 00 4F 00 50 00 2D } // D.E.S.K.T.O.P.-
        $g8 = { 4C 00 41 00 50 00 54 00 4F 00 50 00 2D } // L.A.P.T.O.P.-
        $g9 = { 78 00 38 00 36} // x.8.6
        $g10 = { 78 00 36 00 34 } // x.6.4
        $g11 = { 41 00 64 00 6D 00 69 00 6E } // A.d.m.i.n
        $g12 = { 56 00 69 00 73 00 74 00 61 } // V.i.s.t.a
        $g13 = { 64 00 6E 00 73 } // d.n.s
        $g14 = { 64 00 7A 00 6B 00 61 00 62 72 } // d.z.k.a.b.r
        $g15 = { 78 00 7A 00 6B 00 61 00 62 00 73 00 72 } // x.z.k.a.b.s.r
        $g16 = { 64 00 7A 00 6B 00 61 00 62 00 73 00 72 } // d.z.k.a.b.s.r

        // Version Strings
        $h1 = { 4F 00 43 00 2D } // O.C.-
        $h2 = { 4E 00 56 00 2D } // N.V.-
        $h3 = { 53 00 50 00 2D } // S.P.-
        $h4 = { 49 00 4E 00 2D } // I.N.-

        $i = "System.Net"

    condition:
        10 of ($g*) and
        1 of ($h*) and
        (pe.imports("mscoree.dll", "_CorDllMain") or $i) // DotNet
}

rule Mal_Infostealer_Win32_Jupyter_InfoStealer_Module
{
    meta:
        description = "Detects Jupter infostealer module"
        author = "BlackBerry Threat Research Team"
        date = "2021-11-08"
        license = "This Yara rule is provided under the Apache License 2.0 (https://www.apache.org/licenses/LICENSE-2.0) and open to any user or organization, as long as you use it under this license and ensure originator credit in any derivative to The BlackBerry Research & Intelligence Team"

    strings:
        $d1 = "WebRequest" nocase
        $d2 = "HttpWebRequest" nocase
        $d3 = "WebResponse" nocase
        $d4 = "GetResponseStream" nocase
        $d5 = "GetResponse" nocase
        $d6 = "IsInRole" nocase
        $d7 = "get_UTF8" nocase
        $d8 = "FromBase64String" nocase
        $d9 = "get_OSVersion" nocase
        $d10 = "GetFiles" nocase
        $d11 = "GetExtension" nocase
        $d12 = "get_Current" nocase
        $d13 = "GetEnumerator" nocase

        $j1 = { 6C 6F 67 69 6E 73 } // logins
        $j2 = { 43 00 6F 00 6F 00 6B 00 69 00 65 00 73 } // C.o.o.k.i.e.s
        $j3 = { 00 6C 00 6F 00 67 00 69 00 6E 00 73 00 2E 00 6A 00 73 00 6F 00 6E 00 } // .l.o.g.i.n.s...j.s.o.n.
        $j4 = { 00 63 00 6F 00 6F 00 6B 00 69 00 65 00 73 00 2E 00 73 00 71 00 6C 00 69 00 74 00 65 00 } // .c.o.o.k.i.e.s...s.q.l.i.t.e.

    condition:
        // DotNet
        pe.imports("mscoree.dll", "_CorDllMain") and
        12 of ($d*) and
        2 of ($j*)
}

rule Mal_Infostealer_Win32_Jupyter_Download_and_Execute_Module
{
    meta:
        description = "Detects Jupter download and execute module. Research has shown it downloading SolarDelphi / JupyterStealer."
        author = "BlackBerry Threat Research Team"
        date = "2021-11-09"
        license = "This Yara rule is provided under the Apache License 2.0 (https://www.apache.org/licenses/LICENSE-2.0) and open to any user or organization, as long as you use it under this license and ensure originator credit in any derivative to The BlackBerry Research & Intelligence Team"

    strings:
        $e1 = { 68 00 74 00 74 00 70 00 3A 00 2F 00 2F 00 }
        $e2 = { 47 00 45 00 54 00 00 3D 63 00 3A 00 5C 00 77 00 69 00 6E 00 64 00 6F 00 77 00 73 00 5C 00 73 00 79 00 73 00 74 00 65 00 6D 00 33 00 32 00 5C 00 77 00 69 00 6E 00 76 00 65 00 72 00 2E 00 65 00 78 00 65 }
        $e3 = { 00 2F 00 67 00 65 00 74 00 2F 00 }
        $e4 = "FromBase64String"
        $e5 = "get_UTF8"
        $e6 = "WebResponse"
        $e7 = "GetResponse"
        $e8 = "Invoke"

    condition:
        // DotNet
        pe.imports("mscoree.dll", "_CorDllMain") and
        dotnet.version == "v4.0.30319" and
        dotnet.assembly.version.major == 0 and
        dotnet.assembly.version.minor == 0 and
        all of ($e*)
}


Indicators of Compromise (IoCs)

SHA256:

  • dd8e1e321ce70472f9f0681c6e2dc078e7d066d89bc63ca4ae1ac53bee8daac2
  • a772d35e54bcd6790ea99f8723d56872891ef5691ed502a82babc618d2e8a452
  • 0adfbce8a09d9f977e5fe90ccefc9612d1d742d980fe8dc889e10a5778592e4d
  • 0e673eb418c87268aa3bcb262e8e03a3f719a95a8e118ba99515c57c9aa02d38
  • 10221ceffbc7d7e59b17b1968d0fa01c8124efa70d1d5a486e53211e4754a22d
  • 13d34fbf591c2cbf38e60ec3c6d185546e206be61dd58923edc23c4b125ff2f0
  • 161b6f4bc07567c0c6e2e394454a66b8aac2f73212a6cf6c0c82b9fdbdb3fcce
  • 1e7914f799371cbc8560bc52203d3531bb20cb4f6092158c76a4842dbf85dabc
  • 2a051324620943464749234c9b49def385b9f6dd7c30f4caa4d98b3af035bd8f
  • 3303926a6468dab25286a65bb9f3e5883a8938e6501031b3b85e21f182d1ed0d
  • 341881d11fd748a81c8cee584dc42392a564aeb839faf7afa136004701e656c1
  • 38c833c34998c9f4d9266f920c0f0862d986cb434740f99175e32f3f49275eb5

C2 IP:

  • 146.70.24[.]229
  • 23.29.115[.]175
  • 92.204.160[.]110
  • 146.70.41[.]157
  • 37.221.114[.]23
  • 188.241.83[.]61
  • 69.46.15[.]151

C2 Identifier/Version:

  • NV-5
  • OC-11
  • OC-1
  • OC-2
  • J13
  • J15
  • J16
  • IN-10
  • NV-1
  • NV-4
  • NV-6
  • OC-3
  • OC-7
  • OC-8
  • OC-9
  • OC-W1
  • SP-10
  • SP-13
  • SP-17
  • SP-18
  • SP-W2

Certificate #1:

  • Serial: 36 FF 67 4E B3 05 E9 9C 35 56 5F A3 01 D5 C4 B0
  • Name: OOO Sistema
  • Valid from: 01:51 PM 12/02/2020
  • Valid to: 01:51 PM 12/02/2021
  • Thumbprint: C301843CA390AED52C4C6D59EF3D125400F186FB

Certificate #2:

  • Serial: 5B A9 00 D7 A7 61 EE 27 C2 79 98 C8 B9 B4 FA 70
  • Name: OOO LEVELAP
  • Valid from: 11:53 AM 09/14/2021
  • Valid to: 11:53 AM 09/14/2022
  • Thumbprint: EDEBF26E6CAD49A8F48A11EFF6BFC13266FF6872

Certificate #3:

  • Serial: 6F E7 21 C3 DD BD 27 74 D0 3D CE A4 4A 26 A7 8A
  • Name: OOO ENDI
  • Valid from: 08:17 PM 09/29/2021
  • Valid to: 08:17 PM 09/29/2022
  • Thumbprint: BC346A6BF6B6D53A69A742A4245A43320980B1C0

Certificate #4:

  • Serial: 7B 44 65 51 DE 53 1A 37 D3 A0 EB FB 8F 0B 6E 01
  • Name: OOO MVS
  • Valid from: 08:19 PM 10/01/2021
  • Valid to: 08:19 PM 10/01/2022
  • Thumbprint: 691718CA7F85C0D5B89250D685EB52A808A321E5

Certificate #5:

  • Serial: 06 48 7A 92 B1 D9 12 B7 9F 22 91 C0 D3 82 0F 2C
  • Name: Soto Manufacturing SRL
  • Valid from: 12:00 AM 10/04/2021
  • Valid to: 11:59 PM 08/04/2023
  • Thumbprint: AEE8241A17357D5713C451406BA4D3FBDCC1E25F

Certificate #6:

  • Serial: 0A 54 C6 04 87 D8 38 4E DC E9 81 81 4B E7 67 CB
  • Name: Decapolis Consulting Inc.
  • Valid from: 12:00 AM 10/31/2021
  • Valid to: 11:59 PM 10/24/2022
  • Thumbprint: BB800B7DE9E457D670303AF12E1940C732CC5975


BlackBerry Assistance

If you’re battling this malware or a similar threat, you’ve come to the right place, regardless of your existing BlackBerry relationship.

The BlackBerry Incident Response team is made up of world-class consultants dedicated to handling response and containment services for a wide range of incidents, including ransomware and Advanced Persistent Threat (APT) cases.

We have a global consulting team standing by to assist you providing around-the-clock support, where required, as well as local assistance. Please contact us here: https://www.blackberry.com/us/en/forms/cylance/handraiser/emergency-incident-response-containment
 

The BlackBerry Research & Intelligence Team

About The BlackBerry Research & Intelligence Team

The BlackBerry Research & Intelligence team examines emerging and persistent threats, providing intelligence analysis for the benefit of defenders and the organizations they serve.