欢迎访问Sunbet,Sunbet是欧博Allbet的官方网站!

首页Sunbet_安全工具正文

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

e6e9fdb1a932f3282020-05-2151技术

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的生成方法。

将明文口令转换成十六进制的格式。

转换成Unicode格式,即在每个字节之后添加0x00。

对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爆破行为的方法。

本文为 3gstudent 原创稿件,授权嘶吼独家发布,
奔驰智能汽车组件OLU源码泄露

来自瑞士的软件工程师Till Kottmann发现了属于奔驰母公司戴姆勒(Daimler AG)的git web网关。然后注册了一个代码保存网关的账号,并下载了超过580个git库的内容,其中就含有奔驰汽车上安装的车载逻辑单元(onboard logic units,OLU)的源代码。 OLU 据戴姆勒网站介绍,OLU是位于汽车硬件和软件之间组件,可以将车辆与云端相连接。OLU简化了实时车辆数据的技术访问和管理,允许第三方开发者创建从奔驰车辆上提取数据的app。 这些app一般会被用来对路上的车辆进行追踪、记录车辆的内部状态、或者在车辆被盗时锁定车辆。 不安全的gitlab安装致代码泄露 GitLab是一个基于web的软件包,企业用它来集中处理Git存储库。Git是一种专门用于跟踪源代码修改的软件,允许多人编写代码,然后将代码同步到一个中央服