渗透技巧 —— 从远程桌面客户端提取明文凭据

发布于 2024-10-26 07:30:16 字数 7005 浏览 2 评论 0

0x00 前言

在实际的渗透过程中,如果发现了远程桌面连接的历史记录,那么下一步就需要想办法获取远程桌面连接使用的口令。

本文将会结合 RdpThief 介绍从远程桌面客户端提取明文凭据的方法,分享需要注意的细节。

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

0x01 简介

本文将要介绍以下内容:

  • 获取远程桌面连接口令的思路
  • 使用 Detours 库 hook 系统 API 的方法
  • 使用 API monitor 监控系统 API 调用的方法
  • 使用 RdpThief 从远程桌面客户端提取明文凭据

0x02 获取远程桌面连接口令的思路

通常有以下两种:

1.使用键盘记录程序,记录 mstsc.exe 在启动过程中用户输入的口令

2.在 mstsc.exe 启动时,读取 mstsc.exe 的内存数据,提取出用户输入的口令

RdpThief 是第二种实现思路,使用 Detours 库 hook 系统 API,使用 API monitor 监控系统的 API 调用,找到 mstsc.exe 在内存中存储明文口令的位置,代码简洁有效。

0x03 使用 Detours 库 hook 系统 API 的方法

RdpThief 在实现上使用 Detours 库来 hook 系统 API,所以这里简要介绍一下 Detours 库的用法

Detours 库用于监视和检测 Windows 上的 API 调用,可以用来 hook 系统 API

这里介绍使用 Detours 库 hook 系统 API 的两种方法

1.编译 Detours 源码并使用

(1) 编译 Detours 源码

下载 Detours 源码,地址如下:https://github.com/Microsoft/Detours

使用 Visual Studio 编译 Detours 源码(这里以 VS2015 为例),需要区分 32 位和 64 位

64 位编译:

打开 VS2015 x64 本机工具命令提示符

执行以下命令:

cd Detours-master\src
nmake

命令执行后将在文件夹 Detours-master 下生成以下三个文件夹,包括 Detours 的头文件和库文件

  • bin.X64
  • include
  • lib.X64

32 位编译:

打开 VS2015 本机工具命令提示符

执行以下命令:

cd Detours-master\src
nmake

命令执行后将在文件夹 Detours-master 下生成以下三个文件夹,包括 Detours 的头文件和库文件

  • bin.X86
  • include
  • lib.X86

(2) 导入 Detours

在新建的 C++工程中添加对应版本的头文件:

  • detours.h
  • detours.lib

代码如下:

#include "detours.h"
#pragma comment (lib,"detours.lib")

2.通过 Install-Package 自动安装

(1) 安装

在 Visual Studio 中选择 工具 - >NuGet 包管理器 -> 程序包管理器控制台

输入安装命令:

Install-Package Detours

将会自动安装 Detours 库,如下图

Alt text

(2) 导入 Detours

代码如下:

#include <detours.h>
#pragma comment (lib,"detours.lib")

使用 Detours 库 hook 系统 API 时常用的几个函数:

  • DetourTransactionBegin();
  • DetourUpdateThread(GetCurrentThread());
  • DetourAttach();
  • DetourDetach();
  • DetourTransactionCommit()

Hook 系统 API Messagebox() 的实例代码如下:

#include <Windows.h>
#include <detours.h>
#pragma comment (lib,"detours.lib")
static int(WINAPI *TrueMessageBox)(HWND, LPCTSTR, LPCTSTR, UINT) = MessageBox;
int WINAPI OurMessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType) {
    return TrueMessageBox(NULL, L"Hooked", lpCaption, 0);
}
int main()
{
    DetourTransactionBegin();
    DetourUpdateThread(GetCurrentThread());
    DetourAttach(&(PVOID&)TrueMessageBox, OurMessageBox);
    DetourTransactionCommit();
    MessageBox(NULL, L"Hello", L"Hello", 0);
    DetourTransactionBegin();
    DetourUpdateThread(GetCurrentThread());
    DetourDetach(&(PVOID&)TrueMessageBox, OurMessageBox); 
    DetourTransactionCommit();
}

