PowerShell script exchange
Post Reply
matteu
Veeam Legend
Posts: 824
Liked: 128 times
Joined: May 11, 2018 8:42 am
Contact:

Unencrypt password

Post by matteu »

Hello,

I know there is no support for script on this KB but if provided by Veeam, I would like it to work.
https://www.veeam.com/kb4349

I'm on 12.1 and when I execute the KB, I get some of my account password but I always have this error for $raw :

Exception lors de l'appel de « Unprotect » avec « 3 » argument(s) : « Invalid data.
 »
Au caractère Ligne:1 : 1
+ $raw = [System.Security.Cryptography.ProtectedData]::Unprotect($data, ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : CryptographicException


What should I do to fix it ?

Thanks
Mildur
Product Manager
Posts: 10107
Liked: 2696 times
Joined: May 13, 2017 4:51 pm
Full Name: Fabian K.
Location: Switzerland
Contact:

Re: Unencrypt password

Post by Mildur »

Hi Matteu

Since v12.1, the steps can only be run by a user in the Local Administrators group. We addionally encrypted the credentials with a random key which is stored in the registry.
The key is only accessible by this group. Please check that your user or service account is in the Local Administrators group on the backup server machine.
Then run the script directly on the backup server.

https://www.veeam.com/veeam_backup_12_1 ... new_wn.pdf
Sensitive data protection — saved credentials stored in the configuration database in an encrypted
form using Microsoft Data Protect API (DPAPI) are now additionally protected with a randomly generated
entropy value providing additional key derivation. This entropy is stored in the backup server registry key
only accessible to the Local Administrators group, providing protection against attacks by unprivileged
users and processes
Best,
Fabian
Product Management Analyst @ Veeam Software
matteu
Veeam Legend
Posts: 824
Liked: 128 times
Joined: May 11, 2018 8:42 am
Contact:

Re: Unencrypt password

Post by matteu »

My account is the built in administrator and is local administrator.

I see with 12.1 it's different because I created a custom script with V11 and it's not working anymore. In the KB I can see there is différent method if you are on v11 / v12 / v12.1

I did some more tests :

If I create new credentials, I can get them.

So, I guess I can't recover password I create before v12.1 ? Is it expected ?

In my database (SQL), I can see in encrypted password some start with AQAA.... and others with VmVIY.... Is it the same for you ?

For AQAA... I need to use the V12 method
For VmYIY... I need to use the V12.1 method

I don't have any error on the script if I seperate it but I would like to be sure it's "always" AQAA or VmYiY or a way to identify exactly wich one I need to use ?
Mildur
Product Manager
Posts: 10107
Liked: 2696 times
Joined: May 13, 2017 4:51 pm
Full Name: Fabian K.
Location: Switzerland
Contact:

Re: Unencrypt password

Post by Mildur »

Hi Matteu

I tried the v12.1 script in the KB on my v12.1.1 server and I can decrypt user credentials which I have added before v12.1.
Maybe you can share your custom script?

I only see VmYIY.

Best,
Fabian
Product Management Analyst @ Veeam Software
Mildur
Product Manager
Posts: 10107
Liked: 2696 times
Joined: May 13, 2017 4:51 pm
Full Name: Fabian K.
Location: Switzerland
Contact:

Re: Unencrypt password

Post by Mildur »

I checked another backup server.
I believe AQAA is from pre-V12 and VmYIY are credentials from V12 and later.

Which could mean we haven't re-encrypted old passwords from pre-v12 with the new random key. The old script with only the machine key is still valid. I will discuss it with the team. Thanks for letting us know.

Best,
Fabian
Product Management Analyst @ Veeam Software
matteu
Veeam Legend
Posts: 824
Liked: 128 times
Joined: May 11, 2018 8:42 am
Contact:

Re: Unencrypt password

Post by matteu »

Yes for sure, this is what I use now and work for both.
It's possible the difference is before V12 and V12>=

This explains my test were not all OK.

With this script, I have 0 error because I use 2 methods.
To use it, you don't need to provide anything :)
I get all the data automatically (registry salt, user encrypted password, instance, database). Just copy paste and execute :) No SQL module needed.
I would like to add postgreSQL, I'm working on it.

