Technical Analysis of Code-Signed “Blister” Malware Campaign (Part 2)

Originally published at: https://cloudsek.com/technical-analysis-of-code-signed-blister-malware-campaign-part-2/

The blister is a code-signed malware that drops a malicious DLL file on the victim’s system, which is then executed by the loader via rundll32.exe, resulting in the deployment of a RAT/ C2 beacon, thus allowing unauthorized access to the target system over the internet. Blister Malware campaigns have been active since 15 September 2021.

Part I of CloudSEK’s analysis provides a detailed understanding of how the loader functions. Part 2 will delve into the details of this campaign’s second stage, which is the .dll payload, and its internal working.

Dissecting the Malicious DLL – Blister Malware

As discussed in Part 1, the Blister dropper drops the malicious .dll file in the Temp directory of the user, inside a newly created folder. This malicious .dll then carries out the second stage of the campaign, in which a RAT/ agent is deployed on the system to gain unauthorized access and steal data.

  • The Blister dropper calls the function LaunchColorCpl, which is one of the functions exported by the .dll, via rundll32.exe.
![](upload://rPzAQMLCuA5NDBZcDMfDppGmfdQ.png)

Staging

  • The exported function LaunchColorCpl retrieves the staging code from the resource section of the PE file. This staging code is protected by a simple XOR encoding scheme.
![](upload://xaWBr6fWgqpNiyL76WIn9MRU5uC.png)![](upload://oMGiDn85c097erCOkKigWIpGrAR.png)
  • After the iterative decoding of the staging code, the control is transferred to decoded code in the memory. 
  • The control flow is transferred to the staging code by calling the address in the EAX register.
![](upload://6JwG91Dx2hx26zrAtkMgZubwelz.png)

Anti-Analysis

  • The staging code is heavily obfuscated, and has a logic similar to a spaghetti code, to hinder analysis. All the calls to Windows APIs are obscured and dynamically resolved.
  • The first thing that the staging code does is to make the malware go to sleep by calling the Sleep Windows API. This is a typical strategy used by most malicious codes to bypass security sandboxes and dynamic testing of security products. 
![](upload://wqIxL9DvsYcKGBOGYq0sOM8RLst.png)
  • The hex value “927C0” is passed to kernel32.759F9010 i.e the Sleep function. This value (927C0) translates to “600000” in decimal. Since the Sleep API takes arguments in milliseconds (ms), the 600000 ms get converted to 10 minutes.
  • When the malware resumes from sleep, it fetches the final payload from the resource section of the PE file.
![](upload://tzOsQ8NbkSyDjCNYwLqFBRJZzee.png)

  • In the memory, the protected payload is decoded. The presence of a DOS header, in the payload bytes, confirms that the payload is in PE format and not a shellcode.
![](upload://5tCWufJrr1mmjNPgITrzxsZnFvy.png)
  • An interesting observation from this analysis, is the addition of MZ byte after the decryption process. In the above image, the initial byte is not MZ, rather the MZ byte is later added at the beginning of the payload separately. This behavior is primarily for operational security.
![](upload://9QsSQb4VeNPmPlXb5MULnviSdpV.png)

Process Hollowing

In general, process hollowing allows an attacker to change the content of a legitimate process from genuine code to malicious code before it is executed by carving out the code logic within the target process.

  • After decrypting the final payload, the malware prepares for execution. 
  • This is done by creating a new process to deploy the extracted code and then performing process hollowing to execute the payload in the remote process. The staging code retrieves the Rundll32.exe location from the compromised system. 
![](upload://5vy4xasjRIXiWmOqRdcEaaiMvBM.png)
  • A new process of Rundll32.exe is created via the CreateProcessInternalW API in the suspended state.
![](upload://gOTdgmpM4QAYA46w3lF1piCqNTu.png)
  • The malware uses the following Win32 APIs for process hollowing:
    • ZwUnmapViewOfSection
    • ZwReadVirtualMemory
    • ZwWriteVirtualMemory
    • ZwGetContextThread
    • ZwSetContextThread
    • NtResumeThread
  • ZwWriteVirtualMemory is used to write malicious code into the target process. 
  • To make the thread of the new process point to newly written code, the attacker alters the entry point of the current thread via ZwGetContextThread and ZwSetContextThread
  • These functions are used to perform processor housekeeping activities on the data structure that stores the current context of the running thread. Process hollowing takes advantage of these features to make the process thread run the attacker code.

Step by Step Working of the DLL

  • The staging code allocates a new memory via ZwAllocateVirtualMemory to transfer the previously decrypted final payload.
![](upload://n7E6KBiNtX5y1jlvaAmQ7z0fYBw.png)
  • The payload is then copied to a newly created buffer.. Based on CloudSEK’s testing on the extracted payload, one of the analyzed samples contained the Raccoon stealer as the final stage payload. However, other samples used Cobalt Strike beacon and BitRAT to compromise the target and gain unauthorized access.
![](upload://4qr1aFhL9UqmIpHryeoyNR8a0iH.png)
  • The staging code then injects the code into the newly created remote process i.e Rundll32.exe.
![](upload://7IYr5AHdLvrSeip88jqrSQnc787.png)
  • Later, the memory protections are changed to appropriate ones for the execution of the residing code via NTProtectVirtualMemory.
![](upload://5JOuEmWdo2tGKH8RI4KpARCROOt.png)
  • The thread context is retrieved via ZwGetContextThread API to change the entry point of the thread to execute the payload injected into the remote process.
![](upload://w9qf8CQEUuutP6r4toXMtBrjFz4.png)
  • The ZwSetContextThread is used to modify the thread entry point to that of the newly copied PE file.
![](upload://gOTdgmpM4QAYA46w3lF1piCqNTu.png)
  • At the final stage of process hollowing, the suspended thread of the Rundll32.exe is resumed via NtResumeThread. Then the Rundll32.exe process starts executing the malicious code hollowed into it by the malware.
![](upload://aDjXrVYDEypZIejWMGa49hNii0Q.png)
  • In the clean-up process, the staging code uses NtFreeVirtualMemory to release the allocated memory, which holds the payload assembly, one by one.
![](upload://5vy4xasjRIXiWmOqRdcEaaiMvBM.png)
  • The current process used for staging is terminated via the NtTerminateProcess.
![](upload://slap4PbVizLRSP5P5aZ5BWDzNes.png)

Blister Malware – Maintaining Persistence

  • The Blister malware achieves persistence on the target system by creating an “lnk” file named proamingsGames in the C:\Users\<username>\AppData\Roaming\Microsft\Windows\Start Menu\Startup directory.
  • Whenever the user logs in, explorer.exe executes any file in the Startup folder. As a result, when the user signs into the account, following the boot process, the malware runs as a child process of explorer.exe.
![](upload://2F95W3H097Ixvmz7dtle4LXpJM5.png)
  • The target for the lnk file is set as C:\ProgramData\proamingsGames\proamingsGames.dll,LaunchColorCpl . Here, the malware copies the Rundll32.exe as proamingsGames.exe and the malicious .dll (initially into C:\ProgramData\proamingsGames directory) is dropped in the Temp folder.
![](upload://wPb4asWfwD58lOvy0ZZHgDeTlPO.png)
  • Every time that the system powers up and the user logs in, the lnk file runs a malicious .dll through a renamed instance of Rundll32.exe.

Conclusion

Given that threat actors are actively using valid code-signing certificates in Windows systems, to avoid detection by antivirus software, it is essential for network and endpoint security products to be updated with the malwares’ latest Indicators of Compromise (IoCs). The latest IoCs for the Blister Malware are enumerated in Part 1 of the technical analysis.