Skip to main content

Decoding SmartAssembly 8 obfuscation

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.

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


The sample I'm presenting is not available publicly. However, I found an executable which loads similar malicious DLL on VirusTotal


Popular posts from this blog

Fake PDF converter leading to malicious Electron application through a WebView2 ⤜(ⱺ ʖ̯ⱺ)⤏

In October 2023  neonprimetime user reported on X (I hate this name) a possible new Redline stealer variant masquerading as a PDF converter named PdfConverters.exe (74b6039660be3eda726a4eee209679ba). This sample presents pretty interesting and unusual installation routine so I decided to take a closer look at it. WebView2 application dropper WebView2  allows you to embed web technologies (HTML, CSS, and JavaScript) in your native apps. It has been already proved  this vector could be used in malicious purposes, however it is not popular among attackers. The sample is dropping such application in %TEMP%\.net\PdfConverters directory. It also creates another folder in %TEMP%\PdfConverters.WebView2 which is used as a user data directory by the app. Then it loads the application through msedgewebview2.exe  PdfConverters process tree As already described by Noch Lab on his blog post , the main code of the application is written in C# and resides in app.dll (2e92db69ebdab1e5250985fc08ca87df