渗透技巧——Pass the Hash with Remote Desktop Protocol

发布于 2024-09-21 09:46:17 字数 8113 浏览 11 评论 0

0x00 前言

在之前的文章 《渗透技巧——Pass the Hash with Remote Desktop(Restricted Admin mode)》 ) 介绍了特定条件下(Server 需要开启 Restricted Admin mode,Client 需要支持 Restricted Admin mode)Pass the Hash with Remote Desktop 的方法,本文将要介绍更为通用的方法(通过 NTLM hash 登录 RDP),分析原理,开源代码,记录细节。

0x01 简介

本文将要介绍以下内容:

  • 渗透测试中的需求
  • 验证口令或者 NTLM hash 的实现方法
  • C 实现代码
  • Python 实现代码
  • C sharp 实现代码

0x02 渗透测试中的需求

如果是开发远程桌面服务的客户端,可供选择的方法有很多,例如通过 C#调用 ActiveX 组件 AxMSTSCLib

详细方法可参考: https://www.codeproject.com/Articles/43705/Remote-Desktop-using-C-NET

但是在渗透测试中,我们有以下两个需求:

1.验证口令或者 hash

需要满足以下条件:

  • 可以在 Windows 和 Linux 系统上运行
  • 登录方式支持明文口令和 NTLM hash
  • 命令行下使用

2.远程登录

  • 可以在 Windows 和 Linux 系统上运行
  • 登录方式支持明文口令和 NTLM hash

0x03 验证口令或者 hash 的实现方法

为了支持 NTLM hash 登录,需要对协议和加密方式有所了解

关于 RDP 协议的参考资料: https://github.com/FreeRDP/FreeRDP/wiki/Reference-Documentation

1.使用 Python 实现(rdp_check.py)

代码地址: https://github.com/SecureAuthCorp/impacket/blob/master/examples/rdp_check.py

  • 可以在 Windows 和 Linux 系统上运行
  • 登录方式支持明文口令和 NTLM hash
  • 命令行下使用

脚本运行前需要安装 Impacket

安装方法: pip install Impacket

如果是在 Windows 系统下使用,可以将 Python 脚本转换成 exe,编译好的 exe 文件下载地址: https://github.com/maaaaz/impacket-examples-windows

使用示例:明文口令验证

rdp_check.py /administrator:test123@192.168.1.1

使用示例:NTLM hash 验证

rdp_check.py /administrator@192.168.1.1 -hashes :c5a237b7e9d8e708d8436b6148a25fa1

注:hash 的格式为 LMHASH:NTHASH ,如果只有 NTLM hash,格式为 :NTHASH ,需要注意 : 前面存在一个空格字符

2.使用 C 实现(FreeRDP)

代码地址: https://github.com/FreeRDP

  • 可以在 Windows 和 Linux 系统上运行
  • 登录方式支持明文口令
  • 命令行下使用

如果为了支持 NTLM hash 登录,需要使用旧版本的 FreeRDP,下载地址: https://labs.portcullis.co.uk/download/FreeRDP-pth.tar.gz

如果仅仅为了验证口令或者 hash,需要修改代码,去除后续登录的功能

关于 FreeRDP 的使用可参考: https://github.com/FreeRDP/FreeRDP/wiki/CommandLineInterface

3.使用 C sharp 实现(SharpRDPCheck)

  • 可以在 Windows 系统上运行
  • 登录方式支持明文口令和 NTLM hash
  • 命令行下使用

开发过程记录:

这里无法通过调用 ActiveX 组件 AxMSTSCLib 实现,原因如下:

  • 使用 ActiveX 组件 AxMSTSCLib 无法通过 NTLM hash 登录
  • 对命令行的支持不够友好

所以只能参照 rdp_check.py 的方式,手动构造通信数据

经过搜索,我找到了一个可供参考的代码: https://github.com/RDPUploader/RDPUploader

RDPUploader 包括三个子项目,编译成功后生成两个 dll 和一个 exe 文件,不支持命令行操作,也不支持 NTLM hash 登录,但其中的通信过程写的很清晰

接下来以 RDPUploader 为模板进行开发

这里具体介绍一下支持 NTLM hash 登录的方法:

Remote Desktop Protocol 在进行验证时,先将明文口令转换成 NTLM hash,再进行验证

我们首先寻找 RDPUploader 中从明文口令转换为 NTLM hash 的代码,具体内容如下:

private static byte[] nTOWFv1(string password)
{
    if (password == null)
    {
        throw new Exception("Password parameter is required");
    }

    return MD4.ComputeHash(Encoding.Unicode.GetBytes(password));
}

private static byte[] nTOWFv2(string domain, string username, string password)
{
    HMACT64 hmact = new HMACT64(nTOWFv1(password));
    hmact.update(Encoding.Unicode.GetBytes(username.ToUpper()));
    hmact.update(Encoding.Unicode.GetBytes(domain));
    return hmact.digest();
}

