Technical Analysis of BlueSky Ransomware

CloudSEK BlueSky Ransomware

Author: Anandeshwar Unnikrishnan
Co-author: Aastha Mittal

Category:

Malware Intelligence

Type/Family:

Ransomware

Industry:

Multiple

Region:

Global

What is BlueSky Ransomware?

BlueSky Ransomware is a modern malware using advanced techniques to evade security defences. It predominantly targets Windows hosts and utilizes the Windows multithreading model for fast encryption. It first emerged in late June 2022 and has been observed to spread via phishing emails, phishing websites, and trojanized downloads.

This deep-dive analysis of BlueSky Ransomware covers the following technical aspects:

  • Procedure for privilege escalation
  • Persistence
  • Encryption mechanism
  • Evasion techniques

Initial Phase

  • The modules required for the ransomware are dynamically loaded and addresses of interesting functions are stored in an array for later use.
  • The addresses of the following list of APIs are resolved:
APIs Stored
ntdll.RtlAllocateHeap kernel32.CreateFileW kernel32.SetFilePointer kernel32.CloseHandle kernel32.lstCmpW advapi32.CryptGenRandom
ntdll.FreeHeap kernel32.FindClose kernel32.GetFileSizeEx kernel32.SetFileAttributesW kernel32.OpenProcess shlwapi.PathCombineW
kernel32.FindFirstFileExW kernel32.ReadFile kernel32.GetQueuedCompletionStatus kernel32.MoveFileWithProgress kernel32.TerminateProcess shlwapi.PathRemoveExtensionW
kernel32.FindNextFileW kernel32.WriteFile kernel32.PostQueuedCompletionStatus kernel32.lstrCatW kernel32.WaitForSingleObject
  • After loading the required libraries, the ransomware proceeds to perform the following tasks:
    • Checks that the running process is 32 bit via kernel32.IsWow64Process
    • Decrypts strings
    • Adjust the privilege of the process to SE_DEBUG via ntdll.RtlAdjustPrivilege
    • Retrieves the following:
      • MachineGUID from SOFTWARE\\Microsoft\\Cryptography
      • DigitalProductID and InstallDate from SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion
    • Hides the main thread from debugger by calling ntdll.ZwSetInformationThread by passing ThreadHideFromDebugger (0x11) as ThreadInformationClass
  • The ransomware updates the status as “Completed” after the initial phase and the user data is locked.
Locking of user data after initial phase
Locking of user data after initial phase

 

Mutex Generation

The ransomware creates a global mutex by calling kernel32.CreateMutexA API.

Mutex Creation
Mutex Creation

 

String Decoding

The ransomware decodes all the strings at runtime. Listed below are various extensions avoided while locking, user data extensions locked, and directory names for file enumeration.

Blacklisted Extensions

The ransomware leaves the files with the following blacklisted extensions from locking.

Blacklisted Extensions
“ldf” “icl” “bin” “spl” “diagcab” “ini” “theme” “hta”
“scr” “386” “hlp” “ps1” “ico” “icns” “rtp” “diagpkg”
“icl” “cmd” “shs” “msu” “lock” “prf” “msc” “rtp”
“386” “ani” “drv” “ics” “ocx” “dll” “sys” “msstyles”
“cmd” “adv” “wpx” “key” “mpa” “bluesky” “mod” “cab”
“ani” “theme” “bat” “msp” “cur” “nomedia” “msi” “nls”
“adv” “msi” “rom” “com” “cpl” “idx” “diagcfg” “exe”
“lnk”

User Data Extensions

The files with the following user data extensions are specifically targeted.

User Data Extensions
“ckp” “dbs” “mrg” “qry” “wdb” “sqlite3” “dbc”
“dwg” “dbt” “mwb” “sdb” “db” “sqlitedb” “mdf”
“db3” “dbv” “myd” “sql” “sqlite” “db-shm” “dacpac”
“dbf” “frm” “ndf” “tmd” “accdb” “db-wal”

Directory Names

The ransomware uses these directory names for file enumeration purpose.

Directory Names
“$recycle.bin” “boot” “windows” “perflogs” “appdata”
“program files” “windows.old” “all users” ” users” “programdata”
“$windows.~ws” “system volume information” “$windows.~bt” “program files (x86)”

Pre-Encryption

Cryptographic Algorithm

Cryptographic context is a type of additional authenticated data consisting of non-secret arbitrary name-value pairs. During the initialization phase, the ransomware acquires cryptographic context from advapi32.CryptAcquireContext API. The cryptographic provider used by the malware is “Microsoft Enhanced Cryptographic Provider v1.0” and the encryption scheme selected is RSA.

Acquiring cryptographic context
Acquiring cryptographic context

Recovery Data

Before the execution of the encryption function, the ransomware writes data needed for the recovery of the locked files in the registry. The following data is written:

  • RECOVERY BLOB
  • X25519 public key
