Often, attackers attempting to compromise the host of an information security specialist create “malicious” PoCs (proof-of-concepts) that not only fulfill their intended function but also contain a hidden payload. Most commonly, such techniques target various IDE tools. These can be categorized into several vectors:
- PreBuild/PostBuild Events
- Design-time target execution
- COM, Type Libraries
More details on these techniques can be found in this article.
Recently, a new interesting technique for exploiting the Visual Studio IDE has emerged. It primarily targets the SUO file (solution user options .suo file). This is a user-specific solution configuration file that stores various settings and presets (window positions, debugging configurations, project settings, etc.). The file is automatically generated when launching or creating any project and resides in the hidden .vs folder located at:
...\.vs\[Project name]\v17\.suoTo understand how this works, let’s examine the contents of Microsoft.VisualStudio.dll:


Here we see that VsToolboxService (which resides directly in the .suo file) is loaded using the LoadOptions function, which internally calls BinaryFormatter.Deserialize. This is where deserialization-related risks arise. Interestingly, Microsoft themselves warn against using such data-handling methods for security reasons — yet they use it within their own product:

As a result, when launching any Visual Studio project (even one containing no code at all), the payload embedded in the .suo file will execute. The file is then overwritten with new user preset settings, which can complicate incident response and attack chain reconstruction unless this behavior is known. A PoC for this technique can be found here.
Catching Malware
To detect and prevent such attacks before they occur, we need to examine the payload in detail. The .suo file uses an OLE structure, with our focus on the VsToolboxService element:

Inside this element, we can find the malicious payload encoded in Base64:

To detect such suspicious files, you can use the following YARA rule:
rule suo_deserialization
{
strings:
$header = { D0 CF 11 E0 A1 B1 1A E1 }
$s = "VsToolboxService" wide
$a1 = "AAEAAAD"
$a2 = "ew0KICAgICckdHl"
$a3 = "yAoFZNmAU3l"
$a4 = "kscDYs0KCcYAAAP"
$a5 = "PFByb3BlcnR5R3J"
$a6 = "PD94bWwgdm"
condition:
$header at 0 and $s and any of ($a*)
}Applying this rule in practice, we identified the following suspicious file on VirusTotal:

At first glance, it appears to be a normal file. However, upon inspection of its contents, we discover the Base64-encoded payload that launches PowerShell and downloads another file before executing it:

This file is malicious and belongs to the Backdoor.MSIL.XWorm family. When analyzed in a sandbox, it establishes persistence via Task Scheduler jobs running every minute:

Additionally, the malware communicates with various Pastebin-like services awaiting commands from attackers (T1102):

To protect yourself from such attacks, we recommend using our YARA rule and regularly cleaning up unnecessary files — including .suo (their absence will not affect your project).
In addition, always conduct code reviews of any content within a project downloaded from untrusted sources. Furthermore, follow the guidance provided in Microsoft’s blog to set up “trusted locations” for Visual Studio IDE.

