msvsmon.exe (the remote debugger monitor) unattended in ‘no authentication’ mode is not safe. As with any debugger,
msvsmon.exe can start a process upon a request from the network. It can help an adversary covertly advance in the network, especially if msvsmon.exe runs under a highly privileged account. It can also be used to access a computer after it has been compromised to keep a backdoor open. Since
msvsmon.exe, a signed Microsoft application, makes it possible to start and manipulate processes, it could be used as a convenient tool to disguise malicious activity.
In this post, we discuss the remote debugging feature and talk about its internals. Inspired by an idea from our teammate Kasif Dekel, we show how msvsmon can be used as a new tool in the red team arsenal and share a tool that can detect insecure instances of
msvsmon.exe running in your organization.
Visual Studio Remote Debugger’s msvsmon.exe
Microsoft Windows SDK ships a remote debugging feature, providing a great way to debug applications deployed on a remote computer. One of the components of the remote debugging solution is the msvsmon executable: the application that runs on the remote computer listening to the network and acting as a local debugger. The role of msvsmon.exe is very similar to Linux gdbserver. The msvsmon tool accepts commands from the Visual Studio instance running on the developer’s computer, handles local debug events and passes them to and from Visual Studio.
However, as with all conveniences, the power of remote debugging comes with security tradeoffs. Leaving the remote debugger listening to the network weakens security. To prevent feature weaponizing, Microsoft added authentication to the monitor (enabled by default) and obfuscated exported function names of a few debugging core components:
While helpful, these measures are not 100% effective. Though the authentication is based on Windows authentication, it’s a bit obscure. In order to make debugging simpler, developers are sometimes minded to turn the authentication off. It is worth mentioning that the authentication also enables encryption of the network traffic between the debugger and the debugee.
How Can msvsmon Compromise Your Security?
There are at least two options for malicious usage of the msvsmon.exe: it can be used as a lateral movement tool and as a backdoor tool.
One option is that after gaining access to a computer in the network, an attacker could scan the network looking for running instances of msvsmon.exe. Once found, the instance can be used to start a LOLBin process to advance in the network.
The second, even more interesting option, is using msvsmon as a remote shell. Since msvsmon is a portable application, it can be planted on a compromised computer and, combined with Mshta, WScript and other LOLBins, provides a great way to execute commands remotely. In this scenario, the code of a malicious script could be passed as an argument providing fileless command execution.
Passing the following arguments to the application on launch can help to hide msvsmon.exe from the user:
/noauth, /anyuser, /nosecuritywarn, /nowowwarn /silent, /timeout:2147483646
Also, since msvsmon is a debugger, it is possible to manipulate the debuggee process via the network, providing the remote actor with full control over the running process, including memory and thread manipulation. Thus, even a legitimate process started by msvsmon could be hollowed and turned evil.
The Importance of SOAP and the Remote Debugger
The debugging server uses SOAP protocol for communication. The server consists of a few instances of msvsmon.exe. One of the instances provides SSDP network discovery to make the debuggee host visible to clients. Other instances host the vsdebugeng.dll library, which contains SOAP server implementation. The vsdebugeng.dll also implements the SOAP client and gets loaded into Visual Studio instances.
Whenever a developer chooses the remote debugging option and hits F10, Visual Studio uses one of vsdebugeng.dll’s name-obfuscated functions to communicate with the debugging server, trigger the debugged process execution and handle debugging events coming from the remote process.
Below is a schema of such a SOAP network flow:
Wireshark view of SOAP requests is quite messy:
Luckily, the SOAP protocol can be logged and viewed in more readable format. Enabling Analytic and Debug logs for WebServices in the EventViewer turns on generation of pretty and straightforward XML logging that is viewable via EventViewer:
To demonstrate the possibility of using the debugging server by third-party software, we researched the protocol and created a custom client that instructs the server to launch and resume a process. The client triggers execution of mshta.exe, which in turn executes JScript code passed as an argument to mshta.exe. It’s actually one step to the real backdoor tool that can be used to control the remote computer.
The debugging protocol turns out to be rather complex. It contains many data structures and implements a lot of SOAP requests. While we did discover some of them, these were merely the tip of the remote debugging iceberg. The server uses quite a few types of SOAP requests, the most important of which send or query information from the server and handle requests (callbacks) coming from it. The most notable stages of process creation are: Initialization, SetConfiguration and Launch. Every stage gets triggered by a SOAP request initiated by the client. Since msvsmon is a debugger, it starts the process with CREATE_SUSPENDED flag on, so the Resume request is needed to let the process go.
How to Protect Against Misuse of the Remote Debugger?
Given the possibilities for misusing and abusing the msvsmon remote debugging component, it is important to consider how to harden the security of a developer’s network.
First of all, do not run the debugging server with the authentication off. It is possible to create a simple authentication setup by adding remote administrative user’s credentials to the local credential store (Windows credential manager was first introduced in Windows Vista). The Windows credential manager stores credentials for websites, applications and network connections and is very useful for remote debugging. For example, if the target computer name is ‘DEBUGGEE’ and the administrative user is ‘dbg’, adding DEBUGGEEdbg entry along with the password to the Credential manager should do the job. More details on Credential manager API can be found here.
Next, in Visual Studio set the ‘Connection’ property of the debugging configuration to ‘Remote with Windows authentication’ and run the debugging server on the target computer. Now, authenticated debugging is ready.
How to Scan for Insecure Debugging Servers
In order to help find insecure debugging servers in the network, we have released a scanner that broadcasts SOAP probe requests to all adapters in the OS and handles replies from running debugging servers. By default, msvsmon.exe uses the standard WebServices discovery port: UDP:3702. (More on debugger port assignments in this article). Msvsmon.exe replies to probe requests with the configuration descriptor, which amongst other settings contains the authentication level. An example of the output of the script is shown below:
The ability to remotely debug an application running on another machine is a useful feature for developers. However, as we’ve pointed out in this post, the msvsmon component of Visual Studio’s remote debugger has security implications that organizations need to be aware of. We hope that this post will help increase awareness of these implications and that the scanner we have developed and made freely available will be of use to security teams looking to harden their network against this kind of potential misuse by malicious actors.