千机游戏提供最新游戏下载和手游攻略!

流量一波---远程桌面客户端获取明文账号密码密码明文和密文的区别

发布时间:2024-06-17浏览:5

远程桌面大家都很熟悉,是管理员和黑客们的最爱。

A. 简介

通常,用于登录远程桌面的帐户具有很高的权限,这对红队(攻击者)来说是很大的帮助。通常,当谈到窃取登录凭据时,人们总是关注 LSASS,但操纵 lsass.exe 不仅受到端点保护响应程序的监控,还受到防病毒程序的监控。所以,绕道而行并找到其他不那么严密监控的方式是很自然的。哦,LSASS 通常需要超级权限。

在本文中,我们将向您展示如何编写一个工具,允许您通过 API 挂钩从远程桌面客户端提取明文密码。如果您已经在目标计算机上拥有普通用户权限,并且该用户正在使用远程桌面会话,则此方法允许您无需权限即可从远程桌面提取明文密码。

B.API钩子

简单来说,API Hooking 就是拦截指定程序的函数调用,并将其重定向到另一个函数的过程。这可以通过改写内存中的代码,将目标函数改写为重定向到另一个函数,最后返回到原来的函数执行(这个收尾工作的目的是确保用户的正常功能不受影响)。Windows 中有多种 API Hooking 的方法,但这些方法很复杂,足以写另一篇文章了。

出于教学目的,我们使用微软的 Detours 库,它是开源的,并且兼容 32 位和 64 位程序。其他一些框架,例如 Frida,也有类似的功能。但是,Detours 是最轻量级的,在对中心点进行操作时具有特殊优势。为了展示这个库的强大功能,让我们用它来 hook MessageBox 函数。

在 hook 一个函数之前,我们需要了解两件事:

原函数和钩子函数的指针地址。

为了使挂钩顺利进行,目标函数和挂钩函数应该具有相同数量的变量、相似的参数和调用约定。

在下面的例子中,我们挂钩MessageBox函数调用,然后修改传递给原始函数的参数。

#include "pch.h"
#include 
#include 
#include 
static int(WINAPI * TrueMessageBox)(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType) = MessageBox;
int WINAPI _MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType) {
 return TrueMessageBox(NULL, L"Hooked", L"Hooked", 0);
 }
int main()
{
// Hook MessageBox
DetourRestoreAfterWith();
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)TrueMessageBox, _MessageBox); // Two Arguments DetourTransactionCommit();
MessageBox(NULL, L"We can't be hooked", L"Hello", 0); // Detach Hooked Function
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)TrueMessageBox, _MessageBox); DetourTransactionCommit();
}

运行这个程序的时候,如果不进行hook的话,消息框应该返回“We can't be hooked”。但是我们hook了,所以hook之后消息框返回的内容是这样的:

C. 找到要挂钩的内容

在hook之前,我们需要先定位到我们感兴趣的函数,这些函数的参数对应的数据应该就是我们感兴趣的内容,在我们的例子中,服务器的机器名、IP、用户名和密码就是我们感兴趣的。API Monitor在这个场合确实很强大,它可以让你绑定到指定的进程,记录所有的API调用,并查看所有相关的结果。

为此,我们将 API Monitor 连接到 mstsc.exe 程序并启动一个简单的连接。

现在我们可以开始在 API 监视器中搜索我们在远程桌面连接中输入的用户名。有几个 API 调用包含此字符串,但最有趣的是 CredIsMarshaledCredentialW。

OK,拿着这个函数名去MSDN上找找这个函数的定义,可以看到这个函数只有一个参数,是一个32位的指向unicode字符串的指针(LPCWSTR)。

为了保证钩子函数能拿到正确的数据,我们将mstsc.exe绑定到Windbg,然后在Windbg中在CredIsMarshaledCredentialW处设置一个断点。当使用这个mstsc.exe建立连接并尝试登录时,我们可以发现传递给这个函数的第一个参数就是这个unicode字符串的地址。

以同样的方式,搜索密码字符串,我们可以发现CryptProtectMemory调用包含指向密码字符串的指针。

通过API Monitor我们可以看到CryptProtectMemory位于Crypt32.dll中,但是这是错误的,因为在Win10最新版本中,这个函数是由dpapi.dll导出的。为了保证在这个API调用中能够获取到正确的数据,我们这里使用了Windbg,然后将mstsc.exe绑定到Windbg,并在CryptProtectMemory函数上设置断点。

通过浏览相应内存中的数据,我们可以推断出密码参数是一个指向数据结构的指针。我们感兴趣的信息就在这个数据结构的开头,所以我们不需要解析整个数据结构。与前面的例子不同,本例中对该函数的几次调用并不包含我们要找的信息。但有一种方法可以区分它们,从包含密码字符串长度的前 4 个字节可以看出。我们可以从内存中读取这个长度并进行比较。如果它大于 0x2,则表示此数据结构包含密码字符串。

用同样的方法可以找到SspiPrepareForCredRead的第二个参数,也就是IP地址所在的位置。

D.RdpThief 显示

现在我们知道需要挂钩哪些函数才能提取敏感凭证信息,我们可以以此为基础来实现 RdpThief 的功能。

RdpThief 是一个独立的 DLL,当它被注入到 mstsc.exe 进程中时,会执行 API 钩子函数,提取纯文本账户密码并保存到文件中。该进程需要一个攻击性脚本,记录当前状态,监控多个进程,并在适当的时候将 shellcode 注入 mstsc.exe。可以使用 sRDI 项目将此 DLL 转换为 shellcode。当 RdpThief 启用时,它会每 5 秒读取一次进程列表,搜索 mstsc.exe,并将其注入其中。

有人针对Cobalt Strike平台创建了此攻击脚本,加载此攻击脚本时会激活3个新命令:

rdpthief_enable:启用新的mstsc.exe进程的心跳检查,并在适当的时间注入shellcode

rdpthief_disable:禁用新mstsc进程的心跳检查,并且不撤回注入的DLL

rdpthief_dump:如果可用,则打印提取的账户密码

下面是一个视频展示

热点资讯