Blog

eSentire Threat Intelligence Malware Analysis: SolarMarker: To Jupyter and Back

BY eSentire Threat Response Unit (TRU)

November 16, 2023 | 18 MINS READ

Attacks/Breaches

Threat Intelligence

Threat Response Unit

TRU Positive/Bulletin

Want to learn more on how to achieve Cyber Resilience?

TALK TO AN EXPERT

IN THIS POST

Key Takeaways

  • SolarMarker uses process injection to run the hVNC and data staging payload.
  • The actors behind SolarMarker primarily utilize .NET for the majority of their payloads, with the notable exception of the observed hVNC backdoor, which is written in Delphi.
  • The initial infection triggers numerous PowerShell processes, resulting in a highly noticeable activity pattern.
  • The threat actor(s) started crafting their own websites to host the landing pages.
  • We are currently seeing versions JN-2, JN-10 and M-VII being deployed.

The eSentire Threat Response Unit (TRU) has been monitoring SolarMarker (also known as Jupyter) since 2021. This malware, written in .NET, possesses a backdoor and is capable of stealing information. The delivery method involves the threat actor(s) compromising vulnerable WordPress websites, which ultimately leads to the distribution of the SolarMarker payload to users.

The threat actor(s) had used MSI and EXE payloads before that were over 200-300 MB in size. eSentire has observed SolarMarker activities since the end of 2022 and the beginning of 2023, targeting healthcare, power and utilities, transportation, legal, software, and finance industries before taking a short break.

SolarMarker threat actor(s) tend to slightly change the format of the second-stage PowerShell decryption script, they went from using XOR encryption to AES, but the logic is still the same.

2020:

The decryption routine uses simple XOR on the encrypted Base64-encoded payload saved to the disk as a text file. The decrypted payload is then directly executed via IEX, shown in Figure 1 below.

Figure 1: Decryption routine (2020)

2021:

Simple XOR is used to decrypt the payload. The payload is stored under a randomly named file under the %AppData%\Microsoft folder. The resulting decrypted data is then loaded as an assembly using the [Reflection.Assembly]::Load method, shown in Figure 2 below.

Figure 2: Decryption routine (2021)

2022:

The payload is encrypted with the AES encryption algorithm. It sets the encryption key using a Base64-encoded string, and the initialization vector (IV) is the first 16 bytes of the encrypted file (Figure 3).

Figure 3: Decryption routine (2022)

January 2023:

The AES key and IV are stored in a byte array. The encrypted payload Base64-encoded payload is stored under C:\Users\<username>\ under a randomly named file (Figure 4).

Figure 4: Decryption routine (January 2023)

May 2023:

The decryption algorithm is the same as the one mentioned above, but the encrypted payload is stored under the randomly created registry name under HKCU:\Software\Classes\ (Figure 5). The payload is written to the registry as bytes instead of in Base64-encoded format.

After loading the decrypted payload into memory, the script enters an infinite loop and includes a delay using the Start-Sleep command. This behavior might be an attempt to evade detection, as the script continues to run indefinitely with periodic pauses.

Figure 5: Decryption routine (May 2023)

January Case

In early January 2023, our Security Operations Center (SOC) received an alert regarding suspicious SearchIndexer usage. This included the detection of a PowerShell script loading processes and outbound network connections to IP addresses flagged as suspicious.

After conducting a thorough investigation, our TRU determined that the infection occurred after the user executed the first stage SolarMarker executable payload that was downloaded from the compromised WordPress website.

The second stage .NET payload was AES-encrypted on disk under %userprofile%. The day after the initial execution, SolarMarker’s third-stage payload was injected into SearchIndexer.exe process, shown in Figure 6.

Figure 6: Infection chain
Figure 7: First stage decryption algorithm (January case)

On the next day after the initial infection, the threat actor(s) pushed the next stage on the infected host which resulted in the searchindexer.exe process injection. We observed over 15k file modification events, which resembled the data staging performed by SolarMarker in the later stages of post-infection as shown in Figure 8.

Figure 8: Data staging

We obtained the Event Logs file (Figure 9) from the client and were able to correlate the timestamps for the process injection and extracted the PowerShell script.

