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