Tag Archives: security

Generate-Key

To compliment my earlier post I have created a short function to generate keys.

Function Generate-key{
Param(
    [validateset(128,192,256)]
    $bits,
    [switch]$COUT,
    $seed
)
    $bytes = $bits/8
    $array = @()
    If($seed){
        1..$bytes | ForEach-Object{
            $array += Get-Random -Minimum 0 -Maximum 255 -SetSeed $seed
        }
    }
    Else{
        1..$bytes | ForEach-Object{
            $array += Get-Random -Minimum 0 -Maximum 255
        }
    }
    If($COUT){
        [string]$retval = ($array -join ',') 
        Return $retval
    }
    Else{
        Return [Byte[]]$Key = $array
    }
}

Encrypting strings with custom keys in powershell

Since the ConvertTo-SecureString is not really secure, and neither is the EncodedCommand (base64string) I made two short functions to encrypt and decrypt strings in order to send them across the void unharmed.

Function Encrypt-String{
Param(
    
    [Parameter(
        Mandatory=$True,
        Position=0,
        ValueFromPipeLine=$true
    )]
    [Alias("String")]
    [String]$PlainTextString,
    
    [Parameter(
        Mandatory=$True,
        Position=1
    )]
    [Alias("Key")]
    [byte[]]$EncryptionKey
)
    Try{
        $secureString = Convertto-SecureString $PlainTextString -AsPlainText -Force
        $EncryptedString = ConvertFrom-SecureString -SecureString $secureString -Key $EncryptionKey

        return $EncryptedString
    }
    Catch{Throw $_}

}

this function accepts a string, a key and outputs the encryptedstring.

To encrypt call the function with a plaintext string and a key. the key must be a byte array with 16,24 or 32 bytes (128,192 or 256 bits)

Calling the function looks like this.

$string = @'
I am about to become encrypted!
'@

[Byte[]]$Key = 117,9,103,192,133,20,53,149,81,95,108,34,81,224,226,220,56,68,133,120,139,241,176,239,171,54,231,205,83,57,51,255

$EncryptedString = Encrypt-String -PlainTextString $string -Key $Key

The output becomes

PS> $encryptedString
76492d1116743f0423413b16050a5345MgB8AG8AVABnAGcAagArAFYAUgBoAGkAYwBOAFIAZgBTAGEAQQB1AGsAMQBmAHcAPQA9
AHwAZQBiADIAOAA4ADQAYwA5ADEAMABlAGMAOABmADUAOAAyAGIANQAzADIAOABjADIAOAAxADUAZgAxADYAMgAyAGQAMgA2AGUA
ZQA2ADYANAA2AGUAYQA0AGMAMgBmADMAYgAwADIAMgAxAGQAOQAxADcANwBhADgANwAxADcAZgBjADEANwAxADcANwA1ADgANwBh
ADMAMgA3AGEAMABmADcAYQAzADcAYQBiADgANAAwADkAOQA4ADgANgA1AGYAMwA5ADMANAA3ADkAZgAwAGIAZAA1AGQAZgA2AGEA
MABmADIANwBmADkANQBhAGYAOAAxAGYANgA0ADAAOAAxAA==

Now to the decrypt. This function needs the exact encryptedstring and the exact key that the string was encoded with.

Function Decrypt-String{
Param(
    [Parameter(
        Mandatory=$True,
        Position=0,
        ValueFromPipeLine=$true
    )]
    [Alias("String")]
    [String]$EncryptedString,

    [Parameter(
        Mandatory=$True,
        Position=1
    )]
    [Alias("Key")]
    [byte[]]$EncryptionKey
)
    Try{
        $SecureString = ConvertTo-SecureString $EncryptedString -Key $EncryptionKey
        $bstr = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecureString)
        [string]$String = [Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr)
        [Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr)

        Return $String
    }
    Catch{Throw $_}

}

To call this function simply input the encryptedString and key and you get the pre-encrypted string as the return value.

PS> Decrypt-String -EncryptedString $EncryptedString -EncryptionKey $Key
I am about to become encrypted!

Both functions accept value by pipeline so a Get-content can be used like this.

Get-Content C:\temp\encrypted.txt | Decrypt-String -EncryptionKey $Key

An overkill version of this is to double encode/encrypt. First convert the string to a base64 (encodedCommand style) then encode it with the key. This really adds no further security except to obfuscate the encrypted package and in case someone gets the key to decrypt they have to convert the encodedcommand to a string from base 64

Function Encrypt-String{
Param(
    
    [Parameter(
        Mandatory=$True,
        Position=0,
        ValueFromPipeLine=$true
    )]
    [Alias("String")]
    [String]$PlainTextString,
    
    [Parameter(
        Mandatory=$True,
        Position=1
    )]
    [Alias("Key")]
    [byte[]]$EncryptionKey
)
    Try{
        $bytes = [System.Text.Encoding]::Unicode.GetBytes($PlainTextString)
        $encodedCommand = [Convert]::ToBase64String($bytes)
        $secureString = Convertto-SecureString $encodedCommand -AsPlainText -Force
        $EncryptedString = ConvertFrom-SecureString -SecureString $secureString -Key $EncryptionKey

        return $EncryptedString
    }
    Catch{Throw $_}

}


Function Decrypt-String{
Param(
    [Parameter(
        Mandatory=$True,
        Position=0,
        ValueFromPipeLine=$true
    )]
    [Alias("String")]
    [String]$EncryptedString,

    [Parameter(
        Mandatory=$True,
        Position=1
    )]
    [Alias("Key")]
    [byte[]]$EncryptionKey
)
    Try{
        $SecureString = ConvertTo-SecureString $EncryptedString -Key $EncryptionKey
        $bstr = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecureString)
        [string]$String = [Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr)
        [Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr)

        $data = @()
        [convert]::FromBase64String($encodedCommand) | ForEach-Object{
            If($_ -ne 0){
                $data += [char]$_
            }
        }

        Return ($data -join '')
    }
    Catch{Throw $_}

}

Retreive passwords through GPO/GPP with powershell.

There is a known vulnerability in windows where all passwords stored in Group policy preferences are encrypted with a public AES key (link to msdn).

In this post we will go through how to get all the usernames and passwords from group policies in the minimum amount of time with maximum amount of data so we can infiltrate the domain.

What we will need is a fast USB stick loaded with a set of scripts. (attached at the bottom of the post)

First we want to retreive all XML files that may contain passwords. We do this by a query to the SYSVOL. This is the bulk of the time and it is recommended to perform this first if you’re using this on someone else’s computer (perhaps forgot to lock or in a public area).
For this run “Get-GPPXML.ps1”

If there is still time, we can go ahead and encrypt by running “Decrypt-passwords.ps1”, this will save it as a csv file to be opened in excel with the following headers for easy reading.
Domain Usernames Passwords NewNames(might be reset) File ChangedTimestamp

http://saemundsson.se/wp-content/uploads/2015/02/Get-GPPPasswords.zip