When compiling an application in the .NET framework, the source code is being compiled into Common Intermediate Language. Then, at runtime, the CIL code is passed through a Just In Time Compiler which translates it into the machine code. The problem is that the CIL can be very easily decompiled back (using apps like dnSpy, .NET Reflector or IlSpy) to the original source code of the application.
To protect intellectual property and the source code, the applications should be somehow obfuscated. There are multiple tools which can help you with that. One of them is SmartAssembly
SmartAssembly is a commercial .NET obfuscator created by Redgate. As the website says:
... [It] helps protect your application against reverse-engineering or modification, by making it difficult for a third-party to access your source code.
Malware authors take advantage of the .NET framework and its compatibility with Windows environment, however they also need to protect their code to be as successful as possible. SmartAssembly obfuscator is one of their favorites because it's easy to use, convenient and there is a 14-day free trial :) Level of obfuscation depends on the SmartAssembly version and features used by the malware authors.
SmartAssembly sample analysis
Recently a malicious campaign has been observed on LinkedIn, where the attackers were sending fake job offers to the targets. As a result, an executable is delivered to a victim. Once executed, it is dropping and presenting to the user a job description in PDF or DOCX. However, in the background it is loading a malicious DLL file. In this article I will describe the static analysis steps of the DLL file.
Initial determination
SmartAssembly adds some metadata and multiple classes it needs to work properly to the obfuscated application. Tools like PeStudio, Detect It Easy! or Exeinfo PE can identify a file is protected with that tool.
|
PeStudio |
|
Detect It Easy! |
|
Exeinfo PE
Exeinfo PE even suggests that we should use de4dot to deobfuscate the file. However, when you try to do this, de4dot will crash and will not provide any output. |
Source code analysis
I am using dnSpy to decompile the executable and examine the source code.
|
dnSpy main view |
There are some namespaces containing the application logic and multiple SmartAssembly classes. The Entry Point is defined in SDCBundle.Program.Main. The only thing it does is invoking the Go() function from the AppRunHandler class.
|
Go() function |
First thing that brought my attention is the invocation of
CryptService.Init() function. Looks like something which might contain information about encryption methods. However, I really don't like unicode function names so before proceeding I will beautify the code using
SimpleAssemblyExplorer (yes, the tool from 2015 still works quite well).
|
SimpleAssemblyExplorer Deobfuscator |
The deobfuscator was not able to resolve delegations and encoded strings, but at least changed the unicode names of functions and variables.
Inside of the CryptService class there are indeed functions responsible for encrypting and decrypting data with AES. The key for the cipher is defined as:
So all you have to do is to get the value of the CryptService.KEY attribute. Easy, right? Well, that's where the SmartAssembly magic happens because this attribute is obfuscated.
|
Key obfuscation |
Strings decryption
To understand how the obfuscation works I really recommend you to go through
the article written by Jason Reaves. At high level, it loads data from the resources section, decrypts and decompresses it. As a result it generates a table of base64 encoded strings preceded with their length.
In my case the resource also contains the {z} header followed by value 3, which means AES encryption. The key and IV for decrypting the resource are hardcoded in the Unzip function of SimpleZip class.
|
Unzip function |
Jason described how you can decrypt the content using Python, but if you are not so comfortable with scripting there is an easier way - CyberChef. If you are not familiar with it CyberChef is a simple, intuitive web app for carrying out all manner of "cyber" operations within a web browser.
Remember that if you want to process confidential files there, you should run it locally on your machine.
AES Decrypt function in CyberChef does not allow using decimal format of the key and IV so conversion is needed e.g. to base64.
|
AES key conversion |
Using dnSpy the resource can be saved to a file and then uploaded to CyberChef as input. Before decryption routine, the first 4 bytes of the input must be removed ({z} header and the value representing AES). The recipe should look like this:
|
AES Decrypt |
|
AES Decrypt output in hex |
We get another obfuscation layer with the {z} header. This time followed by 01, which is raw inflate. Next three integers describe the size of the input and output buffers so they need to be removed before decompressing as well.
|
Decrypted and decompressed strings
|
As a result, base64 encoded strings have been revealed. Each string is preceded with its length. They can be of course decoded one by one but I think this time creating a simple script would be more effective and beneficial. I leave that as a task for the reader.
|
Decoded strings |
Perfect! The AES key is fZh/DkfzaglWyzRa7ZLyUA==. The decryption routine, which is using this key, is used to load a config stored in the second resource included in the sample.
Final payload decryption
Searching the second resource name reveals that it's being decoded the same way as the strings resource and loaded as another assembly.
|
Assembly resource load |
|
Assembly resource decryption |
The decrypted assembly contains only two additional resources with large base64 encoded strings which can be decrypted using retrieved AES key.
|
Decrypted resource assembly |
c05p1 is a PDF file used as a decoy by the attackers and presented to a victim during execution. The second one (core05) is more interesting. Decrypting it gives us another base64 encoded DLL file.
|
Decrypting core assembly |
This one is the final information stealing logic. Most of the strings are still obfuscated but this time just with another hardcoded AES key, so they are easy to decode.
The goal of the malware is to collect information about the host, web browsing sessions and cookies, taking screenshot etc. Everything it collects is uploaded to a Telegram bot. Full analysis of the sample is a topic for another story, so I will leave it to the reader as the purpose of this article was to show how you can bypass SmartAssembly protections.
|
Final payload
|
|
Final payload decrypted strings |
Remarks
The sample I'm presenting is not available publicly. However, I found an executable which loads similar malicious DLL on
VirusTotal.
Comments
Post a Comment