Ochrana heslom a šifrovanie v skriptoch PowerShell

Pri písaní automatizačných skriptov v PowerShell správcovia často píšu heslá priamo do tela skriptu PoSh. Ako viete, toto je extrémne nebezpečné, keď sa používa v produktívnom prostredí, pretože ostatní používatelia servera alebo správcovia ho môžu vidieť v jasnej podobe. Preto je vhodné používať bezpečnejšie metódy na používanie hesiel v skriptoch PowerShell alebo na šifrovanie hesiel, ak nemôžete použiť interaktívny vstup.

Je bezpečné požiadať používateľa o interaktívne zadanie hesla v skripte pomocou rutiny cmdlet Získajte poverenie. Napríklad požadujeme užívateľské meno a heslo a uložíme ich do objektu typu PSCredential:

$ Cred = Získajte poverenie

Pri prístupe k vlastnostiam premennej môžete zistiť meno zadaného používateľa.

$ Cred.Užívateľské meno

Ale keď sa pokúsite zobraziť heslo, text System.Security.SecureString bude vrátený, pretože heslo je teraz uložené ako SecureString.

$ Cred.Password

Objekt PSCredential, ktorý sme uložili do premennej $ Cred, sa teraz dá použiť v cmdletoch, ktoré podporujú tento typ objektu..

Parametre $ Cred.Username a $ Cred.Password sa dajú použiť v cmdlets, ktoré nepodporujú objekty PSCredential, ale vyžadujú samostatné užívateľské meno a heslo.

Rutinu Read-Host môžete použiť aj s atribútom AsSecureString a požiadať o heslo používateľa:
$ pass = Read-Host "Zadajte heslo" -AsSecureString

V takom prípade nebudete môcť vidieť ani obsah premennej $ pass, v ktorej je uložené heslo.

Vo vyššie uvedených metódach použitia hesla v skriptoch PowerShell sa predpokladalo, že pri spustení skriptu bolo heslo zadané interaktívne. Táto metóda však nie je vhodná pre rôzne scenáre, ktoré sa spúšťajú automaticky alebo prostredníctvom plánovača.

V takom prípade je vhodnejšie zašifrovať údaje účtu (meno a heslo) a uložiť ich v zašifrovanej podobe do textového súboru na disku alebo použiť priamo v skripte.

Takže pomocou cmdlet ConvertFrom-SecureString Heslo môžete previesť z formátu SecureString na šifrovaný reťazec (šifrovanie sa vykonáva pomocou rozhrania Windows Data Protection API - DPAPI). Šifrované heslo môžete zobraziť na obrazovke alebo ho uložiť do súboru:

$ Cred.Password | ConvertFrom-SecureString | Set-Content c: \ ps \ passfile.txt

Ak chcete použiť šifrované heslo zo súboru, musíte pomocou cmdlet vykonať spätný prevod do formátu Securestring. ConvertTo-SecureString:

$ username = "corp \ administrator"
$ pass = Get-Content c: \ ps \ passfile.txt | ConvertTo-SecureString
$ creds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $ username, $ pass

Takže v premennej $ creds sme dostali objekt PSCredential s užívateľskými povereniami.

Ak sa však pokúsite skopírovať súbor passfile.txt na iný počítač alebo ho použiť pod iným používateľom (nie s tým, pod ktorým bolo vytvorené heslo), uvidíte, že premenná $ creds.password je prázdna a neobsahuje heslo. Faktom je, že šifrovanie pomocou DPAPI sa vykonáva pomocou kľúčov uložených v užívateľskom profile. Bez týchto kľúčov na inom počítači nemôžete dešifrovať súbor pomocou hesla.
ConvertTo-SecureString: Kľúč nie je možné použiť v určenom stave.
"Argument sa nedá spracovať, pretože hodnota argumentu hesla je NULL.
Zadajte pre argument hesla hodnotu, ktorá nie je NULL. “

Preto, ak sa skript spustí pod iným (servisným) účtom alebo na inom počítači, musíte použiť iný šifrovací mechanizmus, ktorý je jedinečný pre DPAPI. Cudzí šifrovací kľúč možno zadať pomocou týchto parametrov -kľúč alebo -SecureKey.

Napríklad môžete použiť PowerShell na vygenerovanie 256-bitového kľúča AES, ktorý môžete použiť na dešifrovanie súboru. Uložte kľúč do textového súboru password_aes.key.

$ AESKey = Byte nového objektu [] 32
[Security.Cryptography.RNGCryptoServiceProvider] :: Create (). GetBytes ($ AESKey)
$ AESKey | out-file C: \ ps \ password_aes.key

Teraz môžete uložiť heslo do súboru pomocou tohto kľúča:

$ Cred.Password | ConvertFrom-SecureString -Key (obsah C: \ ps \ password_aes.key) | Set-Content c: \ ps \ passfile.txt

Nezabudnite, že ak zadáte účet domény v skripte Powershell a máte v ňom pravidelnú politiku zmeny hesla, budete musieť tento súbor aktualizovať zakaždým, keď sa heslo zmení (pre určité účty môžete vytvoriť samostatnú politiku hesiel pomocou viacerých hesiel FGPP).

Takto sme dostali dva súbory: súbor so šifrovaným heslom (passfile.txt) a súbor so šifrovacím kľúčom (password_aes.key).

Môžete ich preniesť do iného počítača a pokúsiť sa získať heslo zo súboru z prostredia PowerShell (súbor s kľúčmi môžete umiestniť do sieťového adresára)

$ pass = Get-Content c: \ ps \ passfile.txt | ConvertTo-SecureString -Key (get-content \\ Server1 \ Share \ password_aes.key)
$ pass

Ak sa nechcete obťažovať so samostatným súborom s kľúčom AES, môžete zašiť šifrovací kľúč priamo do skriptu. V takom prípade musíte namiesto kľúča v oboch prípadoch použiť

[Byte []] $ key = (1 ... 16)
$ Cred.Password | ConvertFrom-SecureString -Key $ key | Set-Content c: \ ps \ passfile.txt

A pre dešifrovanie:

[Byte []] $ key = (1 ... 16)
$ pass = Get-Content c: \ ps \ passfile.txt | ConvertTo-SecureString - Kľúč $

Ako vidíte, heslo nie je prázdne, čo znamená, že bolo úspešne dešifrované a môže sa použiť na iných počítačoch.

rada. Prístup do súboru je potrebné obmedziť pomocou kľúča AES, aby k nemu mal prístup iba používateľ alebo účet, pod ktorým je skript spustený. Pri umiestňovaní do sieťového adresára starostlivo skontrolujte povolenia NTFS v súbore password_aes.key.

A nakoniec najsmutnejší moment. Heslo z objektu PSCredential vo voľbe je vytiahnuté veľmi jednoducho:

$ Cred.GetNetworkCredential (). Heslo

Heslo môžete extrahovať v textovej podobe zo SecureString:

$ BSTR = [System.Runtime.InteropServices.Marshal] :: SecureStringToBSTR ($ pass)
[System.Runtime.InteropServices.Marshal] :: PtrToStringAuto ($ BSTR)

Ako viete, z tohto dôvodu je nežiaduce ukladať heslá pre privilegované účty, ako sú Domain Admins, kdekoľvek okrem DC.

Rada. Na ochranu administratívnych záznamov pred extrahovaním hesiel z pamäte pomocou nástrojov, ako je Mimikatz, musíte použiť komplexné opatrenia vrátane organizačného plánu.