Figure 9: Event logs containing the PowerShell scripts that ran on the infected host

The PowerShell script unravels the third-stage payload (Figure 10).

Figure 10: Snippet of the PowerShell script containing the third-stage payload

StellarInjector

The decryption algorithm used for the third-stage payload is identical to that of the first-stage payload. In this algorithm, the IV consists of the initial 16 bytes obtained after base64 decoding the payload, while the AES key spans 24 bytes. Upon decryption, the script reveals a .NET 32-bit DLL binary, compiled on December 19, 2022 (MD5: 86906856be32fad96e86e7fd6bca89d9). We named the third stage payload as StellarInjector.

Figure 11: Third-stage payload decryption algorithm

SolarMarker employs a string obfuscation technique, where characters are added to a string by subtracting an integer offset from a sequence of numbers. Ultimately, this process yields a resulting string composed of characters (Figures 12-13).

Figure 12: Obfuscated strings
Figure 13: Decoded strings

The threat actor(s) incorporated the inclusion of garbage strings (Figure 14 and 15) with the intention of potentially evading detection by antivirus software, thereby increasing the malware's stealthiness. By introducing such meaningless data, the analysis process can be further complicated, creating challenges for analysts in deciphering the true purpose of the malware.

Figure 14: Garbage data
Figure 15: Output of the junk data

In order to ensure a clear understanding of the sample's functionality, we proceeded with renaming the methods for easy identification (Figure 16).

Figure 16: Renamed methods

Upon examining the majority of the method names, it appears that the process involves the process hollowing. This technique utilizes APIs like ZwUnmapViewOfSection to unmap the process and subsequently resumes execution by utilizing VirtualAllocEx, SetThreadContext, and WriteProcessMemory.

Upon further analysis of the payload, a significant byte array blob was discovered, indicating the presence of an embedded payload, shown in Figure 17.

Figure 17: Embedded payload

Right after the embedded payload, we observe its decryption utilizing the AES CBC algorithm (Figure 18), with the first blob of bytes serving as the key and the second blob as the IV.

Further, we can observe the creation of a new thread with the executable `searchindexer.exe` located at `C:\Windows\SysWOW64\SearchIndexer.exe`, indicating that our embedded payload will be executed from this location (Figure 19).

Figure 19: Payload injection into SearchIndexer.exe

SolarPhantom Backdoor

The extracted payload is written in Delphi and is approximately 520KB in size. Further analyzing the payload, we have found something resembling the hVNC functionality with the hardcoded command and control (C2). We named the hVNC backdoor payload as SolarPhantom.

The code snippets below (Figure 20 and 21) involve operations related to graphics and text rendering; it also involves functions that capture and print the contents of a window, such as PrintWindow and TBitmap.

Figure 20: Graphics and text rendering (1)
Figure 21: Graphics and text rendering (2)

In the code below, the SendMessageA function is used to send the WM_CAP_DRIVER_CONNECT message (0x40Au) to the window specified by the hWnd handle. This message is typically used in video capture applications to connect to a video capture device or webcam (Figure 22).

If the return value of SendMessageA is equal to 1, it means that the capture operation was successful. In this case, the code snippet immediately returns 1, indicating a successful capture.

The function also retrieves the handle of the desktop window via GetDesktopWindow, then it captures the window via capCreateCaptureWindowA, which contains the “CaptureWindow” as the name used for the capture window. The code suggests that its functionality is to capture the footage from web cameras.

Figure 22: Snippet of code that captures webcam footage

Below you can see the APIs being called, such as CreateDesktopA to create a hidden desktop (Figure 23), and SetThreadDesktop, which assigns the hidden desktop to the calling thread, which is the backdoor.

Figure 23: Functions to create a hidden desktop

The snippet of code below is handles the mouse input events (Figure 24) and interacts with windows based on that input. It performs actions based on the mouse action requested and sends messages to the appropriate window to simulate those actions using APIs such as WindowFromPoint (retrieves the handle of the window under the mouse cursor), GetWindowRect (retrieves the window’s rectangle) and PostMessageA (posts the messages to the window). It assigns a value to the variable v7 to represent the type of mouse action (e.g., left-click, right-click, wheel-up, wheel-down, move, select).