Writing data needed for recovery of locked files
Writing data needed for recovery of locked files

 

Updated view of the registry
Updated view of the registry

 

Ransom Note

If writing the decryption data fails, the ransomware will not execute the routine responsible for the encryption of user data. After a successful registry operation, the ransomware generates a ransom note as the initial task in the function that performs the locking.

Ransom note generation
Ransom note generation

 

The following steps are performed:

  • A random and unique recovery ID for the victim is generated and stored in the heap buffer.
  • The Bluesky ransomware creates ransom note in “.txt” and “.html” formats.
  • Two blocks of 1000 (4096) bytes of heap memory are allocated to hold the final ransom notes.
  • Two temporary buffers (txt_ransom_note_buffer and html_ransom_note_buffer) are allocated to hold encoded notes retrieved from the binary.
  • A place format string specifier is used as a placeholder for the recovery ID generated in the initial step.
  • The function “sub_2866E0” is responsible for formatting the note by replacing the “%s” with the recovery ID value which is 242 characters long.
  • The result is then stored in memory, to be later used by the function responsible for writing the note to the filesystem.
Decoded note in the buffer
Decoded note in the buffer

Process Termination

After creating the ransom note, the ransomware enumerates the processes running on the compromised system. The ntdll.ZwQuerySystemInformation API is called by passing the SystemInformation class (0x5) to get the process list from the system. The list is used by the ransomware to selectively kill the processes.

Enumeration of processes running on the compromised system
Enumeration of processes running on the compromised system

 

Process Termination Task
Process Termination Task

 

The following steps are performed to terminate the running processes:

  • The ransomware starts to analyze the process structure to retrieve the image name and uses shlwapi.PathRemoveExtensionW API to remove the extension (.exe) from the name.
  • Once the name of the process without extension is retrieved, the ransomware calls sub_2869B0 to calculate the size of the process name.
  • Next a call is made to sub_2868C0 to convert the characters to lowercase for uniformity.
  • Finally, a custom byte encoding is used to convert the string to a hex value.
  • The generated hex value is checked against an array of encoded values of processes to be terminated.
Process names the threat actor wants to terminate
Process names the threat actor wants to terminate

 

  • At the initial phase the handle to “Shell_Traywnd”, which is obtained using user32.FindWindowA, is passed to the GetWindowThreadProcessId API in order to get the process ID of explorer.exe. (explorer.exe is responsible for creating “Shell_Traywnd”). The process ID is stored in the memory.
  • If there is a match, the target process ID, obtained at the initial phase, is passed to sub_2910F0.
  • The malware checks if the process ID is of its own process or of explorer.exe. After the check, a handle to process is retrieved via kernel32.OpenProcess API.
  • Only “non-critical” processes are terminated to prevent bug check (Blue Screen of Death). If the passed process handle is not critical, it is terminated via kernel32.TerminateProcess.
The function sub_2910F0
The function sub_2910F0

 

  • The ransomware calls ntdll.NtQueryInformationProcess by passing ProcessBreakOnTermination (0x1d) as the InformationClass to identify critical processes.
Call to NtQueryInformationProcess Class
Call to NtQueryInformationProcess Class

 

Empty Recycle Bin

Following the process termination, the ransomware empties the recycle bin by calling shell32.SHEmptyRecycleBinA.

Emptying the recycle bin
Emptying the recycle bin

 

Encryption

Threading Model: Windows IO Completion Ports in Nutshell

  • The Bluesky ransomware performs the encryption by utilizing IO completion ports. I/O completion ports provide an efficient threading model for processing multiple asynchronous input-output (I/O) requests on a multiprocessor system.
Threading model using the IO ports
Threading model using the IO ports

 

  • The main thread creates the IO completion port via CreateIOCompletionPort. The created port can be associated with many file handles. When the asynchronous IO operation on one of the file handles is completed, an IO completion packet is queued in FIFO order to the associated port.
  • The worker thread performs a call to PostQueuedCompletionStatus to enqueue the associated data. In the case of ransomware, the data will be the absolute path of the user files waiting in the queue to get encrypted.
  • Another worker thread performs GetQueuedCompletionStatus to dequeue the contents from the main queue. Usually, in ransomware, this thread is responsible for performing encryption and ransom note generation.
  • The following section contains an depth description of each of the above-mentioned functions.

CreateIOCompletionPort

The call to CreateIOCompletionPort involves the following steps:

  • The main thread retrieves the processor count from the PEB (Process Environment Block) structure.
  • A call to CreateIoCompletionPort is made by passing processor count as NumberOfConcurrentThreads parameter value.
  • Multiple worker threads are created by calling kernel32.CreateThread.
  • For each thread, an affinity mask (a bit mask indicating what processor a thread should run on) is set by calling kernel32.SetThreadAffinityMask.
  • The main thread performs basic drive enumeration and calls PostQueuedCompletionStatus.