0x04 使用 API monitor 监控系统 API 调用的方法

RdpThief 使用 API monitor 监控系统的 API 调用,找到 mstsc.exe 在内存中存储明文口令的位置,这里简要介绍一下 API monitor 的用法

API monitor 的下载地址:http://www.rohitab.com/downloads

运行后需要选择进行监控的模块,如下图

Alt text

接着选择需要监控的进程,如下图

Alt text

API monitor 将会监控进程运行时调用的 API,如下图

Alt text

0x05 RdpThief 测试

介绍 RdpThief 细节的文章:https://www.mdsec.co.uk/2019/11/rdpthief-extracting-clear-text-credentials-from-remote-desktop-clients/

RdpThief 的代码里包括三部分内容:

1.C++工程,编译生成 dll

编译生成的 dll,需要注入到 mstsc.exe 进程中

这里可以使用我之前写的 dll 注入的代码,地址如下:https://github.com/3gstudent/Homework-of-C-Language/blob/master/NtCreateThreadEx%20%2B%20LdrLoadDll.cpp

但是需要把 FreeDll() 的功能去掉,dll 需要一直在进程 mstsc.exe 的内存中,用来记录用户输入的口令

2.RdpThief_x64.tmp

shellcode 格式的 dll,作者使用 sRDI 将编译好的 dll 转换为 shellcode 格式,便于 cna 脚本的调用

3.RdpThief.cna

Colbalt Strike 使用的 cna 脚本,用于注入 shellcode 格式的 dll

支持三个命令:

  • rdpthief_enable,每 5 秒搜索 mstsc.exe 并将 dll 注入
  • rdpthief_disable,停止 rdpthief_enable,但不会卸载注入的 dll
  • rdpthief_dump,显示抓取的凭据,默认读取路径为 %temp%\data.bin

实际测试

预期功能:

在 mstsc.exe 中输入用户名口令后,无论是否正确,都会被记录在文件 %temp%\data.bin

  1. 在 Win10 下没有问题
  2. 在 Win7 下能够获得输入的用户名和口令,但无法获得 Server 名称

查找问题原因:

RdpThief 在实现上通过捕获 API SspiPrepareForCredRead() 获得 Server 名称

在 Win7 系统下,我使用 API monitor 监控系统调用的 API,发现不存在这个 API,如下图

Alt text

找到问题的原因

解决方法 1:

通过搜索,发现 API CredReadW() 能够记录 Server 名称,如下图

Alt text

所以可以尝试 hook API CredReadW ,示例代码如下:

static BOOL(WINAPI *OriginalCredReadW)(LPCWSTR TargetName, DWORD Type, DWORD Flags, PCREDENTIALW *Credential) = CredReadW;
BOOL HookedCredReadW(LPCWSTR TargetName, DWORD Type, DWORD Flags, PCREDENTIALW *Credential)
{
    lpServer = TargetName;
    return OriginalCredReadW(TargetName, Type, Flags, Credential);
}

添加 Attach 和 Detach 代码:

DetourAttach(&(PVOID&)OriginalCredReadW, HookedCredReadW);
DetourDetach(&(PVOID&)OriginalCredReadW, HookedCredReadW);

解决方法 2:

远程桌面建立连接后会在注册表保存远程桌面连接的记录,这里可以通过读取远程桌面连接的历史记录获得 Server 名称

使用的脚本地址:https://github.com/3gstudent/List-RDP-Connections-History/blob/master/ListLogged-inUsers.ps1

0x06 小结

本文介绍了使用 Detours 库 hook 系统 API 和使用 API monitor 监控系统 API 调用的方法,测试 RdpThief,分享在 Win7 下使用时获得 Server 名称的方法,实现了从远程桌面客户端提取明文凭据。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

上一篇:

下一篇:

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

哭了丶谁疼

暂无简介

0 文章
0 评论
23 人气
更多

推荐作者

新人笑

文章 0 评论 0

mb_vYjKhcd3

文章 0 评论 0

小高

文章 0 评论 0

来日方长

文章 0 评论 0

哄哄

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文