Semnarea scripturilor PowerShell
I ❤️ PowerShell. Este un instrument foarte util pentru automatizarea acelor sarcini pe care le faci de mai multe ori. Dar poate fi, de asemenea, o gaură de securitate uriașă dacă o lăsați.
PowerShell vă permite să administrați aproape tot ce se află pe mașina dvs., așa că există o mulțime de daune care ar putea fi făcute de cineva capabil să ruleze scripturi malițioase în mediile dvs.
Confirmat anterior doar la Windows, începând cu versiunea 6 și acum, odată cu lansarea PowerShell 7.0, acesta poate fi implementat și pe Linux și MacOS. Cu toate acestea, acest articol vorbește despre Politicile de execuție care nu pot fi modificate în mediile care nu sunt Windows, astfel încât nu va oferi niciun beneficiu utilizatorilor de Linux/MacOS (ne pare rău).
Politici de execuție
O modalitate prin care puteți restricționa capacitatea de a rula scripturi în mediile Windows este de a utiliza politicile de execuție ale PowerShell. Tldr este că acestea pot fi utilizate pentru a restricționa scripturile care vor rula în mediu. Opțiunile disponibile, de la cea mai puțin sigură la cea mai sigură, sunt:
Bypass
Nimic nu este blocat.
Unrestricted (Se aplică întotdeauna pe mașinile Non-Windows)
La fel ca ByPass
, dar solicită utilizatorului înainte de a rula scripturi de pe internet.
RemoteSigned (implicit pentru serverele Windows)
Scriptele care au fost descărcate de pe internet pot fi rulate numai dacă sunt semnate. Scripturile scrise pe mașină pot fi rulate
AllSigned
Toate scripturile trebuie să fie semnate înainte de a fi rulate
Restricted (implicit pentru clienții Windows)
Previne rularea scripturilor. Poate rula doar comenzi individuale.
Rularea scripturilor
Dacă doriți să rulați propriile scripturi PowerShell pe serverul dvs. Dar primiți un PSSecurityException
ca următorul PSSecurityException
.
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
O modalitate de a rezolva această problemă este de a schimba politica de execuție folosind comanda Set-ExecutionPolicy
și de a reduce securitatea mașinii. Aceasta este, în general, o idee proastă.
Personal, nu aș folosi niciodată ceva mai puțin sigur decât RemoteSigned
pe un server, dar AllSigned
în mod ideal.
Ce este o semnătură de script?
Prezumabil că doriți să mențineți securitatea mașinii și să nu deschideți o vulnerabilitate, așa că opțiunea care vă rămâne este să vă semnați scripturile.
Semnarea unui script înseamnă că cineva care are acces la cheia privată pentru un certificat de semnare a codului a adăugat un bloc de semnătură la sfârșitul fișierului de script.
function Get-Wibble { return "Wibble"}# SIG # Begin signature block# vpnIUpm2XxLRhU1no0iuA62xKxYzR6m95z9Ax21ppeTC9NoRd8ocoSGr1zAd# qlMOlz4lZoVWR4ZmtdCgzde1dVxzv4jjHb6ziDiY2o05UXswD2bl6XaOrUpd# Li0Qjg3d3y2r1nrpO8hos906bgXQswysvouegUJcpt8ftmqBKfEYNeBgnBFm# SIG # End signature block
(Doar un exemplu. Blocul de semnătură este, de obicei, mult mai lung)
Blocul de semnătură va conține un hash al scriptului care a fost criptat cu ajutorul cheii private. La încercarea de a rula scriptul, acesta este decriptat cu ajutorul cheii publice și comparat cu hash-ul real. Dacă se potrivește, atunci putem confirma că scriptul nu a fost modificat, deoarece hash-ul s-ar schimba imediat ce s-ar întâmpla acest lucru.
Certificate cu autofirmare
Dacă scripturile dvs. vor fi rulate doar de mașinile din organizația dvs., atunci cel mai probabil veți putea autofirma certificatele. Alternativa este să cheltuiți $$$ și să cumpărați un certificat de semnare a codului în fiecare an.
Autosemnarea înseamnă că veți genera singur certificatul și veți semna scripturile folosind acest certificat.
Cum să creați un certificat de auto-semnare
PowerShell are comanda foarte utilă New-SelfSignedCertificate
pentru a produce certificate auto-semnate. Putem apoi să le exportăm și să le plasăm în diferite magazine.
În mod implicit, comanda va crea un certificat care expiră după 1 an. Puteți schimba acest lucru folosind parametrul -NotAfter
și furnizându-i data la care doriți ca certificatul să expire.
Pentru a crea un certificat porniți o sesiune PowerShell și rulați următoarele
$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"
Acest lucru va crea certificatul și îl va exporta în două fișiere separate cu extensiile .pfx
și .cer
.
PFX
Certificatul PFX este cel care va trebui să fie instalat pe mașinile care vor face semnarea. În cazul nostru, acesta este fiecare dintre mașinile dezvoltatorilor noștri.
Ar trebui să fie instalat în magazinul cert:\CurrentUser\Root
, cunoscut și sub numele de magazinul „Trusted Root Certification Authorities”.
Acest fișier trebuie păstrat într-un loc sigur. Parola ar trebui apoi să fie securizată separat (utilizați un manager de parole). Dacă un actor rău intenționat intră în posesia ambelor, atunci își poate semna scripturile malițioase ca și cum ar fi în locul dumneavoastră.
CER
Fisierul de certificat CER este ceea ce va trebui să instalați pe mașinile care vor rula scripturile. Acesta nu va necesita o parolă pentru a fi instalat, dar nu poate fi folosit pentru a semna scripturile. Acesta conține doar cheia publică folosită pentru decriptarea semnăturii.
Pentru că nu conține cheia privată, acest certificat poate fi distribuit liber în toate mediile care vor rula scripturile.
Acesta va trebui instalat în două magazine de certificate pe mașinile care vor rula scripturile; Magazinele cert:\LocalMachine\Root
și cert:\LocalMachine\TrustedPublisher
.
Semnarea unui script
Funcția Set-AuthenticodeSignature
este furnizată pentru a semna scripturile. Trebuie să transmitem calea către script și certificatul din magazin. Am scris o funcție wrapper care poate semna scripturile.
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 }}
Variabila $certificateName
trebuie să conțină numele utilizat la crearea certificatului.
Puteți utiliza funcția furnizând o cale către directorul care conține scripturile și aceasta va trece în buclă prin ele, semnându-le pe toate.
După ce ați instalat scripturile pe mașina țintă, ar trebui să puteți acum să rulați scripturile fără probleme.
.