Code: Select all

$DBConfiguration = Get-ItemProperty -Path "HKLM:\SOFTWARE\Veeam\Veeam Backup and Replication\DatabaseConfigurations"
$DBProduct = $DBConfiguration.SqlActiveConfiguration

# Add EncryptionSalt value from registry HKLM\SOFTWARE\Veeam\Veeam Backup and Replication\Data
$saltbase = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Veeam\Veeam Backup and Replication\Data").EncryptionSalt


if ($DBProduct -eq "Mssql")
{
    $SQLConfiguration = Get-ItemProperty -Path "HKLM:\SOFTWARE\Veeam\Veeam Backup and Replication\DatabaseConfigurations\MsSql"
    $SQLServer        = $SQLConfiguration.SqlServerName
    $SQLInstance      = $SQLConfiguration.SqlInstanceName
    $SQLDB            = $SQLConfiguration.SqlDatabaseName
    $SQLConnection    = $SQLServer + "\" + $SQLInstance
    $sqlquery="SELECT user_name,password from dbo.Credentials"

    $Connection                  = New-Object System.Data.SQLClient.SQLConnection
    $Connection.ConnectionString = "server='$SQLConnection';database='$SQLDB';trusted_connection=false; integrated security='true'"
    $Connection.Open()
    $command                     = $Connection.CreateCommand()
    $command.CommandText         = $sqlquery
    $Datatable                   = New-Object "System.Data.Datatable"
    $result                      = $command.ExecuteReader()
    $Datatable.Load($result)
    $Result=$Datatable   


}

Foreach ($account in $result)
{
    if ($account.password -like "AQAA*")
    {
        $context = $account.password
        Add-Type -AssemblyName 'system.security'
        $data = [Convert]::FromBase64String($context)
        $raw = [System.Security.Cryptography.ProtectedData]::Unprotect($data, $null, [System.Security.Cryptography.DataProtectionScope]::LocalMachine)
        
        [PSCustomObject]@{
            Name = $account.user_name
            Password = [System.Text.Encoding]::UTF8.GetString($raw)        
        }
    }
    else
    {    
        # Add encrypted value from the configuration database with single quotes. ('value' not '"value"')
        $context = $account.password


        # Make no changes below this line
        Add-Type -AssemblyName System.Security 
        $salt = [System.Convert]::FromBase64String($saltbase)
        $data = [System.Convert]::FromBase64String($context)
        $hex = New-Object -TypeName System.Text.StringBuilder -ArgumentList ($data.Length * 2)
        foreach ($byte in $data) {$hex.AppendFormat("{0:x2}", $byte) > $null}
        $hex = $hex.ToString().Substring(74,$hex.Length-74)
        $data = New-Object -TypeName byte[] -ArgumentList ($hex.Length / 2)
        for ($i = 0; $i -lt $hex.Length; $i += 2) {$data[$i / 2] = [System.Convert]::ToByte($hex.Substring($i, 2), 16)}
        $securedPassword = [System.Convert]::ToBase64String($data)
        $data = [System.Convert]::FromBase64String($securedPassword)
        $local = [System.Security.Cryptography.DataProtectionScope]::LocalMachine
        $raw = [System.Security.Cryptography.ProtectedData]::Unprotect($data, $salt, $local) 
        [System.Text.Encoding]::UTF8.Getstring($raw)
    }
}
matteu
Veeam Legend
Posts: 824
Liked: 128 times
Joined: May 11, 2018 8:42 am
Contact:

Re: Unencrypt password

Post by matteu » 2 people like this post

Updated to work with PostgreSQL.
If It's SQL database, no action required.
If it's PostgreSQL database, password for user used by veeam to connect to PostgreSQL will be prompted.


Code: Select all

$DBProduct = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Veeam\Veeam Backup and Replication\DatabaseConfigurations").SqlActiveConfiguration

# Add EncryptionSalt value from registry HKLM\SOFTWARE\Veeam\Veeam Backup and Replication\Data
$saltbase = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Veeam\Veeam Backup and Replication\Data").EncryptionSalt


