原文地址:http://contextis.co.uk/resources/blog/rdp-replay/
发现可以数据包:
keyboard layout是2052-天朝
1. 密文
首先值得注意的是,在发起冗长的握手协议后,所有的信息都是加密的。wireshark可以解密大多数的SSL密文---前提是需要密钥。
2. 第一步
我拥有Linux RDP客户端rdesktop的代码,找到了产生密文交换的地方。这些是关于安全交换共享session密钥的地方。通过printf函数打印出单个pcap session的session密钥。通过实验,发现可以使用rdesktop解密函数来获得解密后的数据
3. 处理数据
协议栈如下所示:
值得注意的是,根据协商,协议栈可能含有或不含SSL,从而RDP和Fast Mode头和细节将会不同,这就是非SSL数据加密的地方。
3.1 pcap重放
可以写一个工具实现读取pcap文件,然后重放。
3.2 Ethernet
发现负载是IPv4(类型是0x0800)
3.3 TCP/IP
处理IP4不是很简单,我必须处理分片,以及checksum检查。我们必须紧紧依靠TCP来确保我们生成正确的TCP/IP数据。需要重新排序数据包,去掉重复数据包,进行TCP checksum检查。默认,它会暂停在TCP的第一个SYN数据包。
3.4 TPKT / X.224 / T.125
这几层进行了最小的处理,仅仅确保匹配,检查长度,丢弃非荷载的帧。我们不感兴趣发起和协商信息。总之,这阶段我们需要的是RDP荷载数据。
3.5 RDP
参照
http://msdn.microsoft.com/en-us/library/cc240445.aspx
4. 密文
我需要获得每个我想解密/显示的session中的密钥。唯一的方法是使用私有密钥,由于session密钥使用公共加密方法交换。基本密钥加密类似:
做了简化处理。如图,我们可以使用加密的session来恢复原始session密钥,以及私有密钥。
4.1 获得私有密钥
RDP使用两种加密方法。使用RC4和SSL。更多是使用SSL,但是老版本的服务器/客户端不支持它,并且使用更古老的加密方法。
4.2 RC4密钥提取
最开始(vista之前)只有一种RDP私有密钥,并且存储在LSA(local security authority),一个叫L$HYDRAENCKEY_28ada6da-d622-11d1-9cb9-00c04fb16e75的注册表项中,
用管理员权限使用如下图工具提取:
密钥为c18f99e6……33bd从0x110~0x14f
vista之后使用DPAPI来处理密钥。密钥长度从521 bit增加到2048 bit。更短的密钥在L$HYDRAENCKEY_52d1ad03-4565-44f3-8bfd-bbb0591f4b9d中可以发现
4.3 提取SSL密钥
需要使用Mimikatz。
生成PFX文件后,使用openssl命令来提取密钥
引用
openssl pkcs12 –in infile.pfx –nodes –out outfile.pem
当弹出提示符后,输入密码:
mimikatz
4.4 解密
现在获得私有密钥了,所以理论上可以进行sessio密钥恢复了。
5. RDP层
使用https://github.com/FreeRDP/FreeRDP/tree/master/libfreerdp api