In today’s edition, we’ll cover two techniques: Remote service creation over RPC and SharpRDP.
Remote service creation over RPC
Windows services can be used as a means of persistence in an environment, and can be created in multiple ways, one of which is remotely. Doing so often involves this service creation will be executed over RPC.
In this article Jonny Johnson explains the inner workings of RPC and points to some detection opportunities for this specific technique. One of them is for the situation where a registry key is created on the system through the Service Control Manager. This is also visible on one of our favorite reference websites for Windows processes, the Strontic Xcyclopedia.
A sample command to remotely create a service would be:
sc.exe \\rainbow-room create WeDoHaveAChoice binpath="C:\windows\system32\choice.exe"
Executing a command against a remote system like the one above will cause the originating system to initiate a connection to the target system through a Remote Procedure Call (RPC) on a high TCP port to the services.exe process. In its turn services.exe will process the command and proceed to create the required registry keys allowing the service to be loaded.
The provided detection is looking at established incoming connections towards the services.exe process. This event is then joined by the creation of a registry key that is loaded on boot. To make it clear, changing the registry key does not load the service immediately, it will be on the next boot when it takes effect.
Depending on how your IT organization is set up it might require filtering the IP addresses of the maintenance servers/jump hosts, a simple “|summarize count() by RemoteIP” will help you find them quite quickly.
You can find the query here on GitHub.
Blue: Keep in mind that a service creation can also be executed locally; in that case monitor for odd processes writing to the Services registry hive. This can be either in the CurrentControlSet\Services or ControlSet001\Services hive.
They are technically the same location, the CurrentControlSet is a pointer to the ControlSet001 or in some cases ControlSet002, the last known good configuration. A sample query that could be used as a start for a hunt would be:
DeviceRegistryEvents| where (RegistryKey contains @"\System\CurrentControlSet\Services" or RegistryKey contains @"\System\ControlSet001\Services") and ActionType =="RegistryKeyCreated"// Filter trusted processes| where not(InitiatingProcessFolderPath has_any (@"c:\windows\system32",@"c:\windows\winsxs",@"c:\windows\syswow64",@"c:\programdata\microsoft\windows defender\platform\",@"c:\program files\windows defender advanced threat protection\mssense.exe"))// Filter other AVs (if present, make sure to remove if you don't have them)| where not(InitiatingProcessFolderPath has_any (@"c:\program files (x86)\trend micro\security agent",@"c:\program files\common files\mcafee",@"c:\program files (x86)\symantec\symantec endpoint protection"))| summarize count() by InitiatingProcessFolderPath, RegistryKey
The Remote Desktop Protocol (RDP) allows someone to access the desktop of a system remotely and work with it interactively. However, depending on the access an adversary has on your environment, this may be more or less viable as a lateral movement technique, since real-time manual interaction is required.
SharpRDP tries to remediate this by allowing attackers to perform remote command execution through RDP without the need to have real-time manual interaction by simulating keystrokes on the target system. This allows an attacker to (asynchronously) run a binary on an already compromised system, which in turn will connect to the target system and execute a set of keystrokes.
Essentially you can compare the keystrokes injection to the blind injection you would achieve by using a Ducky or the JackIt keystroke injection attack, with the distinction that, for SharpRDP, you actually need credentials.
For an attacker this method of executing commands can be very useful, especially if he managed to get his hands on a local admin account (not RID500) and you have your ‘LocalAccountTokenFilterPolicy’ set to 0. Using SharpRDP an attacker can execute the (elevated) commands required to change this registry key, disabling the security features which prevent elevated access by such accounts through network logons like SMB or WMI.
You can find the query here on GitHub
Blue: SharpRDP basically has no legitimate use case. Therefore it would be great to be able to detect it. However, as it uses the regular RDP libraries, this is quite difficult. The only tell-tale sign from a connection perspective is the default resolution of 200x200 that is being used by SharpRDP. Additionally, you could monitor for very short RDP connections, in particular the ones of under a minute of duration.
Lastly, you could monitor for the behavior that SharpRDP exhibits on the target system. The most relevant is leveraging taskmgr.exe to gain elevated execution, which means that taskmgr.exe is creating unexpected child processes. However, this will not catch slightly more advanced adversaries which do not simply run the standard tool. You could include the filter to look at taskmgr.exe being launched without command line parameters — which is the default behavior of SharpRDP. Unfortunately, this is relatively simple to change as an attacker. During our testing the provided detection without the additional filter was already providing a small number of detections.
At this point you might wonder what the command line parameters are doing. As far as we could dig up there is no clear documentation on this. What we did see is that there is a difference in the way task manager is launched from a command line perspective. See below for details how the various ways the Task Manager is launched shows its different command line arguments.
- Right-click the taskbar, and click Start Task Manager.
- Press Ctrl+Shift+Esc.
- Press Ctrl+Alt+Del, and click Start Task Manager.
- Start a non-elevated Task Manager, and click the Show processes from all users button.
Red: It is fairly trivial to change the characteristics of SharpRDP. For example by explicitly setting a more realistic requested resolution, expanding the connection time or changing the way it achieves code-execution.