在渗透测试中,远程桌面连接的历史记录不可忽视,根据历史记录往往能定位出关键的服务器。
前几天有一篇文章介绍了如何清除记录,那么这篇文章就来介绍一下如何导出历史记录。
清除记录的文章地址如下:
http://woshub.com/how-to-clear-rdp-connections-history/#h2_3
最开始的设想是通过枚举注册表就能够完成,但深入研究发现,想要获得所有用户的历史记录,需要逐个获得用户的NTUSER.DAT文件,通过注册表加载配置单元,导入用户配置信息,再进行枚举才能够实现。
本文将要介绍以下内容:
枚举注册表键值HKCU:\Software\Microsoft\Terminal Server Client\Servers
每个注册表项保存连接的服务器地址,其中的键值UsernameHint
对应登录用户名
如下图
已登录用户的注册表信息会同步保存在HKEY_USERS\SID
下,SID要对应每个用户的SID
当前系统登录两个用户,分别有两个子项,如下图
注:
HKEY_USERS仅包含了缺省用户设置和登录用户的信息,在用户未登录时用户的设置是不可用的
也就是说,如果当前登录了两个用户,那么这两个用户的注册表信息都会保存在HKEY_USERS\SID
下,如果第三个用户未登录,无法直接获得该用户的注册表信息,也就无法导出该用户的远程桌面连接历史记录
所以,通过枚举注册表键值HKEY_USERS\SID\Software\Microsoft\Terminal Server Client\Servers
能够获得已登录用户的远程桌面连接历史记录
对于未登录用户,无法直接获得注册表配置信息,这里可以通过加载配置单元的方式来解决
选中HKEY_USERS项,文件
-加载配置单元
,如下图
打开用户的NTUSER.DAT文件,路径为C:\Documents and Settings\用户名\NTUSER.DAT
接着指定一个项名称,即可在HKEY_USERS下读取该用户的注册表配置信息,如下图
注:
删除该项需要通过卸载配置单元来清除
所以,想要获得所有用户的远程桌面连接历史记录,首先需要枚举注册表键值HKEY_USERS\SID\
,对于未登录用户,需要加载对应的NTUSER.DAT文件,再次枚举获得完整记录,最后卸载对应的注册表项
补充:
通过命令行实现加载配置单元的实例:
Reg load HKEY_USERS\S-1-5-21-1170783345-3748964848-1387080272-1003 C:\Documents and Settings\c\NTUSER.DAT
通过命令行实现卸载配置单元的实例:
Reg unload HKEY_USERS\S-1-5-21-1170783345-3748964848-1387080272-1003
位置:HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Servers
枚举指定注册表项下的子项:
dir "Registry::HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Servers" -Name
查询指定注册表项的注册表键值:
(Get-ItemProperty -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Servers\192.168.62.137").UsernameHint
加入foreach循环实现枚举:
$RegPath = "Registry::HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Servers\"
$QueryPath = dir $RegPath -Name
foreach($Name in $QueryPath)
{
(Get-ItemProperty -Path $RegPath$Name).UsernameHint
}
加入捕获异常,不输出错误信息,如果查不到注册表键值,返回无法获得
完整脚本:
$RegPath = "Registry::HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Servers\"
$QueryPath = dir $RegPath -Name
foreach($Name in $QueryPath)
{
Try
{
$User = (Get-ItemProperty -Path $RegPath$Name -ErrorAction Stop | Out-Null).UsernameHint
Write-Host "Server:"$Name
Write-Host "User:"$User"`n"
}
Catch
{
Write-Host "No RDP Connections History"
}
}
位置:HKEY_USERS\SID\Software\Microsoft\Terminal Server Client\Servers
注:
SID对应每个用户的sid
首先需要枚举所有用户sid
powershell:
Get-WmiObject -Class Win32_UserAccount
wmi:
wmic /NAMESPACE:"\\root\CIMV2" PATH Win32_UserAccount GET /all /FORMAT:list
枚举用户名及其对应的SID:
$AllUser = Get-WmiObject -Class Win32_UserAccount
foreach($User in $AllUser)
{
Write-Host $User.Name":"$User.SID
}
将以上脚本结合,先枚举用户的SID,查询对应HKEY_USERS下的注册表项,再次枚举注册表键值项,获得完整结果:
(需要管理员权限)
$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 "Server:"$Name
Write-Host "User:"$User
}
Catch
{
Write-Host "No RDP Connections History"
}
}
Write-Host "----------------------------------"
}
注:
$User.Status表示帐户状态,通过Get-WmiObject -Class Win32_UserAccount
无法直接查询到,可通过wmi命令获取:
wmic /NAMESPACE:"\\root\CIMV2" PATH Win32_UserAccount GET /all /FORMAT:list
加载配置单元的文件位置:
"C:\Documents and Settings\用户名\NTUSER.DAT"
注:
需要新启动一个进程来卸载配置单元,否则提示失败
为了避免使用多个try catch捕获异常,代码结构作了改变,使用If Else作判断,完整实现代码可参考:
https://github.com/3gstudent/List-RDP-Connections-History
测试结果如下图
本文介绍了如何通过powershell获得Windows系统的远程桌面连接历史记录,需要注意的是无法直接获得未登录用户的注册表配置信息(可以加载配置单元解决)。根据远程桌面连接历史记录,往往能定位出关键的服务器。