Calling CreatIoCompletionPort
Calling CreatIoCompletionPort

 

Retrieving processor count from PEB
Retrieving processor count from PEB

 

PostQueuedCompletionStatus Function
PostQueuedCompletionStatus Function

 

Following APIs are used for drive enumeration on the system:

  • kernel32.GetLogicalDriveStringsW
  • kernel32.GetDriveTypeW

Further enumeration of files is performed by creating worker thread for PostQueuedCompletionStatus.

Creation of worker thread for PostQueuedCompletionStatus
Creation of worker thread for PostQueuedCompletionStatus

 

The main thread calls mpr.WNetOpenEnumW for enumerating network resources and creates a worker thread same as above that performs the PostQueuedCompletionStatus call.

Calling mpr.WNetOpenEnumW function
Calling mpr.WNetOpenEnumW function

 

Worker Thread: PostQueuedCompletionStatus

The worker thread that performs the PostQueuedCompletionStatus
The worker thread that performs the PostQueuedCompletionStatus

 

The newly created thread for PostQueuedCompletionStatus leads to the following:

  • The files are enumerated via kernel32.FindFirstFileExW and kernel32.FindNextFileW.
  • If it is a directory, the thread function is recursively called to perform the file enumeration.
  • If it is a user file, then the absolute path is enqueued to the completion queue via PostQueuedCompletionStatus call.
  • This worker thread is responsible for gathering the files for encryption.

Worker Thread: GetQueuedCompletionStatus

This worker thread is responsible for doing the actual locking of the user files. The ransomware hides this thread from the debugger via ntdll.ZwSetInformationThread by passing ThreadHideFromDebugger as the ThreadInformationClass.

Calling ntdll.ZwSetInformationThread function
Calling ntdll.ZwSetInformationThread function

 

The thread decodes the file extension “.bluesky” and proceeds to perform the encryption. The kernel32.GetQueuedCompletionStatus is called in an infinite loop to retrieve the absolute path of the user data.

Decoding file extension “.bluesky”
Decoding file extension “.bluesky”

 

The sub_288780 function is responsible for encrypting the data. The thread checks if the dequeued item is a directory or a file.

  • If it is a file then it proceeds to encrypt the data by using the following APIs:
    • kernel32.CreateFileW
    • kernel32.SetFilePointer
    • kernel32.ReadFile
    • kernel32.WriteFile
  • If the item is a directory then sub_28EDA0 is executed to dump the ransom note. The file name strings are decoded dynamically.
File name strings being decoded
File name strings being decoded

 

Execution of sub_28EDA0
Execution of sub_28EDA0

 

The note content generated by the ransomware is written on the disk by calling:

  • kernel32.CreateFileW
  • kernel32.WriteFile
Ransom note being written on the disk
Ransom note being written on the disk

Post Encryption

Once the user data is successfully locked, the ransomware performs the following operations:

  • Releases the mutex created at the initial phase
  • Sets the thread state to ES_Continous
  • Destroys the allocated heap
  • Exits the process via kernel32.ExitProcess
Post encryption functions
Post encryption functions

 

Indicators of Compromise(IoCs)

MD5
961fa85207cdc4ef86a076bbff07a409
53c95a43491832f50e96327c1d23da40
5ef5cf7dd67af3650824cbc49ffa9999
efec04688a493077cea9786243c25656
d8a44d2ed34b5fee7c8e24d998f805d9
848974fba78de7f3f3a0bbec7dd502d4

Appendix

Ransom Note in .txt format
Ransom Note in .txt format

 

Ransom Note in .html format
Ransom Note in .html format

 

Anandeshwar Unnikrishnan
Threat Intelligence Researcher , CloudSEK
Anandeshwar is a Threat Intelligence Researcher at CloudSEK. He is a strong advocate of offensive cybersecurity. He is fuelled by his passion for cyber threats in a global context. He dedicates much of his time on Try Hack Me/ Hack The Box/ Offensive Security Playground. He believes that “a strong mind starts with a strong body.” When he is not gymming, he finds time to nurture his passion for teaching. He also likes to travel and experience new cultures.
This is Alt
Total Posts: 0
Technical Writer at CloudSEK
×
Anandeshwar Unnikrishnan
Threat Intelligence Researcher , CloudSEK
Anandeshwar is a Threat Intelligence Researcher at CloudSEK. He is a strong advocate of offensive cybersecurity. He is fuelled by his passion for cyber threats in a global context. He dedicates much of his time on Try Hack Me/ Hack The Box/ Offensive Security Playground. He believes that “a strong mind starts with a strong body.” When he is not gymming, he finds time to nurture his passion for teaching. He also likes to travel and experience new cultures.
Latest Posts
  • Redline Stealer _ ClouDSEK
  • CloudSEK BlueSky Ransomware
  • Technical Analysis of MedusaLocker Ransomware
  • Recordbreaker: The Resurgence of Raccoon