This could potentially be used to simulate mouse events and interact with windows on the hidden virtual desktop.

Figure 24: Mouse input events

SolarPhantom creates the directories under the %TEMP% folder based on the Browsers that are present on the infected machine (Figure 25 & 26). Each browser will have the following tag names followed by _bkp.

The files from the user’s browsers are copied to the created directories and are exfiltrated to the C2 server.

Figure 26: File copy to the newly created directory (2)

An example of the data copied from Browser folders is shown in the screenshot below (Figure 27). It should be noted that the files include sensitive information, such as cookies and login data.

Figure 27: Example of the exfiltrated browser data

SolarPhantom initially verifies the existence of a specific browser's '_bkp' directory. If found, it further checks for the presence of browser executables by attempting to retrieve their file timestamps. In case the timestamp retrieval fails, the code proceeds to search for the executables in the 'Program Files' directory, which accommodates 64-bit applications, rather than 'Program Files (x86)'.

Subsequently, it customizes the behavior and appearance of the browser process by specifying the initial position and size of its window before launching the browser. These operations are also performed for Microsoft Edge, Firefox, Portable Chrome, and Brave browsers.

Furthermore, SolarPhantom disables browser metrics, hardware acceleration, and window occlusion calculations (Figure 28). This operation is likely intended to prevent any disruptions in the operation of the hVNC module.

Figure 28: Browser executable check and disabling browser metrics

SolarPhantom generates a random 26-character value and passes it to HWID?/ string to send over to C2 (Figure 29).

Figure 29: Random string generator function

During the initial execution, SolarPhantom sends out the host computer name and username along with the randomly generated HWID to C2 in the following format:

Further investigating, we found 42 SolarPhantom samples on VirusTotal tied to the same C2. You can find the hashes in the Indicators of Compromise section.

May Case

In May, our TRU team conducted a comprehensive analysis of the most recent campaign orchestrated by the SolarMarker threat actor(s). In contrast to previously observed campaigns where the threat actor(s) utilized Google Drive and compromised WordPress websites, it appears that the threat actor(s) now employ their own websites to deploy and host the malicious payload.

This strategic shift grants them increased control over the hosting environment, enabling them to swiftly take down the malicious landing page at their discretion, thereby impeding further scrutiny and analysis by researchers. The landing pages resemble other legitimate companies. In our case, threat actor(s) replicated legitimate websites  of BookBaby (self-publishing company) and Arcadis (engineering company).

The threat actor(s) is still using SEO poisoning. SEO attacks are deceptive tactics employed to manipulate search engine rankings, often involving techniques such as keyword stuffing to deceive search engines and drive traffic to the payload hosting websites.

The initial infection chain is similar to the previous campaigns. The user clicks on the first link (Figure 30), which redirects them to a payload download page with a different link generated each time for a different user (Figure 31). After clicking “Open Document,” the payload will be served from the attacker’s server (Figure 33) that is hosted on Hestia Control Panel over port 8083.

Figure 30: Webpage serving the payload, BookBaby clone (1)
Figure 31: Webpage serving the payload, BookBaby clone (2)
Figure 32: Webpage created to likely serve the payloads, Arcadis clone
Figure 33: Initial infection chain

The website in Figure 30 contains other SEO keywords that might potentially be used:

After executing the first stage payload, SolarMarker first connects to the C2. Then it sleeps for a period of time, and then decrypts the second stage payload, loads, and runs it in memory while establishing a connection to another C2. The persistence is achieved via the startup folder after running for 4-10 minutes. SolarMarker creates the handler key in the registry that points to the encrypted payload within the registry under HKCU:\Software\Classes\<random_name>.

It’s worth noting that eSentire TRU has observed SolarMarker storing the encrypted payload under C:\<username>\<encrypted_payload> (November campaign) or under the %TEMP% folder in previous intrusions.

The latest SolarMarker payloads are dropping decoys such as SumatraPDF and pdf files. The latest decoy at the time of this writing is shown below (Figure 34).

Figure 34: PDF decoy