if ($DBProduct -eq "Mssql")
{
    #Get SQL configuration
    $SQLConfiguration = Get-ItemProperty -Path "HKLM:\SOFTWARE\Veeam\Veeam Backup and Replication\DatabaseConfigurations\MsSql"
    $SQLServer        = $SQLConfiguration.SqlServerName
    $SQLInstance      = $SQLConfiguration.SqlInstanceName
    $SQLDB            = $SQLConfiguration.SqlDatabaseName
    $SQLConnection    = $SQLServer + "\" + $SQLInstance
    $sqlquery="SELECT user_name,password from dbo.Credentials"

    $Connection                  = New-Object System.Data.SQLClient.SQLConnection
    $Connection.ConnectionString = "server='$SQLConnection';database='$SQLDB';trusted_connection=false; integrated security='true'"
    $Connection.Open()
    $command                     = $Connection.CreateCommand()
    $command.CommandText         = $sqlquery
    $Datatable                   = New-Object "System.Data.Datatable"
    $result                      = $command.ExecuteReader()
    $Datatable.Load($result)
    $Result=$Datatable   


}

else
{
    #If postgreSQL
    
    #Get PostgreSQL configuration

    $PostgreSQLConfiguration = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Veeam\Veeam Backup and Replication\DatabaseConfigurations\PostgreSql")
    $PostgreUser             = $PostgreSQLConfiguration.SQLUsername
    $PostgreSecPassword      = (Get-Credential -Message "Enter password for user $PostgreUser" -UserName $PostgreUser)
    $PostgrePassword         = $PostgreSecPassword.GetNetworkCredential().Password
    $PostgrePort             = $PostgreSQLConfiguration.SqlHostPort
    $PostgreDatabase         = $PostgreSQLConfiguration.SqlDatabaseName
    $PostgreQuery            = "SELECT user_name,password,description,change_time_utc FROM credentials"
    $dburl                   = "postgresql://$($PostgreUser):$PostgrePassword@localhost:$PostgrePort/$PostgreDatabase"
    $Result                  = $PostgreQuery | & "C:\Program Files\PostgreSQL\15\bin\psql" --csv $dburl | ConvertFrom-Csv

}

#Decrypt password
Foreach ($account in $result)
{
    $Name = $account.user_name
    $Password = "<N/A>"
    if ($account.password -like "AQAA*")
    {
        $context = $account.password
        Add-Type -AssemblyName 'system.security'
        $data = [Convert]::FromBase64String($context)
        $raw = [System.Security.Cryptography.ProtectedData]::Unprotect($data, $null, [System.Security.Cryptography.DataProtectionScope]::LocalMachine)
        $Password = [System.Text.Encoding]::UTF8.Getstring($raw)

    }
    if ($account.password -like "VmVlY*")
    {    
        # Add encrypted value from the configuration database with single quotes. ('value' not '"value"')
        $context = $account.password


        # Make no changes below this line
        Add-Type -AssemblyName System.Security 
        $salt = [System.Convert]::FromBase64String($saltbase)
        $data = [System.Convert]::FromBase64String($context)
        $hex = New-Object -TypeName System.Text.StringBuilder -ArgumentList ($data.Length * 2)
        foreach ($byte in $data) {$hex.AppendFormat("{0:x2}", $byte) > $null}
        $hex = $hex.ToString().Substring(74,$hex.Length-74)
        $data = New-Object -TypeName byte[] -ArgumentList ($hex.Length / 2)
        for ($i = 0; $i -lt $hex.Length; $i += 2) {$data[$i / 2] = [System.Convert]::ToByte($hex.Substring($i, 2), 16)}
        $securedPassword = [System.Convert]::ToBase64String($data)
        $data = [System.Convert]::FromBase64String($securedPassword)
        $local = [System.Security.Cryptography.DataProtectionScope]::LocalMachine
        $raw = [System.Security.Cryptography.ProtectedData]::Unprotect($data, $salt, $local) 
        $Password = [System.Text.Encoding]::UTF8.Getstring($raw)
    }

    [PSCustomObject]@{
        Name     = $Name
        Password = $Password
    }
}


Post Reply

Who is online

Users browsing this forum: No registered users and 15 guests