补充:NTLM hash 的生成方法

  1. 将明文口令转换成十六进制的格式
  2. 转换成 Unicode 格式,即在每个字节之后添加 0x00
  3. 对 Unicode 字符串作 MD4 加密,生成 32 位的十六进制数字串

这里以明文口令 test123 为例:

转换成十六进制的格式为 74657374313233

转换成 Unicode 格式为 7400650073007400310032003300

对字符串 7400650073007400310032003300 作 MD4 加密,结果为 c5a237b7e9d8e708d8436b6148a25fa1

更多细节可参考之前的文章 《Windows 下的密码 hash——NTLM hash 和 Net-NTLM hash 介绍》

这里我们可以将 nTOWFv1(password) 的结果输出,验证 NTLM hash 的生成方法是否准确,修改后的代码如下:

private static byte[] nTOWFv2(string domain, string username, string password)
{

    byte[] a = nTOWFv1(password);
    string text = "";
    for (int i = 0; i < a.Length; i++)
    {
        text += a[i].ToString("X2");
    }
    Console.WriteLine(text);
    HMACT64 hmact = new HMACT64(a);
    hmact.update(Encoding.Unicode.GetBytes(username.ToUpper()));
    hmact.update(Encoding.Unicode.GetBytes(domain));
    return hmact.digest();
}

输出的字符串为 C5A237B7E9D8E708D8436B6148A25FA1 ,验证成功

接下来,直接传入字符串 C5A237B7E9D8E708D8436B6148A25FA1 进行验证

这里需要将 hex 格式的字符串转换为 byte[],代码如下:

public static byte[] ConvertHexStringToBytes(string hexString)
{
    hexString = hexString.Replace(" ", "");
    if (hexString.Length % 2 != 0)
    {
        throw new ArgumentException("wrong length of ntlm hash");
    }
    byte[] returnBytes = new byte[hexString.Length / 2];
    for (int i = 0; i < returnBytes.Length; i++)
    {
        returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
    }
    return returnBytes;
 }

private static byte[] nTOWFv2(string domain, string username, string password)
{
    string text = "C5A237B7E9D8E708D8436B6148A25FA1";
    byte[] byteArray = ConvertHexStringToBytes(text);
    HMACT64 hmact = new HMACT64(byteArray);
    hmact.update(Encoding.Unicode.GetBytes(username.ToUpper()));
    hmact.update(Encoding.Unicode.GetBytes(domain));
    return hmact.digest();
}

验证成功,最后将固定字符串修改为变量传递即可实现对 NTLM hash 登录的支持

完整代码已开源,地址如下: https://github.com/3gstudent/SharpRDPCheck/

可通过 Visual Studio 进行编译,编译的目标框架推荐使用.NET Framework 4.6,这是为了使用 TLSv1.2

否则会使用 TLSv1.0,在进行登录时会失败,提示如下:

[!] Authentication Error (The decryption operation failed, see inner exception.)

InnerException: System.ComponentModel.Win32Exception (0x80004005): The Local Sec
urity Authority cannot be contacted

参考资料: https://docs.microsoft.com/en-us/dotnet/api/system.net.security.sslstream.authenticateasclient?redirectedfrom=MSDN&view=netframework-4.8

编译成功后在安装.NET Framework 4 的 Windows 系统下都可以正常使用

0x04 防御思路

对于 RDP 的爆破攻击,可以选择提高用户口令的强度

对于爆破行为的检测,可以通过 cmd 查看其他用户通过 RDP 登录当前系统的日志:

wevtutil gli "Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational"
wevtutil qe /f:text "Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational"

每当 Listener RDP-Tcp 收到一个连接请求,将产生 EventID 为 261 的日志

也就是说,只要收到了 RDP 的连接请求,无论连接是否成功,均会产生 EventID 为 261 的日志

通过 Powershell 查看其他用户通过 RDP 登录当前系统的日志:https://gallery.technet.microsoft.com/Remote-Desktop-Connection-3fe225cd

0x05 小结

本文介绍了针对 Remote Desktop Protocol,验证口令或者 NTLM hash 的实现方法,开源代码 SharpRDPCheck,分享程序实现 NTLM hash 登录的细节,最后介绍通过日志检测 RDP 爆破行为的方法。

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

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

发布评论

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

关于作者

天煞孤星

暂无简介

0 文章
0 评论
22 人气
更多

推荐作者

玍銹的英雄夢

文章 0 评论 0

我不会写诗

文章 0 评论 0

十六岁半

文章 0 评论 0

浸婚纱

文章 0 评论 0

qq_kJ6XkX

文章 0 评论 0

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