I wrote this last week and found it useful to recover data offline from the LSA store. Make sure to replace the key, secret, and IV into the code in the same format and it should decrypt for you.

function Initialize-AESCryptography($key) {
    $crypto = New-Object "System.Security.Cryptography.AesManaged"
    $crypto.Mode = [System.Security.Cryptography.CipherMode]::ECB
    $crypto.Padding = [System.Security.Cryptography.PaddingMode]::Zeros
    $crypto.BlockSize = 128
    $crypto.KeySize = 256

    $IV = $null
    if ($IV) {
        if ($IV.getType().Name -eq "String") {
            #depending on how you want to do this, you can either take a full string, not encoded
            #or an B64 encoded string. Comment/Uncomment what you want
            $crypto.IV = [System.Convert]::FromBase64String($IV)
            #$crypto.IV = [Text.Encoding]::UTF8.GetBytes($IV)
        }
        else {
            $crypto.IV = $IV
        }
    }
    else {
        #The default when called CreateEncryptor is to automatically create a Key or IV
        #Since we want to store the key later, better for us to do it.
        $crypto.GenerateIV()
    }

    if ($key) {
        if ($key.getType().Name -eq "String") {
             #depending on how you want to do this, you can either take a full string, not encoded
             #or an B64 encoded string. Comment/Uncomment what you want
            $crypto.Key = [System.Convert]::FromBase64String($key)
            #$crypto.Key = [Text.Encoding]::UTF8.GetBytes($key)
        }
        else {
            $crypto.Key = $key
        }
    }
    else {
        #The default when called CreateEncryptor is to automatically create a Key or IV
        #Since we want to store the key later, better for us to do it.
        $crypto.GenerateKey()
      }
    $crypto
}

function ConvertFrom-AESEncryptedString($crypto, $bytes) {
    $decryptor = $crypto.CreateDecryptor();
    # a little obfuscution here. This isn't even needed.
    #changed to not use IV in the final String
    #$unencryptedData = $decryptor.TransformFinalBlock($bytes, 16, $bytes.Length - 16);
    $unencryptedData = $decryptor.TransformFinalBlock($bytes, 0, $bytes.Length);

    #The below line shouldn't need to Trim Zeros (which was the pad)
    [System.Text.Encoding]::UTF8.GetString($unencryptedData).Trim([char]0)
}

[byte[]] $key = 0xed, 0xbc, 0x73, 0x26, 0xf8, 0x21, 0xe9, 0x6a, 0xbc, 0x38, 0x34, 0x7a, 0xfa, 0xbd, 0x1c, 0x70, 0x18, 0xf2, 0x24, 0xf5, 0x82, 0xe9, 0x00, 0xac, 0xf8, 0x41, 0x6f, 0x5b, 0x03, 0xe8, 0xac, 0xd4
[byte[]] $secret =  0x7e, 0x39, 0xfe, 0x9d, 0x51, 0xe2, 0x2d, 0x55, 0x14, 0x0e, 0xfe, 0x8b, 0x0b, 0x5f, 0x13, 0x19, 0x4a, 0x4b, 0x15, 0x52, 0x00, 0xb7, 0xd8, 0x2f, 0x6d, 0x46, 0x90, 0x40, 0xe9, 0x64, 0x30, 0x94, 0xef, 0x38, 0x96, 0x5a, 0x44, 0xa1, 0xb7, 0x2a, 0x79, 0x82, 0xbf, 0x15, 0x55, 0xc2, 0xab, 0x8b 
[byte[]] $iv = 0x68, 0x74, 0x86, 0x95, 0x9a, 0x69, 0x70, 0xb2, 0x66, 0x74, 0xc8, 0x30, 0x25, 0x60, 0x49, 0x71, 0xb9, 0xee, 0x06, 0x73, 0x42, 0xdb, 0x28, 0x8a, 0x22, 0x1f, 0xd0, 0x86, 0x0b, 0xfb, 0x41, 0xc5 

$hasher = [System.Security.Cryptography.HashAlgorithm]::Create('sha256')
[void]$hasher.TransformBlock($key,0,$key.Count,$hash,0)

For ($i=0; $i -lt 999; $i++) 
{
    [void]$hasher.TransformBlock($iv,0,$iv.Count,$hash,0)
}

[void]$hasher.TransformFinalBlock($iv, 0, $iv.Count)
$hashString = [System.BitConverter]::ToString($hasher.Hash)
$hashString.Replace('-', '')

$key = $hasher.Hash

$crypto = Initialize-AESCryptography $key
ConvertFrom-AESEncryptedString $crypto $secret

I’ve been working on throwing together other code to mash it into one, I cant take all the credit for below.

Leave a Reply

Your email address will not be published. Required fields are marked *