PowerShell szkriptek aláírása
I ❤️ PowerShell. Ez egy igazán hasznos eszköz azoknak a feladatoknak az automatizálásához, amelyeket többször is elvégezünk. De egyúttal egy tátongó biztonsági rés is lehet, ha hagyod.
A PowerShell lehetővé teszi, hogy szinte mindent adminisztráljon a gépén, így rengeteg kárt okozhat, ha valaki képes rosszindulatú szkripteket futtatni a környezetében.
A korábban csak Windowsra korlátozódott, a 6. verzió óta, és most a PowerShell 7.0 kiadásával Linuxon és MacOS-en is telepíthető. Ez a cikk azonban a Végrehajtási házirendekről szól, amelyek nem módosíthatók a nem Windows környezetekben, így a Linux/MacOS felhasználók számára nem jelentenek előnyt (bocsánat).
Végrehajtási házirendek
A PowerShell végrehajtási házirendjeinek használatával korlátozhatja a parancsfájlok futtatásának lehetőségét a Windows környezetekben. A tldr az, hogy ezekkel korlátozhatók a környezetben futtatható parancsfájlok. A rendelkezésre álló lehetőségek a legkevésbé biztonságostól a legbiztonságosabbig a következők:
Bypass
Nem blokkol semmit.
Korlátozás nélküli (Nem Windows gépeken mindig érvényes)
Az ByPass
-vel megegyező, de az internetről származó szkriptek futtatása előtt megkérdezi a felhasználót.
RemoteSigned (alapértelmezett Windows szerverek esetén)
Az internetről letöltött szkriptek csak akkor futtathatók, ha alá vannak írva. A gépen írt parancsfájlok futtathatók
AllSigned
Minden parancsfájlt alá kell írni a futtatásuk előtt
Restricted (alapértelmezett Windows klienseknél)
Elakadályozza a parancsfájlok futtatását. Csak egyedi parancsok futtatására képes.
Szkriptek futtatása
Szerveren szeretné futtatni saját PowerShell szkriptjeit. De a következőhöz hasonló PSSecurityException
üzenetet kap.
PS C:\Users\Administrator\Downloads> .\wibble.ps1.\wibble.ps1 : File .\wibble.ps1 cannot be loaded. The file.\wibble.ps1 is not digitally signed. You cannot run this script on the current system.For more information about running scripts and setting execution policy, see about_Execution_Policies athttp://go.microsoft.com/fwlink/?LinkID=135170.At line:1 char:1+ .\wibble.ps1+ ~~~~~~~~~~~~ + CategoryInfo : SecurityError: (:) , PSSecurityException + FullyQualifiedErrorId : UnauthorizedAccess
A probléma megoldásának egyik módja, hogy a Set-ExecutionPolicy
parancs segítségével megváltoztatja a végrehajtási házirendet, és csökkenti a gép biztonságát. Ez általában rossz ötlet.
Személy szerint én soha nem használnék a RemoteSigned
-nél kevésbé biztonságosat egy szerveren, de a AllSigned
ideális esetben.
Mi az a script aláírás?
Vélhetően meg akarod tartani a gép biztonságát, és nem akarsz sebezhetőséget nyitni, ezért az a lehetőség marad számodra, hogy aláírod a scriptjeidet.
A szkript aláírása azt jelenti, hogy valaki, aki hozzáfér a kódaláíró tanúsítvány magánkulcsához, egy aláírási blokkot illeszt a szkriptfájl végére.
function Get-Wibble { return "Wibble"}# SIG # Begin signature block# vpnIUpm2XxLRhU1no0iuA62xKxYzR6m95z9Ax21ppeTC9NoRd8ocoSGr1zAd# qlMOlz4lZoVWR4ZmtdCgzde1dVxzv4jjHb6ziDiY2o05UXswD2bl6XaOrUpd# Li0Qjg3d3y2r1nrpO8hos906bgXQswysvouegUJcpt8ftmqBKfEYNeBgnBFm# SIG # End signature block
(Csak példa. Az aláírási blokk általában sokkal hosszabb)
Az aláírási blokk a magánkulccsal titkosított szkript kivonatát tartalmazza. A szkript futtatásának megkísérlésekor ezt a nyilvános kulcs segítségével visszafejtik, és összehasonlítják a tényleges hash-val. Ha egyezik, akkor megerősíthetjük, hogy a szkriptet nem manipulálták, mivel a hash megváltozik, amint ez megtörténik.
Önaláíró tanúsítványok
Ha a szkripteket csak a szervezeten belüli gépek fogják futtatni, akkor a tanúsítványokat valószínűleg önaláírással is alá lehet írni. Az alternatíva az, hogy minden évben $$$-t kell költenie és kódaláíró tanúsítványt vásárolnia.
Az önaláírás azt jelenti, hogy a tanúsítványt saját maga generálja, és a szkripteket ennek segítségével írja alá.
Hogyan készítsünk önaláíró tanúsítványt
A PowerShell rendelkezik a nagyon hasznos New-SelfSignedCertificate
paranccsal az önaláíró tanúsítványok előállításához. Ezeket aztán exportálhatjuk és elhelyezhetjük különböző tárolókban.
A parancs alapértelmezés szerint olyan tanúsítványt hoz létre, amely 1 év múlva lejár. Ezt megváltoztathatjuk a -NotAfter
paraméterrel, és megadhatjuk a tanúsítvány lejárati dátumát.
A tanúsítvány létrehozásához indítsunk el egy PowerShell munkamenetet, és futtassuk a következőt
$CertificateName = Read-Host "Input your certificate name"$OutputPFXPath = "$CertificateName.pfx"$OutputCERPath = "$CertificateName.cer"$Password = Get-Credential -UserName Certificate -Message "Enter a secure password:"$certificate = New-SelfSignedCertificate -subject $CertificateName -Type CodeSigning -CertStoreLocation "cert:\CurrentUser\My"$pfxCertificate = Export-PfxCertificate $certificate -FilePath $OutputPFXPath -password $Password.passwordExport-Certificate -Cert $certificate -FilePath $OutputCERPathImport-PfxCertificate $pfxCertificate -CertStoreLocation cert:\CurrentUser\Root -Password $password.passwordWrite-Output "Private Certificate '$CertificateName' exported to $OutputPFXPath"Write-Output "Public Certificate '$CertificateName' exported to $OutputCERPath"
Ez létrehozza a tanúsítványt, és két különálló fájlba exportálja .pfx
és .cer
kiterjesztéssel.
PFX
A PFX tanúsítványt kell telepíteni az aláírást végző gépekre. A mi esetünkben ez minden fejlesztői gépünk.
Ezt a cert:\CurrentUser\Root
tárolóba kell telepíteni, más néven a “Trusted Root Certification Authorities” tárolóba.
Ezt a fájlt egy biztonságos helyen kell tárolni. A jelszót ezután külön kell biztosítani (jelszókezelőt kell használni). Ha egy rossz szereplő mindkettőt megszerzi, akkor úgy írhatja alá a rosszindulatú szkriptjeit, mintha az Ön helyében lenne.
CER
A CER tanúsítványfájlt kell telepítenie a gépekre, amelyeken a szkriptek futni fognak. Ennek telepítéséhez nem lesz szükség jelszóra, de a szkriptek aláírására nem használható. Csak az aláírás visszafejtéséhez használt nyilvános kulcsot tartalmazza.
Mivel nem tartalmazza a privát kulcsot, ez a tanúsítvány szabadon terjeszthető minden olyan környezetben, ahol a szkriptek futni fognak.
Ezt két tanúsítványtárba kell telepíteni a szkripteket futtató gépeken; A cert:\LocalMachine\Root
és a cert:\LocalMachine\TrustedPublisher
tárba.
Szkript aláírása
A szkriptek aláírására a Set-AuthenticodeSignature
funkció szolgál. Át kell adnunk a szkript elérési útvonalát és a tanúsítványt a tárolóból. Írtunk egy wrapper függvényt, amely képes aláírni a szkripteket.
function Set-ScriptSignatures { param ( $pathToScripts = "." ) $certificateName = "PowerShell Signing Certificate" $scripts = Get-ChildItem -Path "$pathToScripts\*" -Include *.ps1, *.psm1 -Recurse $certificate = @(Get-ChildItem cert:\CurrentUser\My -codesign | Where-Object { $_.issuer -like "*$certificateName*" } ) foreach ($script in $scripts) { Write-Host "Signing $script" Set-AuthenticodeSignature $script -Certificate $certificate }}
A $certificateName
változónak tartalmaznia kell a tanúsítvány létrehozásakor használt nevet.
A funkciót úgy használhatja, hogy megadja a szkripteket tartalmazó könyvtár elérési útvonalát, és a program végigmegy rajtuk, aláírva az összeset.
Mihelyt telepítette a szkripteket a célgépre, most már minden gond nélkül futtathatja a szkripteket.