Upon analyzing one of the recent unobfuscated first-stage payloads (MD5: 3fd9d81c06743c2eaffce6995ff1e46c) which is written in .NET, we noticed an embedded blob of base64-encoded text. The blob contains the base64-encoded PDF decoy file and an AES-encrypted payload as shown in the image below (Figure 35).

Figure 35: Embedded PDF decoy and second stage payload

The “powerShell.BeginInvoke” line starts the execution of the PowerShell script that's been constructed. The "while (!mainApp.ShouldExit && !mre.WaitOne(100))" line causes the main program to wait in a loop until either the PowerShell script finishes executing (signaled by mre being set), or until the main application is supposed to exit (mainApp.ShouldExit becomes true). The WaitOne(100) call causes the loop to check these conditions every 100 milliseconds (Figure 36).

Figure 36: Beautified and decoded Base64 blob
Figure 37: Decrypted first-stage payload
Figure 38: Persistence via registry

Numerous PowerShell processes are spawned under the parent process of the first stage payload every 10-15 seconds, which makes it very noisy (Figure 39).

Figure 39: Initial payload spawning multiple PowerShell processes

If the infected machine has StartUp notifications enabled, they might notice the new StartUp apps created every 4 minutes with a random name. Navigating to the Startup folder under C:\Users\<username>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup, we notice many shortcuts with randomly-generated names. Each of them would point to a PowerShell file under the %AppData% folder.

But why would files in the %AppData% have 0 bytes in size? (Figure 40). That is right, the files have the extension keys registered under Computer\HKEY_CURRENT_USER\Software\Classes\. We also described similar behavior in our previous SolarMarker blog. Each registered extension points to the handler key that contains a PowerShell one-liner to decrypt the payload.

Figure 40: PowerShell files under %AppData%
Figure 41: StartUp Apps
Figure 42: Startup shortcuts

The decrypted second stage payload (MD5: 5fd6c3722eeb7a3c1d54e46c28a020b3) is 567KB in size. The backdoor configuration is shown below.

Figure 44: Payload configuration

Where the version tag is M-VII (we have observed versions JN-2, JN-10 and M-VII in the ongoing campaign so far). The RSA key is:

<RSAKeyValue><Modulus>154ce5nikW2Xbd/8vX5nWqTqQ55EqWNFuaLm4phvECdlmsjYoGqb5o053OxOKGSVhZTZPMwCffhaL0Xgqhz6tRtfrRgIE5c8CZdK8fLTnC6aOFF5U6D/UbwVzZhSaKYwbh1t958MvLQ4TYuJlbPEdTIzWDURKhHZ/qGkLfmvvLWCNG94lmDmSK/osPXwfctzqaX0R2ps+3r88fEHkCuM9UGzlVojr9PXCHpZqj7z1mZiax+sOMdWxAt2ByBP++ghYUG9BM7v0No9QyhtJEz3MArEVERgdWjHh1olmEe4Qk1V5bziC8s6xNB0oCfnjrGis6K9tf9SkBdwyOOLYKHeoQ==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>

The method shown below is used to retrieve information about the operating system, including the version and product name by querying the registry path Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion and CurrentBuild, ProductName values.

The backdoor sends out the basic information on the infected machine, including the configuration using this template with the placeholders for HWID (unique value generated based on the hardware of the infected machine), pc_name, Win (Windows version), arch (architecture), rights (IsAdmin check), and version:

Some of the information parsing is shown below:

Figure 45: Snipper of the info parsing

The code snippet below creates a new instance of WindowsPrincipal using WindowsIdentity.GetCurrent() to get the current Windows user identity. It checks if the current user is in the Administrator role using the IsInRole method with the WindowsBuiltInRole.Administrator parameter. If the user is in the Administrator role, the ‘+’ is applied; if not – the ‘-‘ is applied for the placeholder {4}.

Figure 46: IsAdmin check

The constructor below initializes a ProcessStartInfo object with the command powershell, indicating the execution of a PowerShell process. The ProcessStartInfo object is then used to start the PowerShell process in the call_it method, where the PowerShell script is written to the standard input of the process.

Figure 47: PowerShell script execution function

