远程桌面访问RDP协议探究
当前位置:点晴教程→知识管理交流
→『 技术文档交流 』
RDP 远程桌面连接协议,作为相对比较广泛的协议。对于协议识别来说很值得学习。首先 RDP 资料丰富,开源的程序也特别多。另一方面作为一个比较老的协议,版本丰富,兼容性强,小问题也多。从安全的角度更能看出协议的演变和发展。本文会从环境搭建、简要分析和思考这几方面来讲解。 预备知识除非另有说明,否则数据包一律按 little-endian 字节顺序排列 RDP协议的发展RDP(Remote Desktop Protocol,远程桌面协议)是基于 ITU-T(国际电信联盟)的T.120协议中的T.128应用程序共享协议(又称为 T.share),随后由英国软件公司 DataConnection Limited 优化成 RDP 的雏形。此时,微软看到 RDP 是块肥肉,果断收购了DataConnection Limited,进而把 RDP 变成自己的囊中物(知识产权)。 发展至今,已经有 10 个版本了。当前主要使用的版本有 6.1(Windows Server 2008/Windows Vista SP1/Windows XP SP3),7.0(Windows Server 2008 R2/Windows 7),其中 7.0 版本增加了 Remote FX 功能,用于提升高清图像的渲染效果,如 2D、3D 图像。(摘自全球主流云桌面传输协议 - 知乎 ) 目前 RDP 协议标志位(对应了第一阶段的 PROTOCOL_RDP 又称为标准型RDP协议,最早出现在Windows NT 4.0上,这个协议本身本身就存在很大隐患,它使用明文传输。之后采取多种安全级别的加密算法,它支持四个加密级别:低、客户端兼容、高、 并且符合 FIPS(无、40位RC4、56位RC4、128位RC4或3DES ),可以在服务器上配置所需的加密级别来传输数据。 对于标准的RDP协议微软犯了一个错误,加密的算法使用 RSA, 但是公钥是内置在客户端中。也就是说所有服务器的私钥其实都是一样的。微软现在已经公开了此私钥:
这个版本中 PROTOCOL_SSL 使用标准的加密层,类似于 http 和 https 的关系。数据默认是安全的,所以在传输过程中内部的数据是明文的,但是也有问题一旦知道私钥就很容解出来例如在 clientInfo 中会直接传递明文包含账户密码 在rdp协议链接阶段也会把一些本地主机的信息发送给客户端 RDP在前两个版本里不具备鉴权功能,只有数据传输的功能。鉴权只能使用 windows 自身身份认证的功能。
CredSSP 协议虽然也使用 TLS 隧道,但它不是在受保护的隧道中传输密码,而是使用 NTLM 或 Kerberos 进行身份验证。该协议也称为网络级认证(NLA)。使用外部安全协议的好处是 RDP 开发人员不再需要手动实现协议安全机制,而是可以依赖众所周知且经过验证的安全协议包(例如实现 SSL 的 Schannel 安全包,请参阅 [MSDN- SCHANNEL])提供端到端安全性。 RDP协议的分层RDP协议栈分为六个层次自上向下分别为
工具
实际上 环境准备工作获取rdp 私钥Wireshark for Pentester: Decrypting RDP Traffic(https://www.hackingarticles.in/wireshark-for-pentester-decrypting-rdp-traffic/) 如何使用Wireshark解密Windows远程桌面(RDP)协议-二进制漏洞-看雪-安全社区(https://bbs.kanxue.com/thread-255173.htm) 下载好最新版本的Mimikatz(https://github.com/gentilkiwi/mimikatz/releases)把Mimikatz放到RDP服务器里,命令行执行Mimikatz.exe 运行下面3条命令
步骤2:把.pfx转换成.pem
运行上面的命令以后,会提示需要密码( password ),输入 mimikatz 即可 注意 测试的最新版本的 windows10 导出不了私钥 抓取rdp流为了抓取干净的数据包需要进行一些设置 首先捕获过滤器设置
登录后保存数据包 解密 RDP 数据流wireshark 设置 菜单栏 Wireshark -> preference -> protocols ->TLS 设置完解密后rdp 连接初始化(Connect Request PDU)并没有使用TLS加密。会显示 这个是数据包解析错误导致的,为了便于分析请设置请选中此数据包 此时数据包会显示正常 开始分析微软将rdp初始化连接分成10部分 连接顺序可以分为十个不同的阶段但是并不是所有的阶段都会出现如 Security Exchange 在标准RDP中会出现。但是增强型RDP中没有出现。我们这里只关注必要的阶段 1. 初始化连接X.224 Connection Request PDUtpktHeader 数据格式如下tpktHeader (4 bytes): A TPKT Header, as specified in [T123] section 8.
x224Crq 数据格式如下x224Crq (7 bytes): An X.224 Class 0 Connection Request transport protocol data unit (TPDU), as specified in [X224] section 13.3.
X.224 Connection Response PDU 图片来源: RDP Negotiation Request (RDP_NEG_REQ) | Microsoft Learn --- [MS-RDPBCGR]:RDP 协商请求 (RDP_NEG_REQ) |Microsoft 学习 作为协议识别只需要知道第一个阶段已经可以粗略识别了。在这里参考bodyhack的代码。
另外想要精确识别就是在进行 tls连接后会进行ntlmssp的挑战响应,能够非常准确的提取出来主机名和操作系统的版本。
发现的问题在实现的时候为了准确和方便需要判断如果flag支持 CredSSP。实现过程中发现我测试的 windows7 版本在发送 ntlm 协议的时候并没有正确的返回数据。抓包后发现NTLMSSP_NEGOTIATE消息被分开两部分发送了。我们先看看正常的数据包 再看一下不正常的 先发送 30 再发送其他数据。经过调试和分析发现是 Golang 标准库在实现的时候为了解决 TLS1.0 的安全问题而引入的https://github.com/golang/go/blob/2184a394777ccc9ce9625932b2ad773e6e626be0/src/crypto/tls/conn.go#L1216 大概意思是 TLS 1.0 在使用块模式密码时容易受到选择明文攻击,因为它们的初始化向量是可预测的。通过将每个应用数据记录分成两条记录,可以有效地随机化初始化向量,从而防止这种攻击。解决此类问题有两种方法: 使用 FOFA (无脑吹确实好用)随机选择10000条测试一下效果
经过 naabu 测试存活后测试。发现 FOFA 对于使用 TLS1.0 版本的 ntlmssp 的挑战响应并没有解析成功。 再次挑选测试发现有些版本的 windows 客户端可以正确连接,但是使用 Golang 在进行 TLS 握手的时候直接退出,看环境推测是 windows server 2016。搭建以后抓包 经过分析,发现 Server Hello 要求的 Cipher Suite 为TLS_RSA_WITH_AES_128_CBC_SHA256 (0x003c)。Client Hello 中并没有支持。(go 默认支持的很少)好吧统统加上去,可以正常识别了。 本文发布时,此类问题 FOFA 已经修复,其他空间搜索引擎可以自测。 思考在协议识别过程中,各家系统对协议支持都相对比较完善了。但是基础库应该已经是协议识别准确率的短板。很多厂商很有可能并没有关注这一块。只是依赖编程语言的标准库或者第三方库。而对于不同的协议尤其是老旧协议的支持,还有加密算法的支持,可能随着编程语言和安全的发展往往无法会废弃掉,而这种基础库往往很见细节,可能少实现一个都会漏掉很多。 该文章在 2024/3/12 19:28:13 编辑过 |
关键字查询
相关文章
正在查询... |