In this post, I will provide an in-depth technical analysis of Dark Crystal RAT, a backdoor written in C#.
File Metadata
Malware sample
: hereMD5
: b478d340a787b85e086cc951d0696cb1SHA256
: 8d41d5131fac719cc11823fb57bef9ef1ea063dbb8f52b235a3948bece039d95SHA1
: 563d9f1b35b4898d16aff1dccd8969299f7ab8b7File Size
: 1.2 MBCRC32
: 4a1ebf06
Sandbox Analysis
Running the application in any.run gives us the following process graph.
The original executable drops two executables mnb.exe
and dal.exe
. Subsequently, mnb.exe
drops three executables fsdffc.exe
,dfsds.exe
and daaca.exe
. According to the process graph, dfsds.exe
seems to do some interesting stuff so let’s reverse it first.
Deobfuscation and Detecting Persistence
1 | ➜ darkcrystal file dfsds.exe |
So, this is a .NET executable. Loading it into DnSpy, a .NET decompiler and decompiling the Main function, we get the following output.
We see that there are multiple calls to the function ExporterServerManager.InstantiateIndexer
with different arguments which is clearly a sign of obfuscation. Let’s try to deobfuscate this executable using de4dot.
So, de4dot successfully decompiled it. Let’s decompile the deobfuscated binary dfsds-cleaned.exe
.
As soon as we decompile the Main()
method, we notice a giant base64 string. Let’s decode it and see what’s there in it.
1 | ➜ dcr echo TUhvc3Q6aHR0cDovL2RvbWFsby5vbmxpbmUva3NlemJseGx2b3Uza2NtYnE4bDdoZjNmNGN5NXhnZW80dWRsYTkxZHVldTNxYTU0LzQ2a3FianZ5a2x1bnAxejU2dHh6a2hlbjdnamNpM2N5eDhnZ2twdHgyNWk3NG1vNm15cXB4OWtsdnYzL2FrY2lpMjM5bXl6b24weHdqbHhxbm4zYjM0dyxCSG9zdDpodHRwOi8vZG9tYWxvLm9ubGluZS9rc2V6Ymx4bHZvdTNrY21icThsN2hmM2Y0Y3k1eGdlbzR1ZGxhOTFkdWV1M3FhNTQvNDZrcWJqdnlrbHVucDF6NTZ0eHpraGVuN2dqY2kzY3l4OGdna3B0eDI1aTc0bW82bXlxcHg5a2x2djMvYWtjaWkyMzlteXpvbjB4d2pseHFubjNiMzR3LE1YOkRDUl9NVVRFWC13TGNzOG8xTlZFVXRYeEo5bjl5ZixUQUc6VU5ERUY= | base64 -d |
This gives us the configuration that the malware might be using. Reversing it further, we see a function SchemaServerManager.StopCustomer
that returns a random process name. We can change its name to something meaningful such as GetRandomProcess
.
1 | public static string StopCustomer() |
It copies the executable into the folder containing application data (%APPDATA%
) and saves it with its name as the random process name generated earlier. After that it checks whether the file %APPDATA%\dotNET.lnk
exists or not. If it exists, it deletes it otherwise it calls a function SchemaServerManager.PublishCustomer
with the first argument as %APPDATA%\dotNET.lnk
and the second argument as %APPDATA%\randomProcess.exe
where randomProcess
is the process name generated earlier. This function creates a shortcut dotNET.lnk
for %APPDATA%\randomProcess.exe
. After that, it copies the shortcut into the startup folder. Any programs placed inside the startup folder are automatically run when the device starts. It opens the registry key HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
and saves the value %APPDATA%\dotNET.lnk
into the registry key with the name scrss
. Run
is a special registry key that makes the programs listed into it run whenever the user logs in. Once again, it generates a new, random process name and checks whether a file with this name is present in the C drive or not. It also checks for the existence of the existence of the file Sysdll32.lnk
in the startup folder and the C drive.
1 | if (!File.Exists("C:\\" + randomProcess + ".exe") && (!File.Exists(Environment.GetFolderPath(Environment.SpecialFolder.Startup) + "\\Sysdll32.lnk") || !File.Exists("C:\\Sysdll32.lnk"))) |
If the result of these conditions comes False, it copies the executable into C drive with its name as <randomProcess>.exe
, creates a shortcut C:\\Sysdll32.lnk
, copies it to the startup folder, creates a registry value HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run\Wininit
pointing to C:\\Sysdll32.lnk
.
All these steps were done to ensure persistence by running the executable at system startup and user-logon. After that, it starts a new process.
1 | try |
If the process successfully starts, the current application is terminated and the new process continues its execution. Further, it creates more files, shortcuts and more registry values. All the shortcuts and registry values created by it are:
Copies of the executable
1 | C:\Users\<username>\AppData\Roaming\<randomProcess>.exe |
Shortcuts
1 | C:\Users\<username>\AppData\Roaming\dotNET.lnk |
Registry Values
1 | HKCU\Software\Microsoft\Windows\CurrentVersion\Run\scrss -> C:\Users\<username>\AppData\Roaming\dotNET.lnk |
Detecting multiple instances
After all these steps, the malware sleeps for a random time interval between 5 and 7 seconds, creates and md5 hash of the base64 encoded configuration string we found earlier.
1 | private static bool CreateCustomer(string config) |
Here, the value of config is bc2dc004028c4f0303f5e49984983352
. If another instance of the malware is already running, this function returns false and the process exits.