The method below creates an instance of the class, passing it a dictionary of properties and the ps_script parameter. The dictionary contains three key-value pairs, specifying properties for the ProcessStartInfo object used internally. These properties indicate that the process should not create a window, should redirect the standard input, and should not use the user's shell for execution.

Figure 48: Passing properties to ProcessStartInfo

The code snippet below is responsible for fetching additional payload from C2, specifically exe and ps1 files, and placing them under the %TEMP% folder with a randomly generated name using the GetRandomFileName method.

The following templates are used to communicate with the infected machine, where change_status means the successful execution of the fetched payload:

More on the backdoor commands, you can read in our previous blog.

Figure 49: Payload fetching

The backdoor still uses the unique Base64-encoded value as a hash for communication with C2. Where “idle” means that the infected machine is in the waiting state for the instructions from the C2 server.

Figure 50: C2 communication via unique hash

How eSentire is Responding

Our TRU combines threat intelligence gained from research and security incidents to create practical outcomes for our customers. We are taking a comprehensive response approach to combat modern cybersecurity threats by deploying countermeasures, such as:

Our detection content is supported by investigation runbooks, ensuring our 24/7 SOC (Security Operations Center) Cyber Analysts respond rapidly to any intrusion attempts related to known malware Tactics, Techniques, and Procedures (TTPs).

In addition, TRU closely monitors the threat landscape, constantly addresses capability gaps, and conducts retroactive threat hunts to assess customer impact.

Recommendations from eSentire’s Threat Response Unit (TRU)

We recommend implementing the following controls to help secure your organization against SolarMarker malware:

While the TTPs used by threat actor(s) grow in sophistication, they lead to a certain level of difficulties, at which critical business decisions must be made. To stop attackers using modern attack techniques and tactics from disrupting your business, you need to actively monitor the threat landscape, develop and deploy endpoint detections, and investigate logs and network data during active intrusions.

eSentire’s TRU is a world-class team of threat researchers who develop new detections enriched by original threat intelligence and leverage new machine learning models that correlate multi-signal data and automate rapid response to advanced threats.

If you are not currently engaged with an MDR provider, eSentire MDR can help you reclaim the advantage and put your business ahead of disruption.

Learn what it means to have an elite team of Threat Hunters and Researchers that works for you. Connect with an eSentire Security Specialist.

Indicators of Compromise

Name

Indicators

SolarPhantom

55419e51ef8a0521f5d7075dbec7bc33

SolarPhantom

f5321b32e719e876feae3b5e4a875377

SolarPhantom

23807082358d736404cfa935fe7c65b5

SolarPhantom

d327494547be8cb70479358517f47b1e

SolarPhantom

ecc294c108e6efe26952b0f1278e6c68

SolarPhantom

6fc09961ed82caa2e23f6efe820ca0cb

SolarPhantom

7984837e254f860a29b7a4d811a25963

SolarPhantom

59f1bbdc298a9c8a39ec393caf6ceef5   

SolarPhantom

9b5c28bfce74a166e764a996f60bef15

SolarPhantom

c37e317293b94c933ebaa6410ba85aaa

SolarPhantom

fea30627a4cdb82aaf9d0d7a47b46115

SolarPhantom

80b2e25abd8a70909cc7b94bec90efc2

SolarPhantom

806bad0e26b540bc31b1d566531b95fa

SolarPhantom

b897995143105e5255500341ae48bc9b

SolarPhantom

9413444e0ed67798d044acdcb2b9a4f8

SolarPhantom

bf55a651364edeb64f2e37ff86a094b8

SolarPhantom

e4d1337fbd8bc461a656ed6405184f5e

SolarPhantom

1adbaaa352a8366c03faaa44fc5d4687

SolarPhantom

e33c50ee3bdb341ae0739c9b0a1093c1

SolarPhantom

fbb0b7d940a7ad6a7187eed00f6870b5

SolarPhantom

6fad60bfc2d7e2b0781618467af045a9

SolarPhantom

653eb0de6c8d12eb40b76b59500a06c2

SolarPhantom

38cbe65f8d2221a6c1b32abd4c96206d

SolarPhantom

50b9e707bd2c1adff933a688ee862463

SolarPhantom

b62aa5869c43fbd9995aed9ec33ce41b

SolarPhantom

7d8c0e47d88dc6dbfa82793803a2bcf5

SolarPhantom

b3447a648b588d2fc40cdd5b3eb7542e

SolarPhantom

afecc46a346af09f5a9b4c7739986a8d

SolarPhantom

0700af859d2379420774145592f8862e

SolarPhantom

1a5e7b4cbe34ee385225da8715562f5d

SolarPhantom

848af416d94bb62257df869c54e1c13f

SolarPhantom

7d21a0c42e51f0fa9324cde55252be27

SolarPhantom

ee6b67ed7b062cd1a34bcee528b574dd

SolarPhantom

682e79264e8e7bde1e224a3c13492d50

SolarPhantom

dd77de2a71c6cd1420d44f2bce14ad54

SolarPhantom

fc0703b4c5f4baa2b9d280351eb8e875

SolarPhantom

c892e60fce05e971c6d9c9c011628af3

SolarPhantom

650c2a72a67d015f503235b238097846

SolarPhantom

846efcf0cd6d8dde1e94686dd2b99974

SolarPhantom

658e82033f0028534ad949e51386fe24

SolarPhantom

9d53aab0fd0e50601df06ce3a1131f89

SolarPhantom

4d2c06e92bab48ecfb74f95c34033646

First stage payload

3fd9d81c06743c2eaffce6995ff1e46c

First stage payload

718043093637a580cc83f79b0bb900ad

First stage payload

3fd9d81c06743c2eaffce6995ff1e46c

First stage payload

4f30d09758e9b05e4df6455096e0c835

First stage payload

3fd9d81c06743c2eaffce6995ff1e46c

First stage payload

95cf157fc18f9d1b18cb3d7bdf5a20d4

First stage payload

7ad2a4620cf1187d8c14c12dcb3e7628

StellarInjector

ca229e08ac6a0ace70d2224ea6c5d416

PowerShell payload

0d228332f3b4f45953ab68370c590ace

C2

146.70.86[.]142

C2

146.70.169[.]170

C2

23.29.115[.]186

MITRE ATT&CK

MITRE ATT&CK Tactic

ID

MITRE ATT&CK Technique

Description

Initial Access

T1189

Drive-by Compromise

SolarMarker is delivered via malicious websites hosting the payload disguised as a document file (PDF, DOC, XLS, PPT)

User Execution

T1204.002

Malicious File

The user launches the malicious file

Data Staged

T1074

Credentials from Password Stores

Credentials from Password Stores: Credentials from Web Browsers

SolarMarker performs data staging of sensitive files from browsers, including credentials, cookies and sends them over to C2

Persistence

T1547.001

Boot or Logon Autostart Execution: Registry Run Keys / Startup Folder

Persistence is achieved via the Startup folder

Execution

T1059.001

Command and Scripting Interpreter: PowerShell

SolarMarker utilizes PowerShell to load the payload in memory as well as to retrieve additional payloads from C2

Exfiltration

T1041

Exfiltration Over C2 Channel

SolarMarker payloads are capable of uploading the stolen data to the C2 server

Sigma and Yara

You can find Sigma and Yara rules in the GitHub repository: https://github.com/RussianPanda95/Malware-Rules-IOCs/tree/main/SolarMarker

References

https://www.esentire.com/blog/esentire-threat-intelligence-malware-analysis-solarmarker
https://twitter.com/SquiblydooBlog/status/1660782805687865344?s=20

eSentire Unit
eSentire Threat Response Unit (TRU)

The eSentire Threat Response Unit (TRU) is an industry-leading threat research team committed to helping your organization become more resilient. TRU is an elite team of threat hunters and researchers that supports our 24/7 Security Operations Centers (SOCs), builds threat detection models across the eSentire XDR Cloud Platform, and works as an extension of your security team to continuously improve our Managed Detection and Response service. By providing complete visibility across your attack surface and performing global threat sweeps and proactive hypothesis-driven threat hunts augmented by original threat research, we are laser-focused on defending your organization against known and unknown threats.

Read the Latest from eSentire