SlideShare ist ein Scribd-Unternehmen logo
1 von 18
Downloaden Sie, um offline zu lesen
C12_Sicherheit-an-PowerShell.md 7/11/2020
1 / 18
PowerShell in 7 Schritten produktiv absichern
Powered by
_ _ _ _ _ _ _
| | | | (_) | | | (_) | |
__ _| |_| |_ _| | __ _| | ___ __ _ ___| | __ ___ ___ _ __ ___
/ _` | __| __| | |/ _` | |/ / '__| |/ __| |/ / / __/ _ | '_ ` _ 
| (_| | |_| |_| | | (_| | <| | | | (__| < | (_| (_) | | | | | |
__,_|__|__|_|_|__,_|_|__| |_|___|_|_(_)______/|_| |_| |_|
---------------------- HTTPS://ATTILAKRICK.COM ---------------------
PowerShell Sicherheit - Die Keywords
Zusammenfassungen
Welche Sicherheitsmaßnahmen stehen dem Administrator zur Verfügung, um die PowerShell produktiv
abzusichern und trotzdem administrative Aufgaben an Nicht-Administratoren zu delegieren (Just Enough
Administration, JEA)? Wie können verdächtige und unerwünschte Aktivitäten protokolliert werden
(ScriptBlockLogging)? Wie sollten die Ausführungsrichtlinien eingestellt sein und was bedeutet das für den
Betrieb? Solche und noch weitere Fragen werden hier geklärt, um die Sicherheit an der PowerShell zu
erhöhen.
Schlagwörter
Sicherheit, ExecutionPolicy, ScriptBlockLogging, LanguageMode, JEA
Version
2020.07.02
Permalink
https://attilakrick.com/powershell/powershell-sicherheit/
Einführung
Die PowerShell ist ein Bestandteil des Betriebssystems. Daher sorgt ein generelles Blockieren nur für
scheinbare PowerShell Sicherheit. Den besten Schutz versprechen die Schutz- und Protokollierungs-
Mechanismen von PowerShell selbst.
In diesem Artikel beleuchte wir das Thema PowerShell Sicherheit aus dem Blickwinkel eines Administrators.
Wie PowerShell produktiv abgesichert wird, um trotzdem administrative Aufgaben an Nicht-Administratoren
zu delegieren (Just Enough Administration). Auch geht es darum verdächtige und unerwünschte Aktivitäten zu
protokollieren (ScriptBlockLogging).
C12_Sicherheit-an-PowerShell.md 7/11/2020
2 / 18
TIPP - Neben der administrativen Absicherung, um die PowerShell Sicherheit zu erhöhen, sollten Sie
auch mit sensiblen Daten wie Zugangsdaten, Geheimnisse und Zugangsbeschränkungen entsprechend
umgehen und schützen. Wie Sie das in PowerShell realisieren, finden Sie im Artikel "Mit Sicherheit in
der PowerShell umgehen".
INTERESSANT - Eine gründliche Analyse der Sicherheittechnologie zwischen verfügbaren Shells und
Skriptsprachen finden Sie in dem Artikel Ein Vergleich der Sicherheit von Shell und Skriptsprache.
Altlasten entfernen erhöht die PowerShell Sicherheit
Unbedingt sollten Sie PowerShell 2.0 deinstallieren. Mit dieser alten Shell-Version lassen sich alle
wesentlichen Restriktionen für PowerShell unterlaufen. Das optionale Feature ist vorinstalliert und kann aber
ab Windows 8.1 und Server 2012 deinstalliert werden.
Statische Strings erhöht die Sicherheit
Grundsätzlich immer die einfachen Hochkommas ' verwenden. Es seiden man verwendet Variable im String,
erst dann die doppelten Hochkommas " verwenden. Das erhöht die Sicherheit da die Gefahr von String-
Injection minimiert wird.
# ! FALSCH
$Ort = "Würzburg"
# RICHTIG
$Ort = 'Würzburg'
$s = 'Hallo $Ort!'
# vs.
$s = "Hallo $Ort!"
Ausführungsrichtlinien korrekt konfigurieren
Die Ausführungsrichtlinie ist ein PowerShell Sicherheit-Funktion, die steuert unter welchen Bedingungen
Konfigurations- und Skript-Dateien ausgeführt werden. Die Ausführungsrichtlinien schränken
Benutzeraktionen nicht ein. Stattdessen helfen die Ausführungsrichtlinien Benutzern, dass sie nicht
unbeabsichtigt gegen diese Regeln verstoßen.
WICHTIG - Das Verändern der Ausführungsrichtlinien stellt NUR einen Schutz vor dem unbedarften
Ausführen von Skripts dar - MEHR NICHT!
# READ betroffene About-Seiten:
Get-Help -Name 'about_Execution_Policy' -ShowWindow
# ? Wie ist der aktuelle Status der Ausführungsrichtlinien:
Get-ExecutionPolicy -List
# ? Wie ist die Ausführungsrichtlinie für den aktuellen Script-Host eingestellt:
$env:PSExecutionPolicyPreference
C12_Sicherheit-an-PowerShell.md 7/11/2020
3 / 18
Empfohlene Einstellung für Client und Server: Alle ausführbaren Dateien müssen mit einem x.509-Zertifikat
signiert sein.
Set-ExecutionPolicy -ExecutionPolicy 'AllSigned' -Force
Empfohlene Einstellung für Test- und Entwicklungs-Systeme: Alle ausführbaren Dateien die Remote (z.B.
per Download oder UNC-Pfad, etc.) auf den PC gelangt sind, müssen mit einem X.509-Zertifikat signiert sein.
Diese Dateien werden an einem 'Download-Marker' identifiziert. Dieser kann per Cmdlet Unblock-File
wieder entfernt werden.
Set-ExecutionPolicy -ExecutionPolicy 'RemoteSigned' -Force
Für das automatische Ausführen von signierten Skripten müssen folgende Voraussetzungen erfüllt sein.
1. Das X.509-Zertifikat muss von einer "Vertrauenswürdigen Stammzertifizierungsstelle" (Root) abstammt
ODER es ist selbst in Root abgelegt!
2. Das X.509-Zertifikat muss im Zertifikatspeicher für "Vertrauenswürdige Herausgeber"
(TrustPublisher) enthalten ist.
Ausführungsrichtlinien per GPO steuern: Die Ausführungsrichtlinien können komfortable per GPO
eingestellt werden. Diese wiederum manipulieren folgende Registry-Schlüssel.
Get-ItemPropertyValue -Path
'Registry::HKEY_LOCAL_MACHINESOFTWAREMicrosoftPowerShell1ShellIdsMicrosoft.P
owerShell' -Name 'ExecutionPolicy'
Get-ItemPropertyValue -Path
'Registry::HKEY_LOCAL_MACHINESOFTWAREMicrosoftPowerShell1ShellIdsScriptedDia
gnostics' -Name 'ExecutionPolicy'
Get-ItemPropertyValue -Path
''Registry::HKEY_CURRENT_USERSoftwareMicrosoftPowerShell1ShellIdsMicrosoft.P
owerShell -Name 'ExecutionPolicy'
Skript benötigt erhöhte Admin-Rechte
Im administrativen Umfeld ist nötig, dass Skripte mit erhöhte Admin-Rechte laufen. Zum Skript-Beginn kann
man überprüfen ob die Admin-Rechte vorhanden sind. Sollte dies nicht der Fall sein so könnte das Skript zu
beginn abbrechen, anstatt fehlerhaft in der Mitte auszusteigen.
$IsElevatedAdminRights = ([Security.Principal.WindowsPrincipal]
[Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.W
indowsBuiltInRole]'Administrator')
if(-not $IsElevatedAdminRights) {
C12_Sicherheit-an-PowerShell.md 7/11/2020
4 / 18
throw 'Vorgang abgebrochen! Es werden erhöhte administrative Berechtigungen
benötigt!'
} else {
'Dieses Skript läuft mit erhöhten Admin-Berechtigungen!' | Write-Warning
}
PowerShell PKI-Handling
# READ betroffene Cmdlets:
Get-Command -Name '*' -Module 'PKI'
# ! Zertifikat erstellen:
using namespace 'Microsoft.CertificateServices.Commands'
$params = @{
FriendlyName = 'Superman'
Subject = 'CN=_Superman (Doctor S. Man),
E=s.man@krypton.universe'
HashAlgorithm = 'SHA512'
KeyAlgorithm = 'RSA'
KeyLength = 4096
KeyExportPolicy = [KeyExportPolicy]::ExportableEncrypted
KeySpec = [KeySpec]::KeyExchange
CertStoreLocation = 'Cert:CurrentUserMy'
Type = [CertificateType]::Custom
TextExtension = @('2.5.29.37=
{text}1.3.6.1.5.5.7.3.1,1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.3,1.3.6.1.5.5.7.3.4,1.3.
6.1.5.5.7.3.5,1.3.6.1.5.5.7.3.6,1.3.6.1.5.5.7.3.7,1.3.6.1.5.5.7.3.8,1.3.6.1.5.5.7.
3.9,1.3.6.1.4.1.311.80.1,1.3.6.1.4.1.311.10.3.4,1.3.6.1.4.1.311.10.3.4.1', `
'2.5.29.17=
{text}email=s.man@krypton.universe&upn=s.man@krypton.universe')
NotAfter = (Get-Date).AddMinutes(60)
AlternateSignatureAlgorithm = $true
}
$myPfxCert = New-SelfSignedCertificate @params
# ! Zertifikat exportieren:
$myPfxCert | Export-PfxCertificate -Password (Read-Host -Prompt 'Set PFX-Password
for Superman' -AsSecureString) -FilePath 'C:TempSuperman.pfx'
$myPfxCert | Export-Certificate -Type 'CERT' -Force -FilePath
'C:TempSuperman.cer'
# ! Zertifikat im Zertifikats-Speicher löschen:
Get-ChildItem -Path 'Cert:CurrentUser' -Recurse | Where-Object -Property
'Thumbprint' -CEQ $myPfxCert.Thumbprint | Remove-Item -Force -Recurse
# ! Zertifikat importieren:
C12_Sicherheit-an-PowerShell.md 7/11/2020
5 / 18
Import-Certificate -FilePath 'C:TempSuperman.cer' -CertStoreLocation
'Cert:LocalMachineRoot'
Import-PfxCertificate -FilePath 'C:TempSuperman.pfx' -CertStoreLocation
'Cert:CurrentUserMy' -Password (Read-Host -Prompt 'PFX-Password for Superman' -
AsSecureString)
# ! Zertifikat aus dem Dateisystem lesen und auf Verwendungszweck testen:
Get-PfxData -Password (Read-Host -Prompt 'PFX-Password for Superman' -
AsSecureString) -FilePath 'C:TempSuperman.pfx' | Format-List -Property '*'
$test = Get-PfxCertificate -FilePath 'C:TempSuperman.pfx'
Test-Certificate -Cert $test -Policy 'SSL' | Write-Warning
Test-Certificate -Cert $test -EKU '1.3.6.1.5.5.7.3.1' | Write-Warning # = Server
Authentication
# ! Zertifikat aus dem Cert-Speicher lesen und auf Verwendungszweck testen:
Get-ChildItem -Path 'Cert:CurrentUserMy' | Where-Object -Property 'Subject' -
CLike -Value 'CN=_Superman (Doctor S. Man), E=s.man@krypton.universe' | Test-
Certificate -Policy 'SSL' | Write-Warning
Get-ChildItem -Path 'Cert:LocalMachineRoot' | Where-Object -Property 'Subject' -
CLike -Value 'CN=_Superman (Doctor S. Man), E=s.man@krypton.universe' | Test-
Certificate -EKU '1.3.6.1.5.5.7.3.1' | Write-Warning
# TODO Aufräumen:
Remove-Item -Path 'C:TempSuperman.*' -Force
Get-ChildItem -Path 'Cert:LocalMachine', 'Cert:CurrentUser' -Recurse | Where-
Object -Property 'Subject' -CLike -Value 'CN=_Superman (Doctor S. Man),
E=s.man@krypton.universe' | Remove-Item -Force
PowerShell Script-Dateien signieren
Warum sollte man signieren:
1. Eine Signatur schützt ein Skript (.PS1, .PSM1, .PS1XML, ...) vor Manipulation und erhöht so die
PowerShell Sicherheit!
2. Der Signierer bestätigt mit seiner Signatur den endgültigen Status des Skriptes!
3. Dritte können erkennen wer dieses Skript signiert / erstellt hat.
PowerShell kann über die Ausführungsrichtlinien so konfiguriert werden (AllSigned), dass nur Skripte
ausgeführt werden, wenn folgende Voraussetzungen erfüllt sind:
1. Die Skriptdatei wurde mit einem X.509-Zertifikat signiert!
2. Die signierte Datei wurde anschließend nicht manipuliert!
3. Das Signierer-Zertifikat stamm von einer "Vertrauenswürdigen Stammzertifizierungsstelle" (Root) ab
ODER es ist selbst in Root abgelegt worden!
C12_Sicherheit-an-PowerShell.md 7/11/2020
6 / 18
4. Signierer-Zertifikat wurde zusätzlich im Zertifikatspeicher für "Vertrauenswürdige Herausgeber"
(TrustPublisher) abgelegt!
Zum Beispiel an einer einfachen Umsetzung über ein selbstsigniertes Zertifikat:
# ! 1. Testumgebung vorbereiten
# Ausführungsrichtlinien auf AllSigned setzen
Set-ExecutionPolicy -ExecutionPolicy 'AllSigned' -Scope 'Process' -Force
Set-ExecutionPolicy -ExecutionPolicy 'AllSigned' -Scope 'CurrentUser' -Force
Set-ExecutionPolicy -ExecutionPolicy 'AllSigned' -Scope 'LocalMachine' -Force
# PKI Modul importieren
Import-Module -Name 'PKI' # Windows PowerShell
Import-WinModule -Name 'PKI' # bzw. PowerShell 7
# Test-Ordner C:Temp erstellen
New-Item -Path 'C:Temp' -ItemType 'Directory' -Force | Set-Location
# Test-Script erzeugen
'"> > > Execute Code from .PS1-Script! at $(Get-Date) < < <" | Write-Warning' |
Set-Content -Path '.Test.ps1' -Force
# ! 2. Aktuell wird das Ausführen des Skriptes mit einer Fehlermeldung abgebrochen
. '.Test.ps1'
# ! 3. Signierer-Zertifikate erstellen:
$params = @{
Subject = 'CN=_FirstName_LastName (PS Developer),
E=f.lastname@abc.local'
HashAlgorithm = 'SHA512'
KeyExportPolicy =
[Microsoft.CertificateServices.Commands.KeyExportPolicy]::ExportableEncrypted
CertStoreLocation = 'Cert:CurrentUserMy'
Type = [
Microsoft.CertificateServices.Commands.CertificateType]::CodeSigningCert
NotAfter = (Get-Date).AddYears(5)
}
$myPfxCert = New-SelfSignedCertificate @params
# ! 4. Aus dem Signierer-Zertifikat ein öffentliches Zertifikat erstellen:
$myPfxCert | Export-Certificate -FilePath '.PublicSignerCertificate.cer' -Type
'CERT' -Force
# ! 5. Vertrauensstellung einrichten:
# 1. im Zertifikatsspeicher Root abgelegt werden, um dem Zertifikat generell zu
vertrauen
Import-Certificate -FilePath '.PublicSignerCertificate.cer' -CertStoreLocation
'Cert:LocalMachineRoot'
# 2. im Zertifikatsspeicher TrustedPublisher abgelegt werden, um den signierten
C12_Sicherheit-an-PowerShell.md 7/11/2020
7 / 18
.PS1-Dateien im Besonderen zu vertrauen
Import-Certificate -FilePath '.PublicSignerCertificate.cer' -CertStoreLocation
'Cert:LocalMachineTrustedPublisher'
# ! 6. Das eigentliche Script signieren:
$params = @{
Certificate = $myPfxCert
HashAlgorithm = 'SHA512'
TimestampServer = 'http://timestamp.globalsign.com/scripts/timstamp.dll'
FilePath = '.Test.ps1'
}
Set-AuthenticodeSignature @params
# ! 7. Signiertes Script testen:
# ? Die digitale Signatur sollte GÜLTIG sein?
Get-AuthenticodeSignature -FilePath '.Test.ps1' | Format-List -Property *
# ? Wird .PS1-Datei nun problemlos ausgeführt?
. '.Test.ps1'
# ! 8. Aufräumen
Set-ExecutionPolicy -ExecutionPolicy 'RemoteSigned' -Scope 'Process' -Force
Set-ExecutionPolicy -ExecutionPolicy 'RemoteSigned' -Scope 'CurrentUser' -Force
Set-ExecutionPolicy -ExecutionPolicy 'RemoteSigned' -Scope 'LocalMachine' -Force
Get-ChildItem -Path 'Cert:CurrentUserMy', 'Cert:LocalMachineRoot',
'Cert:LocalMachineTrustedPublisher' | Where-Object Thumbprint -CEQ
$myPfxCert.Thumbprint | Remove-Item
Get-ChildItem -Path '.Test.ps1', '.PublicSignerCertificate.cer' | Remove-Item
TIPP - Vielleicht besitzen Sie ja schon ein entsprechendes Zertifikat zum Signieren. Lassen Sie sich diese wie
folgt anzeigen.
Get-ChildItem -Path 'Cert:CurrentUserMy' -CodeSigningCert
Einfache Host-Ein-/Ausgabe Protokollierung
Eine einfache Variante, um die PowerShell Sicherheit zu erhöhen, ist das Mitschneiden sämtlicher Aktivitäten
und deren Resultate auf einem PowerShell Host. Hierzu verwenden Sie die Cmdlets Start-Transcript und
Stop-Transcript.
# * 1. Transcript starten:
Start-Transcript -Path "C:TempPsHost.log" -Append -Force
# * 2. Test-Eingabe & -Ausgaben erzeugen:
Get-Process
Read-Host -Prompt "Passwort eingeben" -AsSecureString
# * 3. Transcript stoppen:
C12_Sicherheit-an-PowerShell.md 7/11/2020
8 / 18
Stop-Transcript -Verbose
# 4. Log-Datei Anzeigen:
Start-Process -FilePath "C:TempPsHost.log"
Wo und wann Sie Start-Transcript initiieren obliegt Ihnen. Denkbar wäre z.B. einer der Autostartdateien
(profile.ps1).
Aktivitäten mittels ScriptBlockLogging protokollieren
Wenn ScriptBlockLogging aktiviert ist werden sämtliche Befehle zu PowerShell-Vorgängen protokolliert.
Durch den lückenlosen Nachweis sämtlicher PowerShell-Aktivität wir die PowerShell Sicherheit weiter erhöht.
WICHTIG - Bzgl. PowerShell 7: Bevor Ereignisse in das Ereignisprotokoll geschrieben werden können,
muss im Gegensatz zu Linux oder macOS in Windows der Ereignisanbieter registriert sein. Führen Sie
dazu mit erhöhten Berechtigungen folgendes aus.
. "$PsHomeRegisterManifest.ps1"
Get-WinEvent -ListProvider '*powershell*' | Select-Object -Property 'Name'
Permanentes und sicheres Protokollieren sämtlicher Host-Aktivitäten mittels ScriptBlockLogging
aktivieren.
TIPP - ScriptBlockLogging per GPO unter Computerkonfiguration / Administrative Vorlagen
/ Windows-Komponenten / Windows PowerShell / Protokollierung von PowerShell-
Scriptblöcken aktivieren. ACHTUNG - z.Zt. nur für Windows PowerShell, andere Versionen nur per
folgenden Registry-Keys.
# ! Für PowerShell 7 und PowerShell Core:
New-Item -Path
'Registry::HKEY_LOCAL_MACHINESOFTWAREPoliciesMicrosoftPowerShellCore' -Name
'ScriptBlockLogging' -ItemType 'Key' -Force | New-ItemProperty -Name
'EnableScriptBlockLogging' -Value 1 -PropertyType 'DWord' -Force
# ! Für Windows PowerShell:
New-Item -Path
'Registry::HKEY_LOCAL_MACHINESOFTWAREPoliciesMicrosoftWindowsPowerShell' -
Name 'ScriptBlockLogging' -ItemType 'Key' -Force | New-ItemProperty -Name
'EnableScriptBlockLogging' -Value 1 -PropertyType 'DWord' -Force
# ! Für Windows PowerShell 32it:
Registry::HKEY_LOCAL_MACHINESOFTWAREWOW6432NodePoliciesMicrosoftWindowsPower
ShellScriptBlockLogging
# ! Für PowerShell Core 32bit:
Registry::HKEY_LOCAL_MACHINESOFTWAREWOW6432NodePoliciesMicrosoftWindowsPower
ShellCoreScriptBlockLogging
C12_Sicherheit-an-PowerShell.md 7/11/2020
9 / 18
Die so protokollierten Aktivitäten können nun wie folgt ausgewertet werden.
# Test-Code der gleich im Protokoll auftaucht:
Get-ChildItem -Path 'C:Temp'
# ! Auswertung:
Get-WinEvent -ListLog '*powershell*'
Get-WinEvent -FilterHashtable @{ LogName='PowerShellCore/Operational' ; Id="4104"
} | Select-Object -Property 'RecordId', 'ProcessId', 'MachineName', 'UserId',
'TimeCreated', 'Message' | Where-Object -Property 'Message' -IMatch -Value 'Get-
ChildItem'
# TODO Aufräumen:
. "$PsHomeRegisterManifest.ps1" -Unregister
Remove-Item -Path
'Registry::HKEY_LOCAL_MACHINESOFTWAREPoliciesMicrosoftPowerShellCoreScriptBlo
ckLogging' -Recurse -Force
Remove-Item -Path
'Registry::HKEY_LOCAL_MACHINESOFTWAREPoliciesMicrosoftWindowsPowerShellScrip
tBlockLogging' -Recurse -Force
TIPP - Um die PowerShell Sicherheit weiter zu erhöhen, sollten sensible Daten im Protokoll geschützt
werden. Dazu verschlüsseln Sie einfach die Logs (s. Protected Event Logging unter Get-Help -Name
'about_logging_windows' -ShowWindow).
Aktivitäten in der PowerShell-Session einschränken (LanguageMode)
Über $ExecutionContext.SessionState.LanguageMode können Sie weiter einschränken welche Cmdlets,
Typen und Interaktionen erlaubt sind, um die PowerShell Sicherheit weiter zu erhöhen.
# ! Zum Beispiel aktivieren per Autostart über eine der folgenden Dateien:
$profile.AllUsersAllHosts
$profile.AllUsersCurrentHost
# ! 1. Keine Anwendungen und Skripte ab jetzt erlauben:
$ExecutionContext.SessionState.Applications.Clear()
$ExecutionContext.SessionState.Scripts.Clear()
# ! 2. Erlaubte Cmdlets festlegen und die restlichen Cmdlets unsichtbar machen:
$allowedCommands = @()
$allowedCommands += "ForEach-Object"
$allowedCommands += "Get-ChildItem"
$allowedCommands += "Get-Command"
$allowedCommands += "Get-Member"
$allowedCommands += "Get-Module"
$allowedCommands += "Out-Default"
$allowedCommands += "Select-Object"
$allowedCommands += "Test-NetConnection"
$allowedCommands += "Where-Object"
C12_Sicherheit-an-PowerShell.md 7/11/2020
10 / 18
Get-Command -CommandType "Cmdlet", "Function" | Where-Object -Property Name -
NotIn -Value $allowedCommands | ForEach-Object -Process { $_.Visibility =
"Private" }
# ! 3. Den LanguageMode in den beschränkten Sprachmodus versetzen:
$ExecutionContext.SessionState.LanguageMode = "RestrictedLanguage"
Weitere LanguageMode-Details entnehmen Sie den entsprechenden About-Seiten.
# READ siehe auch:
Get-Help -Name 'about_Language_Modes' -ShowWindow
Get-Help -Name 'about_FullLanguage' -ShowWindow
Get-Help -Name 'about_RestrictedLanguage' -ShowWindow
Get-Help -Name 'about_ConstrainedLanguage' -ShowWindow
Um zu ermitteln in welchem Modi sich die aktuelle Sitzung befindet, können Sie die LanguageMode
Eigenschaft abfragen:
$ExecutionContext.SessionState.LanguageMode
Zu den wichtigsten PowerShell Sicherheits-mechanismen gehört der Constrained Language Mode (CLM) die
mehrere gefährlichen PowerShell-Features deaktiviert und so deren Missbrauch minimiert und die PowerShell
Sicherheit erhöht. Der ConstrainedLanguage-Modus erlaubt alle Cmdlets und alle PowerShell-
Sprachelemente, begrenzt jedoch die zulässigen Typen.
Wenn der LanguageMode auf ConstrainedLanguage steht werden folgende wichtige Funktionen geboten:
Alle Cmdlets in Windows-Modulen und andere von UMCI genehmigte Cmdlets sind voll funktionsfähig
und haben, sofern nicht anders angegeben, vollständigen Zugriff auf Systemressourcen.
Alle in Windows enthaltenen Module können importiert und alle Befehle, die die Module exportieren, in
der Sitzung ausgeführt werden.
Das Cmdlet Add-Type kann signierte Assembly laden, jedoch keinen beliebigen C# -Code oder Win32-
APIs.
Das Cmdlet New-Object kann nur für zulässige Typen verwendet werden (siehe unten).
Die Typkonvertierung ist zulässig, jedoch nur, wenn das Ergebnis ein zulässiger Typ ist.
Cmdlet-Parameter, die Zeichenfolgeneingaben in Typen konvertieren, funktionieren nur, wenn der
resultierende Typ ein zulässiger Typ ist.
Es sind nur folgende COM-Objekte zulässig:
Scripting.Dictionary
Scripting.FileSystemObject
VBScript.RegExp
Die folgenden Typen sind im ConstrainedLanguage-Modus zulässig. Benutzer können Eigenschaften
abrufen, Methoden aufrufen und Objekte in diese Typen konvertieren.
C12_Sicherheit-an-PowerShell.md 7/11/2020
11 / 18
[AliasAttribute], [AllowEmptyCollectionAttribute], [AllowEmptyStringAttribute],
[AllowNullAttribute], [Array], [Bool], [byte], [char], [CmdletBindingAttribute], [DateTime],
[decimal], [DirectoryEntry], [DirectorySearcher], [double], [float], [Guid], [Hashtable], [int],
[Int16], [long], [ManagementClass], [ManagementObject], [ManagementObjectSearcher],
[NullString], [OutputTypeAttribute], [ParameterAttribute], [PSCredential],
[PSDefaultValueAttribute], [PSListModifier], [PSObject], [PSPrimitiveDictionary],
[PSReference], [PSTypeNameAttribute], [Regex], [SByte], [string],
[SupportsWildcardsAttribute], [SwitchParameter], [System.Globalization.CultureInfo],
[System.Net.IPAddress], [System.Net.Mail.MailAddress], [System.Numerics.BigInteger],
[System.Security.SecureString], [TimeSpan], [UInt16], [UInt32], [UInt64]
Seit PowerShell 5 wird automatisch erkannt ob in den Constrained Language Mode gewechselt werden
soll. Die PowerShell legt dazu unter $env:TEMP temporär ein Script an und versucht dieses auszuführen. Wird
die PowerShell bei der Ausführung gehindert, startet sie im eingeschränkten Sprach-modus. Dazu müssen Sie
lediglich das Ausführen von Skripten im Ordner $env:TEMP verbieten.
Realisieren können Sie das z.B. per Softwareeinschränkung (GPO) unter Computerkonfiguration /
Windows-Einstellungen / Sicherheitseinstellungen / Richtlinien für Softwareeinschränkung
/ Zusätzliche Regeln.
# TODO Test-Umgebung: Neu Pfad-Regel erstellen für
C:UsersAttilaAppDataLocalTemp :
GPEdit.msc
Oder per AppLocker unter Computerkonfiguration / Windows-Einstellungen /
Sicherheitseinstellungen / Anwendungssteuerungsrichtlinien / AppLocker / Skriptregeln.
Umgang mit Zugriffsberechtigungen (ACL)
Die PowerShell-Board-Mittel sind leider noch überschaubar. Im Grunde können wir von einem vorhandenes
Windows-Objekt, dessen Access-Control-List klonen und genau diese auf ein anderes Objekt übertragen.
Windows Terminal Screenshot - ACL auswerten und Berechtigungen im Klartext anzeigen
# ! Die PowerShell-Board-Mittel:
Get-Command -Name 'Get-Acl', 'Set-Acl', 'ConvertFrom-SddlString'
# ? Berechtigungen von Ordner-A auf Ordner-B übertragen:
New-Item -Path 'C:' -Name 'TempTest' -ItemType 'Directory' -Force
Get-Acl -Path 'C:Temp' | Select-Object -Property '*'
Get-Acl -Path 'C:Temp' | Set-Acl -Path 'C:TempTest'
# TODO Aufräumen:
Remove-Item -Path 'C:TempTest' -Recurse -Force
C12_Sicherheit-an-PowerShell.md 7/11/2020
12 / 18
ACL-Objekte sind mit unter oft kryptisch zu lesen (gacutil.exe) aber lesen und auswerten bekommen wir über
das Cmdlet ConvertFrom-SddlString Unterstützung.
# ? Berechtigungen von ACL-Objekten auswerten:
Get-Acl -Path $env:USERPROFILE | Select-Object -ExpandProperty 'Sddl' |
ConvertFrom-SddlString
Umfassende/aufwendige Möglichkeiten ergeben sich mit .NET oder Sie schauen Sich das Modul
NtfsSecurity aus der PowerShall-Gallery einmal genauer an.
Install-Module -Name 'NTFSSecurity' -Scope 'CurrentUser' -SkipPublisherCheck -
Force -PassThru -Verbose
Get-Command -Module 'NTFSSecurity'
Get-NTFSAccess -Path 'C:Temp'
# TODO Aufräumen:
Remove-Module -Name 'NTFSSecurity' -Force
Uninstall-Module -Name 'NTFSSecurity' -AllVersions -Force
Admin-Aufgaben an Nicht-Admins delegieren (JEA)
Neben den bereits beschriebenen PowerShell Sicherheit-Mechaniken ist die Königsdisziplin, um die
PowerShell Sicherheit auf ein Maximum zu heben das Feature "Just Enough Administration". Dieses vereint die
bereits aufgeführten Funktionen und ergänzt diese.
Just Enough Administration (JEA => Gerade genug Administration) ist ein Feature, das ab Windows 10 und
Server 2016 zur Verfügung steht. Mit JEA (Just Enough Administration) können Systemverwalter mittels
PowerShell granular administrative Aufgaben an Nicht-Administratoren delegieren.
Diese Nicht-Administrator erhalten, unabhängig von der Gruppenmitgliedschaft über eine Remote-Session
mittels "Just Enough Administration"-Zugriff auf vorher festgelegte Komponenten (PSProvider, Cmdlets,
Cmdlet-Parameter, Ausführbare Dateien, etc.).
Das damit realisierte Prinzip "Least Privilege" sieht vor, nur noch die tatsächlich minimalen Rechte für
bestimmte Aufgaben und Dienste an administrative Mitarbeiter zu erteilen.
Die Architektur basiert auf "Just Enough Administration"-Endpoints, mit denen sich der Bediener via Enter-
PSSession verbindet und remote Befehle mit höheren Rechten auf Systemen ausführen kann.
Umfassende Details finden Sie in der Microsoft Dokumentation Just Enough Administration.
HINWEIS - Sollten Sie dieses Beispiel unter PowerShell 7 auf Windows-Rechnern ausführen sind
folgende Schritte nötig.
Import-WinModule -Name 'NetAdapter'
Import-WinModule -Name 'NetConnection'
Import-WinModule -Name 'Microsoft.PowerShell.LocalAccounts'
C12_Sicherheit-an-PowerShell.md 7/11/2020
13 / 18
1. JEA Voraussetzungen prüfen
Just Enough Administration ist ein in Feature ab PowerShell 5.0. Dazu gesellen sich noch weitere
Voraussetzungen, die wir zuerst einmal abklopfen sollten.
# ? PowerShell-Version:
$PSVersionTable.PSVersion -ge [Version]"5.0.0.0"
# ? OS-Version:
Get-ComputerInfo | ForEach-Object { if(($_.OsName -IMatch 'Windows 10' -and
$_.WindowsVersion -ge 1607) -or $_.OsName -IMatch 'Windows Server 2016' -or
$_.OsName -imatch 'Windows Server 2019') { $true } else { $false } }
# ? PS Remoting aktiviert:
try { Invoke-Command -ComputerName 'localhost' -ScriptBlock { 1 | Out-Null } -
Credential (Get-Credential) -ErrorAction Stop ; $true } catch { $false }
In diesem Artikel Just Enough Administration Voraussetzungen werden die Voraussetzungen erläutert, die
erfüllt sein müssen, um "Just Enough Administration" verwenden zu können.
2. Vorbereitungen für "Just Enough Administration" treffen
Im folgenden Code-Block treffen wir die Vorbereitungen für das Testszenario. Dieses Szenario kann komplett
lokal ausgeführt werden ohne dass eine Domänenmitgliedschaft nötig ist.
# TODO Remoting auf Bediener-PC und Wartungs-Server aktivieren:
Get-NetAdapter -Physical | Set-NetConnectionProfile -NetworkCategory 'Private' -
PassThru
Enable-PSRemoting -Force
Set-Item -Path 'WSMan:localhostClientTrustedHosts' -Value '*' -Force
# !TODO Auf dem Wartungs-Server bzw. AD-Domäne Nicht-Admin-Benutzer und -Gruppe
festlegen / erstellen die Verwaltungsaufgaben erledigen müssen:
$NewUser = @{
Name = 'DruckerHorst'
AccountExpires = (Get-Date).AddHours(24)
Description = "24h Demo-Drucker-Managers ohne Admin-Rechte."
Password = (Read-Host -Prompt "Passwort für DruckerHorst" -
AsSecureString)
PasswordNeverExpires = $true
UserMayNotChangePassword = $true
}
New-LocalUser @NewUser
New-LocalGroup -Name 'LocalPrinterManagerGroup' -Description 'JEA-Demo:
DruckerManager-Gruppe für nicht Admins'
Add-LocalGroupMember -Group 'LocalPrinterManagerGroup' -Member 'DruckerHorst'
C12_Sicherheit-an-PowerShell.md 7/11/2020
14 / 18
3. Module-Ordner erstellen
Den JEA-PowerShell-Module-Ordner auf dem Wartungsserver erstellen in dem später die
Rollenfunktionsdateien (Role Capabilities) gesucht werden.
WICHTIG - Der folgende Modul-Ordner muss vor Manipulation geschützt werden, Stichwort ACL.
# Für PowerShell 7:
$ModulePath = "$env:ProgramFilesPowerShellModulesAbcFirma"
# Für Windows PowerShell:
$ModulePath = "$env:ProgramFilesWindowsPowerShellModulesAbcFirma"
New-Item -Path $ModulePath -ItemType 'Directory'
New-ModuleManifest -Path "$ModulePathAbcFirma.psd1" -RootModule 'AbcFirma'
4. Rollenfunktions-Datei erstellen
In dieser/n Rollenfunktionsdatei(en) (PowerShell Role Capability File .PSRC) legen Sie fest welche Rolle was auf
dem Wartungs-Server machen darf.
New-Item -Path "$ModulePathRoleCapabilities" -ItemType 'Directory'
$Parameter = @{
Path =
"$ModulePathRoleCapabilitiesPrinterManagerRoleCapability.psrc"
Author = 'Attila Krick'
CompanyName = 'ATTILAKRICK.COM'
Description = 'Benötigte Tools für Drucker-Manager.'
ModulesToImport = 'Microsoft.PowerShell.Management',
'Microsoft.PowerShell.Core', 'Microsoft.PowerShell.Utility'
VisibleProviders = 'FileSystem', 'Environment', 'Registry'
VisibleCmdlets = 'Clear-Host', 'Exit-PSSession', 'Get-Command', 'Get-
ChildItem', 'Get-FormatData', 'Get-Help', 'Measure-Object', 'Out-Default', 'Out-
String', 'Select-Object', `
@{ Name = 'Restart-Computer'; Parameters = @{ Name =
'ComputerName' ; ValidatePattern = 'VDId+' } }, `
@{ Name = 'Restart-Service' ; Parameters = @{ Name =
'Name' ; ValidateSet = 'Dns', 'Spooler' } }
FunctionDefinitions = @{ Name = 'Get-UserInfo' ; ScriptBlock = {
$PSSenderInfo } }
VisibleExternalCommands = 'C:WindowsSystem32WhoAmI.exe'
}
New-PSRoleCapabilityFile @Parameter
# TODO Kontrolle:
Start-Process -FilePath
"$ModulePathRoleCapabilitiesPrinterManagerRoleCapability.psrc"
C12_Sicherheit-an-PowerShell.md 7/11/2020
15 / 18
Weitere Details finden Sie in der Microsoft Dokumentation Erstellen einer Rollenfunktionsdatei.
5. Sitzungskonfigurations-Datei erstellen
In dieser Sitzungskonfigurations-Datei (PowerShell Session Configuration File .PSSC) wird die Nicht-Admin-
Gruppe(n) mit der entsprechenden Rolle verknüpft.
New-Item -Path "$env:ProgramDataJEASessionConfigurations" -ItemType 'Directory'
$JEAConfigParams = @{
Path =
"$env:ProgramDataJEASessionConfigurationsJEAPrintServerSession.pssc"
Author = 'Attila Krick'
Description = 'Verbindet die Rollen (u.a. Drucker-Manager) mit dieser
Session (JEAPrintServerSession)'
CompanyName = 'ATTILAKRICK.COM'
SessionType = "Default" # ! PROBLEM: "RestrictedRemoteServer"
RunAsVirtualAccount = $true
TranscriptDirectory = "$env:ProgramDataJEASessionConfigurationsTranscripts"
RoleDefinitions = @{ 'LocalPrinterManagerGroup' = @{RoleCapabilities =
'PrinterManagerRoleCapability'}}
Full = $true
}
New-PSSessionConfigurationFile @JEAConfigParams
# ! Kontrolle:
Test-PSSessionConfigurationFile -Path
"$env:ProgramDataJEASessionConfigurationsJEAPrintServerSession.pssc"
Start-Process -FilePath
"$env:ProgramDataJEASessionConfigurationsJEAPrintServerSession.pssc"
Weitere Details finden Sie in der Microsoft Dokumentation JEA-Sitzungskonfigurationen sowie unter Get-
Help -Name 'about_Session_Configuration_Files' -ShowWindow.
6. Die Sitzungskonfiguration registrieren und etablieren
Jetzt können wir Sitzungskonfiguration registrieren und den Endpoint etablieren, um so JEA für den Bediener
zu aktivieren.
Register-PSSessionConfiguration -Name 'JEAPrintServerSession' -Path
"$env:ProgramDataJEASessionConfigurationsJEAPrintServerSession.pssc" -Force
Restart-Service WinRM
# ! Kontrolle - Übersicht der registrierten Sitzungskonfigurationen:
Get-PSSessionConfiguration | Select-Object Name, Permission
Weitere Details finden Sie in der Microsoft Dokumentation Registrieren von JEA-Konfigurationen.
7. Just Enough Administration als Bediener/Verwalter verwenden
C12_Sicherheit-an-PowerShell.md 7/11/2020
16 / 18
Jetzt zeigt es sich, wie es um die PowerShell Sicherheit gestellt ist.
# TODO 1. Per Just Enough Administration (JEA) sich mit dem zu verwalten Server
als Nicht-Admin per Remote verbinden:
$cred = Get-Credential -UserName 'DruckerHorst' -Message 'Credential für
localhost'
# ! Administrator-Remote-Verbindung ist NICHT erlaubt:
Enter-PSSession -ComputerName 'localhost' -Credential $cred
# * JEA-Remote-Verbindung ist ERLAUBT:
Enter-PSSession -ComputerName 'localhost' -ConfigurationName
'JEAPrintServerSession' -Credential $cred
# ! 2. Eine Übersicht der Rechte für Benutzer X:
Get-PSSessionCapability -ConfigurationName "JEAPrintServerSession" -Username
"DruckerHorst" -Full
# ! 3. Just Enough Administration testen:
C:WindowsSystem32WhoAmI.exe # * erlaubt
Get-ChildItem -Path Hkcu: # * erlaubt
Restart-Service -Name Spooler # * erlaubt
Restart-Service -Name AudioSrv # ! Nicht erlaubt
Restart-Computer -ComputerName localhost # ! Nicht erlaubt
Restart-Computer -ComputerName VDI009 # * erlaubt
Get-UserInfo # * erlaubt
Get-Command # * erlaubt
exit # * erlaubt
Weitere Details finden Sie in der Microsoft Dokumentation [Verwenden von JEA]
(https://docs.microsoft.com/de-de/powershell/scripting/learn/remoting/jea/register-jea).
8. Aufgezeigt Konfiguration zurücksetzen
Aufgezeigt Konfiguration wieder rückgängig machen und sämtliche Spuren beseitigen
Unregister-PSSessionConfiguration -Name 'JEAPrintServerSession'
Restart-Service -Name 'WinRM'
Remove-Item -Path
"$env:ProgramDataJEASessionConfigurationsJEAPrintServerSession.pssc" -Force
Remove-Item -Path "$env:ProgramFilesPowerShellModulesAbcFirma" -Recurse -Force
Remove-Item -Path "$env:ProgramFilesWindowsPowerShellModulesAbcFirma" -Recurse
-Force
Remove-LocalGroup -Name 'LocalPrinterManagerGroup'
Remove-LocalUser -Name 'DruckerHorst'
Set-Item -Path "WSMan:localhostClientTrustedHosts" -Value ([String]::Empty) -
Force
Disable-PSRemoting -Force
Get-NetAdapter -Physical | Set-NetConnectionProfile -NetworkCategory "Public"
C12_Sicherheit-an-PowerShell.md 7/11/2020
17 / 18
PowerShell Sicherheit per GPO verteilen
PowerShell Sicherheit per GPO in der ActiveDirectory-Domäne verteilen.
EdgeUI.admx
User / Windows Components / Edge UI / Prevent users from replacing the Command Prompt
with Windows PowerShell in the menu they see when they right-click the lower-left
corner or press the Windows logo key+X
HKCUSoftwarePoliciesMicrosoftWindowsEdgeUI!ShowCommandPromptOnWinX
PowerShellExecutionPolicy.admx
Machine / Windows Components / Windows PowerShell / Turn on PowerShell Script Block
Logging
HKLMSoftwarePoliciesMicrosoftWindowsPowerShellScriptBlockLogging!EnableScriptBlockLo
gging
HKLMSoftwarePoliciesMicrosoftWindowsPowerShellScriptBlockLogging!EnableScriptBlockIn
vocationLogging
User / Windows Components / Windows PowerShell / Turn on PowerShell Script Block
Logging
HKCUSoftwarePoliciesMicrosoftWindowsPowerShellScriptBlockLogging!EnableScriptBlockLo
gging
HKCUSoftwarePoliciesMicrosoftWindowsPowerShellScriptBlockLogging!EnableScriptBlockIn
vocationLogging
Machine / Windows Components / Windows PowerShell / Turn on PowerShell Transcription
HKLMSoftwarePoliciesMicrosoftWindowsPowerShellTranscription!EnableTranscripting
HKLMSoftwarePoliciesMicrosoftWindowsPowerShellTranscription!OutputDirectory
HKLMSoftwarePoliciesMicrosoftWindowsPowerShellTranscription!EnableInvocationHeader
User / Windows Components / Windows PowerShell / Turn on PowerShell Transcription
HKCUSoftwarePoliciesMicrosoftWindowsPowerShellTranscription!EnableTranscripting
HKCUSoftwarePoliciesMicrosoftWindowsPowerShellTranscription!OutputDirectory
HKCUSoftwarePoliciesMicrosoftWindowsPowerShellTranscription!EnableInvocationHeader
Epilog
Von mir gibt es noch weitere PowerShell-Fachartikel und Guides. Und jetzt Neu, abonnieren Sie meinen
PowerShell-YouTube-Kanal.
Oder Wissen vom Trainer mit vielen praxisbezogenen Übungen, Wissenstests und Frage und Antwort-Runden.
Jetzt in meinen PowerShell-Seminaren und -Workshops.
Wenn Sie diesen Artikel als hilfreich empfunden haben würde ich mich über eine Erwähnung und einen
Verweis auf diesen Artikel in den sozialen Medien sehr freuen.
Als Dankeschön bekommen Sie ein von mir erstelltes hochwertiges A1-PowerShell-7-Poster mit den
wichtigsten Informationen für die tägliche Arbeit per Post zugesendet. Hierzu schreiben Sie mir an info at
attilakrick.com einfache eine E-Mail mit dem Link der Erwähnung sowie Ihre Adresse. Aber nur solange der
C12_Sicherheit-an-PowerShell.md 7/11/2020
18 / 18
Vorrat reicht. Ihre Daten (E-Mail, Adresse) werden nur zum Zweck des Poster-Versandes benötigt und
anschließend gelöscht.
[site_reviews_form title="Bitte bewerten Sie diesen Artikel" category="121" assign_to="258" id="kcb17qh9"
hide="title,content,name,email,terms"]

Weitere ähnliche Inhalte

Ähnlich wie PowerShell Sicherheit in 6 Schritten produktiv absichern

Opensource Tools für das Data Center Management
Opensource Tools für das Data Center ManagementOpensource Tools für das Data Center Management
Opensource Tools für das Data Center Managementinovex GmbH
 
Docker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-PatternsDocker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-PatternsQAware GmbH
 
Docker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-PatternsDocker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-PatternsJosef Adersberger
 
Echtes Single Sign-On mit APEX realisieren
Echtes Single Sign-On mit APEX realisierenEchtes Single Sign-On mit APEX realisieren
Echtes Single Sign-On mit APEX realisierenMT AG
 
Slides__Splunk_UserGroup_20220407.pdf
Slides__Splunk_UserGroup_20220407.pdfSlides__Splunk_UserGroup_20220407.pdf
Slides__Splunk_UserGroup_20220407.pdfAlexanderStz1
 
Automatisiertes disaster recovery testing mit der oracle cloud
Automatisiertes disaster recovery testing mit der oracle cloudAutomatisiertes disaster recovery testing mit der oracle cloud
Automatisiertes disaster recovery testing mit der oracle cloudTrivadis
 
Python builds mit ant
Python builds mit antPython builds mit ant
Python builds mit antroskakori
 
Microprofile-Anwendungen mit Quarkus
Microprofile-Anwendungen mit Quarkus Microprofile-Anwendungen mit Quarkus
Microprofile-Anwendungen mit Quarkus gedoplan
 
Automatisierte Linux Administration mit (R)?ex
Automatisierte Linux Administration mit (R)?ex Automatisierte Linux Administration mit (R)?ex
Automatisierte Linux Administration mit (R)?ex Jan Gehring
 
JEE-Microservices mit Quarkus – eine Einführung
JEE-Microservices mit Quarkus – eine EinführungJEE-Microservices mit Quarkus – eine Einführung
JEE-Microservices mit Quarkus – eine Einführunggedoplan
 
Production-ready Infrastruktur in 3 Wochen
Production-ready Infrastruktur in 3 WochenProduction-ready Infrastruktur in 3 Wochen
Production-ready Infrastruktur in 3 WochenAndré Goliath
 
Ionic 2 - Hybridapps auf Steroiden
Ionic 2 - Hybridapps auf SteroidenIonic 2 - Hybridapps auf Steroiden
Ionic 2 - Hybridapps auf SteroidenHendrik Lösch
 
Mögen die Tests mit dir sein
Mögen die Tests mit dir seinMögen die Tests mit dir sein
Mögen die Tests mit dir seincodepitbull
 

Ähnlich wie PowerShell Sicherheit in 6 Schritten produktiv absichern (20)

Opensource Tools für das Data Center Management
Opensource Tools für das Data Center ManagementOpensource Tools für das Data Center Management
Opensource Tools für das Data Center Management
 
Docker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-PatternsDocker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-Patterns
 
Docker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-PatternsDocker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-Patterns
 
Einführung in Docker
Einführung in DockerEinführung in Docker
Einführung in Docker
 
Echtes Single Sign-On mit APEX realisieren
Echtes Single Sign-On mit APEX realisierenEchtes Single Sign-On mit APEX realisieren
Echtes Single Sign-On mit APEX realisieren
 
Slides__Splunk_UserGroup_20220407.pdf
Slides__Splunk_UserGroup_20220407.pdfSlides__Splunk_UserGroup_20220407.pdf
Slides__Splunk_UserGroup_20220407.pdf
 
Automatisiertes disaster recovery testing mit der oracle cloud
Automatisiertes disaster recovery testing mit der oracle cloudAutomatisiertes disaster recovery testing mit der oracle cloud
Automatisiertes disaster recovery testing mit der oracle cloud
 
Python builds mit ant
Python builds mit antPython builds mit ant
Python builds mit ant
 
Webapplikationen mit Node.js
Webapplikationen mit Node.jsWebapplikationen mit Node.js
Webapplikationen mit Node.js
 
Testing tools
Testing toolsTesting tools
Testing tools
 
Microprofile-Anwendungen mit Quarkus
Microprofile-Anwendungen mit Quarkus Microprofile-Anwendungen mit Quarkus
Microprofile-Anwendungen mit Quarkus
 
Automatisierte Linux Administration mit (R)?ex
Automatisierte Linux Administration mit (R)?ex Automatisierte Linux Administration mit (R)?ex
Automatisierte Linux Administration mit (R)?ex
 
Einführung in Puppet
Einführung in PuppetEinführung in Puppet
Einführung in Puppet
 
FLOW3-Workshop F3X12
FLOW3-Workshop F3X12FLOW3-Workshop F3X12
FLOW3-Workshop F3X12
 
Typo3 und Varnish
Typo3 und VarnishTypo3 und Varnish
Typo3 und Varnish
 
Test-Automation mit Selenium WebDriver - ein Artikel der iks im dotnetpro
Test-Automation mit Selenium WebDriver - ein Artikel der iks im dotnetproTest-Automation mit Selenium WebDriver - ein Artikel der iks im dotnetpro
Test-Automation mit Selenium WebDriver - ein Artikel der iks im dotnetpro
 
JEE-Microservices mit Quarkus – eine Einführung
JEE-Microservices mit Quarkus – eine EinführungJEE-Microservices mit Quarkus – eine Einführung
JEE-Microservices mit Quarkus – eine Einführung
 
Production-ready Infrastruktur in 3 Wochen
Production-ready Infrastruktur in 3 WochenProduction-ready Infrastruktur in 3 Wochen
Production-ready Infrastruktur in 3 Wochen
 
Ionic 2 - Hybridapps auf Steroiden
Ionic 2 - Hybridapps auf SteroidenIonic 2 - Hybridapps auf Steroiden
Ionic 2 - Hybridapps auf Steroiden
 
Mögen die Tests mit dir sein
Mögen die Tests mit dir seinMögen die Tests mit dir sein
Mögen die Tests mit dir sein
 

PowerShell Sicherheit in 6 Schritten produktiv absichern

  • 1. C12_Sicherheit-an-PowerShell.md 7/11/2020 1 / 18 PowerShell in 7 Schritten produktiv absichern Powered by _ _ _ _ _ _ _ | | | | (_) | | | (_) | | __ _| |_| |_ _| | __ _| | ___ __ _ ___| | __ ___ ___ _ __ ___ / _` | __| __| | |/ _` | |/ / '__| |/ __| |/ / / __/ _ | '_ ` _ | (_| | |_| |_| | | (_| | <| | | | (__| < | (_| (_) | | | | | | __,_|__|__|_|_|__,_|_|__| |_|___|_|_(_)______/|_| |_| |_| ---------------------- HTTPS://ATTILAKRICK.COM --------------------- PowerShell Sicherheit - Die Keywords Zusammenfassungen Welche Sicherheitsmaßnahmen stehen dem Administrator zur Verfügung, um die PowerShell produktiv abzusichern und trotzdem administrative Aufgaben an Nicht-Administratoren zu delegieren (Just Enough Administration, JEA)? Wie können verdächtige und unerwünschte Aktivitäten protokolliert werden (ScriptBlockLogging)? Wie sollten die Ausführungsrichtlinien eingestellt sein und was bedeutet das für den Betrieb? Solche und noch weitere Fragen werden hier geklärt, um die Sicherheit an der PowerShell zu erhöhen. Schlagwörter Sicherheit, ExecutionPolicy, ScriptBlockLogging, LanguageMode, JEA Version 2020.07.02 Permalink https://attilakrick.com/powershell/powershell-sicherheit/ Einführung Die PowerShell ist ein Bestandteil des Betriebssystems. Daher sorgt ein generelles Blockieren nur für scheinbare PowerShell Sicherheit. Den besten Schutz versprechen die Schutz- und Protokollierungs- Mechanismen von PowerShell selbst. In diesem Artikel beleuchte wir das Thema PowerShell Sicherheit aus dem Blickwinkel eines Administrators. Wie PowerShell produktiv abgesichert wird, um trotzdem administrative Aufgaben an Nicht-Administratoren zu delegieren (Just Enough Administration). Auch geht es darum verdächtige und unerwünschte Aktivitäten zu protokollieren (ScriptBlockLogging).
  • 2. C12_Sicherheit-an-PowerShell.md 7/11/2020 2 / 18 TIPP - Neben der administrativen Absicherung, um die PowerShell Sicherheit zu erhöhen, sollten Sie auch mit sensiblen Daten wie Zugangsdaten, Geheimnisse und Zugangsbeschränkungen entsprechend umgehen und schützen. Wie Sie das in PowerShell realisieren, finden Sie im Artikel "Mit Sicherheit in der PowerShell umgehen". INTERESSANT - Eine gründliche Analyse der Sicherheittechnologie zwischen verfügbaren Shells und Skriptsprachen finden Sie in dem Artikel Ein Vergleich der Sicherheit von Shell und Skriptsprache. Altlasten entfernen erhöht die PowerShell Sicherheit Unbedingt sollten Sie PowerShell 2.0 deinstallieren. Mit dieser alten Shell-Version lassen sich alle wesentlichen Restriktionen für PowerShell unterlaufen. Das optionale Feature ist vorinstalliert und kann aber ab Windows 8.1 und Server 2012 deinstalliert werden. Statische Strings erhöht die Sicherheit Grundsätzlich immer die einfachen Hochkommas ' verwenden. Es seiden man verwendet Variable im String, erst dann die doppelten Hochkommas " verwenden. Das erhöht die Sicherheit da die Gefahr von String- Injection minimiert wird. # ! FALSCH $Ort = "Würzburg" # RICHTIG $Ort = 'Würzburg' $s = 'Hallo $Ort!' # vs. $s = "Hallo $Ort!" Ausführungsrichtlinien korrekt konfigurieren Die Ausführungsrichtlinie ist ein PowerShell Sicherheit-Funktion, die steuert unter welchen Bedingungen Konfigurations- und Skript-Dateien ausgeführt werden. Die Ausführungsrichtlinien schränken Benutzeraktionen nicht ein. Stattdessen helfen die Ausführungsrichtlinien Benutzern, dass sie nicht unbeabsichtigt gegen diese Regeln verstoßen. WICHTIG - Das Verändern der Ausführungsrichtlinien stellt NUR einen Schutz vor dem unbedarften Ausführen von Skripts dar - MEHR NICHT! # READ betroffene About-Seiten: Get-Help -Name 'about_Execution_Policy' -ShowWindow # ? Wie ist der aktuelle Status der Ausführungsrichtlinien: Get-ExecutionPolicy -List # ? Wie ist die Ausführungsrichtlinie für den aktuellen Script-Host eingestellt: $env:PSExecutionPolicyPreference
  • 3. C12_Sicherheit-an-PowerShell.md 7/11/2020 3 / 18 Empfohlene Einstellung für Client und Server: Alle ausführbaren Dateien müssen mit einem x.509-Zertifikat signiert sein. Set-ExecutionPolicy -ExecutionPolicy 'AllSigned' -Force Empfohlene Einstellung für Test- und Entwicklungs-Systeme: Alle ausführbaren Dateien die Remote (z.B. per Download oder UNC-Pfad, etc.) auf den PC gelangt sind, müssen mit einem X.509-Zertifikat signiert sein. Diese Dateien werden an einem 'Download-Marker' identifiziert. Dieser kann per Cmdlet Unblock-File wieder entfernt werden. Set-ExecutionPolicy -ExecutionPolicy 'RemoteSigned' -Force Für das automatische Ausführen von signierten Skripten müssen folgende Voraussetzungen erfüllt sein. 1. Das X.509-Zertifikat muss von einer "Vertrauenswürdigen Stammzertifizierungsstelle" (Root) abstammt ODER es ist selbst in Root abgelegt! 2. Das X.509-Zertifikat muss im Zertifikatspeicher für "Vertrauenswürdige Herausgeber" (TrustPublisher) enthalten ist. Ausführungsrichtlinien per GPO steuern: Die Ausführungsrichtlinien können komfortable per GPO eingestellt werden. Diese wiederum manipulieren folgende Registry-Schlüssel. Get-ItemPropertyValue -Path 'Registry::HKEY_LOCAL_MACHINESOFTWAREMicrosoftPowerShell1ShellIdsMicrosoft.P owerShell' -Name 'ExecutionPolicy' Get-ItemPropertyValue -Path 'Registry::HKEY_LOCAL_MACHINESOFTWAREMicrosoftPowerShell1ShellIdsScriptedDia gnostics' -Name 'ExecutionPolicy' Get-ItemPropertyValue -Path ''Registry::HKEY_CURRENT_USERSoftwareMicrosoftPowerShell1ShellIdsMicrosoft.P owerShell -Name 'ExecutionPolicy' Skript benötigt erhöhte Admin-Rechte Im administrativen Umfeld ist nötig, dass Skripte mit erhöhte Admin-Rechte laufen. Zum Skript-Beginn kann man überprüfen ob die Admin-Rechte vorhanden sind. Sollte dies nicht der Fall sein so könnte das Skript zu beginn abbrechen, anstatt fehlerhaft in der Mitte auszusteigen. $IsElevatedAdminRights = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.W indowsBuiltInRole]'Administrator') if(-not $IsElevatedAdminRights) {
  • 4. C12_Sicherheit-an-PowerShell.md 7/11/2020 4 / 18 throw 'Vorgang abgebrochen! Es werden erhöhte administrative Berechtigungen benötigt!' } else { 'Dieses Skript läuft mit erhöhten Admin-Berechtigungen!' | Write-Warning } PowerShell PKI-Handling # READ betroffene Cmdlets: Get-Command -Name '*' -Module 'PKI' # ! Zertifikat erstellen: using namespace 'Microsoft.CertificateServices.Commands' $params = @{ FriendlyName = 'Superman' Subject = 'CN=_Superman (Doctor S. Man), E=s.man@krypton.universe' HashAlgorithm = 'SHA512' KeyAlgorithm = 'RSA' KeyLength = 4096 KeyExportPolicy = [KeyExportPolicy]::ExportableEncrypted KeySpec = [KeySpec]::KeyExchange CertStoreLocation = 'Cert:CurrentUserMy' Type = [CertificateType]::Custom TextExtension = @('2.5.29.37= {text}1.3.6.1.5.5.7.3.1,1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.3,1.3.6.1.5.5.7.3.4,1.3. 6.1.5.5.7.3.5,1.3.6.1.5.5.7.3.6,1.3.6.1.5.5.7.3.7,1.3.6.1.5.5.7.3.8,1.3.6.1.5.5.7. 3.9,1.3.6.1.4.1.311.80.1,1.3.6.1.4.1.311.10.3.4,1.3.6.1.4.1.311.10.3.4.1', ` '2.5.29.17= {text}email=s.man@krypton.universe&upn=s.man@krypton.universe') NotAfter = (Get-Date).AddMinutes(60) AlternateSignatureAlgorithm = $true } $myPfxCert = New-SelfSignedCertificate @params # ! Zertifikat exportieren: $myPfxCert | Export-PfxCertificate -Password (Read-Host -Prompt 'Set PFX-Password for Superman' -AsSecureString) -FilePath 'C:TempSuperman.pfx' $myPfxCert | Export-Certificate -Type 'CERT' -Force -FilePath 'C:TempSuperman.cer' # ! Zertifikat im Zertifikats-Speicher löschen: Get-ChildItem -Path 'Cert:CurrentUser' -Recurse | Where-Object -Property 'Thumbprint' -CEQ $myPfxCert.Thumbprint | Remove-Item -Force -Recurse # ! Zertifikat importieren:
  • 5. C12_Sicherheit-an-PowerShell.md 7/11/2020 5 / 18 Import-Certificate -FilePath 'C:TempSuperman.cer' -CertStoreLocation 'Cert:LocalMachineRoot' Import-PfxCertificate -FilePath 'C:TempSuperman.pfx' -CertStoreLocation 'Cert:CurrentUserMy' -Password (Read-Host -Prompt 'PFX-Password for Superman' - AsSecureString) # ! Zertifikat aus dem Dateisystem lesen und auf Verwendungszweck testen: Get-PfxData -Password (Read-Host -Prompt 'PFX-Password for Superman' - AsSecureString) -FilePath 'C:TempSuperman.pfx' | Format-List -Property '*' $test = Get-PfxCertificate -FilePath 'C:TempSuperman.pfx' Test-Certificate -Cert $test -Policy 'SSL' | Write-Warning Test-Certificate -Cert $test -EKU '1.3.6.1.5.5.7.3.1' | Write-Warning # = Server Authentication # ! Zertifikat aus dem Cert-Speicher lesen und auf Verwendungszweck testen: Get-ChildItem -Path 'Cert:CurrentUserMy' | Where-Object -Property 'Subject' - CLike -Value 'CN=_Superman (Doctor S. Man), E=s.man@krypton.universe' | Test- Certificate -Policy 'SSL' | Write-Warning Get-ChildItem -Path 'Cert:LocalMachineRoot' | Where-Object -Property 'Subject' - CLike -Value 'CN=_Superman (Doctor S. Man), E=s.man@krypton.universe' | Test- Certificate -EKU '1.3.6.1.5.5.7.3.1' | Write-Warning # TODO Aufräumen: Remove-Item -Path 'C:TempSuperman.*' -Force Get-ChildItem -Path 'Cert:LocalMachine', 'Cert:CurrentUser' -Recurse | Where- Object -Property 'Subject' -CLike -Value 'CN=_Superman (Doctor S. Man), E=s.man@krypton.universe' | Remove-Item -Force PowerShell Script-Dateien signieren Warum sollte man signieren: 1. Eine Signatur schützt ein Skript (.PS1, .PSM1, .PS1XML, ...) vor Manipulation und erhöht so die PowerShell Sicherheit! 2. Der Signierer bestätigt mit seiner Signatur den endgültigen Status des Skriptes! 3. Dritte können erkennen wer dieses Skript signiert / erstellt hat. PowerShell kann über die Ausführungsrichtlinien so konfiguriert werden (AllSigned), dass nur Skripte ausgeführt werden, wenn folgende Voraussetzungen erfüllt sind: 1. Die Skriptdatei wurde mit einem X.509-Zertifikat signiert! 2. Die signierte Datei wurde anschließend nicht manipuliert! 3. Das Signierer-Zertifikat stamm von einer "Vertrauenswürdigen Stammzertifizierungsstelle" (Root) ab ODER es ist selbst in Root abgelegt worden!
  • 6. C12_Sicherheit-an-PowerShell.md 7/11/2020 6 / 18 4. Signierer-Zertifikat wurde zusätzlich im Zertifikatspeicher für "Vertrauenswürdige Herausgeber" (TrustPublisher) abgelegt! Zum Beispiel an einer einfachen Umsetzung über ein selbstsigniertes Zertifikat: # ! 1. Testumgebung vorbereiten # Ausführungsrichtlinien auf AllSigned setzen Set-ExecutionPolicy -ExecutionPolicy 'AllSigned' -Scope 'Process' -Force Set-ExecutionPolicy -ExecutionPolicy 'AllSigned' -Scope 'CurrentUser' -Force Set-ExecutionPolicy -ExecutionPolicy 'AllSigned' -Scope 'LocalMachine' -Force # PKI Modul importieren Import-Module -Name 'PKI' # Windows PowerShell Import-WinModule -Name 'PKI' # bzw. PowerShell 7 # Test-Ordner C:Temp erstellen New-Item -Path 'C:Temp' -ItemType 'Directory' -Force | Set-Location # Test-Script erzeugen '"> > > Execute Code from .PS1-Script! at $(Get-Date) < < <" | Write-Warning' | Set-Content -Path '.Test.ps1' -Force # ! 2. Aktuell wird das Ausführen des Skriptes mit einer Fehlermeldung abgebrochen . '.Test.ps1' # ! 3. Signierer-Zertifikate erstellen: $params = @{ Subject = 'CN=_FirstName_LastName (PS Developer), E=f.lastname@abc.local' HashAlgorithm = 'SHA512' KeyExportPolicy = [Microsoft.CertificateServices.Commands.KeyExportPolicy]::ExportableEncrypted CertStoreLocation = 'Cert:CurrentUserMy' Type = [ Microsoft.CertificateServices.Commands.CertificateType]::CodeSigningCert NotAfter = (Get-Date).AddYears(5) } $myPfxCert = New-SelfSignedCertificate @params # ! 4. Aus dem Signierer-Zertifikat ein öffentliches Zertifikat erstellen: $myPfxCert | Export-Certificate -FilePath '.PublicSignerCertificate.cer' -Type 'CERT' -Force # ! 5. Vertrauensstellung einrichten: # 1. im Zertifikatsspeicher Root abgelegt werden, um dem Zertifikat generell zu vertrauen Import-Certificate -FilePath '.PublicSignerCertificate.cer' -CertStoreLocation 'Cert:LocalMachineRoot' # 2. im Zertifikatsspeicher TrustedPublisher abgelegt werden, um den signierten
  • 7. C12_Sicherheit-an-PowerShell.md 7/11/2020 7 / 18 .PS1-Dateien im Besonderen zu vertrauen Import-Certificate -FilePath '.PublicSignerCertificate.cer' -CertStoreLocation 'Cert:LocalMachineTrustedPublisher' # ! 6. Das eigentliche Script signieren: $params = @{ Certificate = $myPfxCert HashAlgorithm = 'SHA512' TimestampServer = 'http://timestamp.globalsign.com/scripts/timstamp.dll' FilePath = '.Test.ps1' } Set-AuthenticodeSignature @params # ! 7. Signiertes Script testen: # ? Die digitale Signatur sollte GÜLTIG sein? Get-AuthenticodeSignature -FilePath '.Test.ps1' | Format-List -Property * # ? Wird .PS1-Datei nun problemlos ausgeführt? . '.Test.ps1' # ! 8. Aufräumen Set-ExecutionPolicy -ExecutionPolicy 'RemoteSigned' -Scope 'Process' -Force Set-ExecutionPolicy -ExecutionPolicy 'RemoteSigned' -Scope 'CurrentUser' -Force Set-ExecutionPolicy -ExecutionPolicy 'RemoteSigned' -Scope 'LocalMachine' -Force Get-ChildItem -Path 'Cert:CurrentUserMy', 'Cert:LocalMachineRoot', 'Cert:LocalMachineTrustedPublisher' | Where-Object Thumbprint -CEQ $myPfxCert.Thumbprint | Remove-Item Get-ChildItem -Path '.Test.ps1', '.PublicSignerCertificate.cer' | Remove-Item TIPP - Vielleicht besitzen Sie ja schon ein entsprechendes Zertifikat zum Signieren. Lassen Sie sich diese wie folgt anzeigen. Get-ChildItem -Path 'Cert:CurrentUserMy' -CodeSigningCert Einfache Host-Ein-/Ausgabe Protokollierung Eine einfache Variante, um die PowerShell Sicherheit zu erhöhen, ist das Mitschneiden sämtlicher Aktivitäten und deren Resultate auf einem PowerShell Host. Hierzu verwenden Sie die Cmdlets Start-Transcript und Stop-Transcript. # * 1. Transcript starten: Start-Transcript -Path "C:TempPsHost.log" -Append -Force # * 2. Test-Eingabe & -Ausgaben erzeugen: Get-Process Read-Host -Prompt "Passwort eingeben" -AsSecureString # * 3. Transcript stoppen:
  • 8. C12_Sicherheit-an-PowerShell.md 7/11/2020 8 / 18 Stop-Transcript -Verbose # 4. Log-Datei Anzeigen: Start-Process -FilePath "C:TempPsHost.log" Wo und wann Sie Start-Transcript initiieren obliegt Ihnen. Denkbar wäre z.B. einer der Autostartdateien (profile.ps1). Aktivitäten mittels ScriptBlockLogging protokollieren Wenn ScriptBlockLogging aktiviert ist werden sämtliche Befehle zu PowerShell-Vorgängen protokolliert. Durch den lückenlosen Nachweis sämtlicher PowerShell-Aktivität wir die PowerShell Sicherheit weiter erhöht. WICHTIG - Bzgl. PowerShell 7: Bevor Ereignisse in das Ereignisprotokoll geschrieben werden können, muss im Gegensatz zu Linux oder macOS in Windows der Ereignisanbieter registriert sein. Führen Sie dazu mit erhöhten Berechtigungen folgendes aus. . "$PsHomeRegisterManifest.ps1" Get-WinEvent -ListProvider '*powershell*' | Select-Object -Property 'Name' Permanentes und sicheres Protokollieren sämtlicher Host-Aktivitäten mittels ScriptBlockLogging aktivieren. TIPP - ScriptBlockLogging per GPO unter Computerkonfiguration / Administrative Vorlagen / Windows-Komponenten / Windows PowerShell / Protokollierung von PowerShell- Scriptblöcken aktivieren. ACHTUNG - z.Zt. nur für Windows PowerShell, andere Versionen nur per folgenden Registry-Keys. # ! Für PowerShell 7 und PowerShell Core: New-Item -Path 'Registry::HKEY_LOCAL_MACHINESOFTWAREPoliciesMicrosoftPowerShellCore' -Name 'ScriptBlockLogging' -ItemType 'Key' -Force | New-ItemProperty -Name 'EnableScriptBlockLogging' -Value 1 -PropertyType 'DWord' -Force # ! Für Windows PowerShell: New-Item -Path 'Registry::HKEY_LOCAL_MACHINESOFTWAREPoliciesMicrosoftWindowsPowerShell' - Name 'ScriptBlockLogging' -ItemType 'Key' -Force | New-ItemProperty -Name 'EnableScriptBlockLogging' -Value 1 -PropertyType 'DWord' -Force # ! Für Windows PowerShell 32it: Registry::HKEY_LOCAL_MACHINESOFTWAREWOW6432NodePoliciesMicrosoftWindowsPower ShellScriptBlockLogging # ! Für PowerShell Core 32bit: Registry::HKEY_LOCAL_MACHINESOFTWAREWOW6432NodePoliciesMicrosoftWindowsPower ShellCoreScriptBlockLogging
  • 9. C12_Sicherheit-an-PowerShell.md 7/11/2020 9 / 18 Die so protokollierten Aktivitäten können nun wie folgt ausgewertet werden. # Test-Code der gleich im Protokoll auftaucht: Get-ChildItem -Path 'C:Temp' # ! Auswertung: Get-WinEvent -ListLog '*powershell*' Get-WinEvent -FilterHashtable @{ LogName='PowerShellCore/Operational' ; Id="4104" } | Select-Object -Property 'RecordId', 'ProcessId', 'MachineName', 'UserId', 'TimeCreated', 'Message' | Where-Object -Property 'Message' -IMatch -Value 'Get- ChildItem' # TODO Aufräumen: . "$PsHomeRegisterManifest.ps1" -Unregister Remove-Item -Path 'Registry::HKEY_LOCAL_MACHINESOFTWAREPoliciesMicrosoftPowerShellCoreScriptBlo ckLogging' -Recurse -Force Remove-Item -Path 'Registry::HKEY_LOCAL_MACHINESOFTWAREPoliciesMicrosoftWindowsPowerShellScrip tBlockLogging' -Recurse -Force TIPP - Um die PowerShell Sicherheit weiter zu erhöhen, sollten sensible Daten im Protokoll geschützt werden. Dazu verschlüsseln Sie einfach die Logs (s. Protected Event Logging unter Get-Help -Name 'about_logging_windows' -ShowWindow). Aktivitäten in der PowerShell-Session einschränken (LanguageMode) Über $ExecutionContext.SessionState.LanguageMode können Sie weiter einschränken welche Cmdlets, Typen und Interaktionen erlaubt sind, um die PowerShell Sicherheit weiter zu erhöhen. # ! Zum Beispiel aktivieren per Autostart über eine der folgenden Dateien: $profile.AllUsersAllHosts $profile.AllUsersCurrentHost # ! 1. Keine Anwendungen und Skripte ab jetzt erlauben: $ExecutionContext.SessionState.Applications.Clear() $ExecutionContext.SessionState.Scripts.Clear() # ! 2. Erlaubte Cmdlets festlegen und die restlichen Cmdlets unsichtbar machen: $allowedCommands = @() $allowedCommands += "ForEach-Object" $allowedCommands += "Get-ChildItem" $allowedCommands += "Get-Command" $allowedCommands += "Get-Member" $allowedCommands += "Get-Module" $allowedCommands += "Out-Default" $allowedCommands += "Select-Object" $allowedCommands += "Test-NetConnection" $allowedCommands += "Where-Object"
  • 10. C12_Sicherheit-an-PowerShell.md 7/11/2020 10 / 18 Get-Command -CommandType "Cmdlet", "Function" | Where-Object -Property Name - NotIn -Value $allowedCommands | ForEach-Object -Process { $_.Visibility = "Private" } # ! 3. Den LanguageMode in den beschränkten Sprachmodus versetzen: $ExecutionContext.SessionState.LanguageMode = "RestrictedLanguage" Weitere LanguageMode-Details entnehmen Sie den entsprechenden About-Seiten. # READ siehe auch: Get-Help -Name 'about_Language_Modes' -ShowWindow Get-Help -Name 'about_FullLanguage' -ShowWindow Get-Help -Name 'about_RestrictedLanguage' -ShowWindow Get-Help -Name 'about_ConstrainedLanguage' -ShowWindow Um zu ermitteln in welchem Modi sich die aktuelle Sitzung befindet, können Sie die LanguageMode Eigenschaft abfragen: $ExecutionContext.SessionState.LanguageMode Zu den wichtigsten PowerShell Sicherheits-mechanismen gehört der Constrained Language Mode (CLM) die mehrere gefährlichen PowerShell-Features deaktiviert und so deren Missbrauch minimiert und die PowerShell Sicherheit erhöht. Der ConstrainedLanguage-Modus erlaubt alle Cmdlets und alle PowerShell- Sprachelemente, begrenzt jedoch die zulässigen Typen. Wenn der LanguageMode auf ConstrainedLanguage steht werden folgende wichtige Funktionen geboten: Alle Cmdlets in Windows-Modulen und andere von UMCI genehmigte Cmdlets sind voll funktionsfähig und haben, sofern nicht anders angegeben, vollständigen Zugriff auf Systemressourcen. Alle in Windows enthaltenen Module können importiert und alle Befehle, die die Module exportieren, in der Sitzung ausgeführt werden. Das Cmdlet Add-Type kann signierte Assembly laden, jedoch keinen beliebigen C# -Code oder Win32- APIs. Das Cmdlet New-Object kann nur für zulässige Typen verwendet werden (siehe unten). Die Typkonvertierung ist zulässig, jedoch nur, wenn das Ergebnis ein zulässiger Typ ist. Cmdlet-Parameter, die Zeichenfolgeneingaben in Typen konvertieren, funktionieren nur, wenn der resultierende Typ ein zulässiger Typ ist. Es sind nur folgende COM-Objekte zulässig: Scripting.Dictionary Scripting.FileSystemObject VBScript.RegExp Die folgenden Typen sind im ConstrainedLanguage-Modus zulässig. Benutzer können Eigenschaften abrufen, Methoden aufrufen und Objekte in diese Typen konvertieren.
  • 11. C12_Sicherheit-an-PowerShell.md 7/11/2020 11 / 18 [AliasAttribute], [AllowEmptyCollectionAttribute], [AllowEmptyStringAttribute], [AllowNullAttribute], [Array], [Bool], [byte], [char], [CmdletBindingAttribute], [DateTime], [decimal], [DirectoryEntry], [DirectorySearcher], [double], [float], [Guid], [Hashtable], [int], [Int16], [long], [ManagementClass], [ManagementObject], [ManagementObjectSearcher], [NullString], [OutputTypeAttribute], [ParameterAttribute], [PSCredential], [PSDefaultValueAttribute], [PSListModifier], [PSObject], [PSPrimitiveDictionary], [PSReference], [PSTypeNameAttribute], [Regex], [SByte], [string], [SupportsWildcardsAttribute], [SwitchParameter], [System.Globalization.CultureInfo], [System.Net.IPAddress], [System.Net.Mail.MailAddress], [System.Numerics.BigInteger], [System.Security.SecureString], [TimeSpan], [UInt16], [UInt32], [UInt64] Seit PowerShell 5 wird automatisch erkannt ob in den Constrained Language Mode gewechselt werden soll. Die PowerShell legt dazu unter $env:TEMP temporär ein Script an und versucht dieses auszuführen. Wird die PowerShell bei der Ausführung gehindert, startet sie im eingeschränkten Sprach-modus. Dazu müssen Sie lediglich das Ausführen von Skripten im Ordner $env:TEMP verbieten. Realisieren können Sie das z.B. per Softwareeinschränkung (GPO) unter Computerkonfiguration / Windows-Einstellungen / Sicherheitseinstellungen / Richtlinien für Softwareeinschränkung / Zusätzliche Regeln. # TODO Test-Umgebung: Neu Pfad-Regel erstellen für C:UsersAttilaAppDataLocalTemp : GPEdit.msc Oder per AppLocker unter Computerkonfiguration / Windows-Einstellungen / Sicherheitseinstellungen / Anwendungssteuerungsrichtlinien / AppLocker / Skriptregeln. Umgang mit Zugriffsberechtigungen (ACL) Die PowerShell-Board-Mittel sind leider noch überschaubar. Im Grunde können wir von einem vorhandenes Windows-Objekt, dessen Access-Control-List klonen und genau diese auf ein anderes Objekt übertragen. Windows Terminal Screenshot - ACL auswerten und Berechtigungen im Klartext anzeigen # ! Die PowerShell-Board-Mittel: Get-Command -Name 'Get-Acl', 'Set-Acl', 'ConvertFrom-SddlString' # ? Berechtigungen von Ordner-A auf Ordner-B übertragen: New-Item -Path 'C:' -Name 'TempTest' -ItemType 'Directory' -Force Get-Acl -Path 'C:Temp' | Select-Object -Property '*' Get-Acl -Path 'C:Temp' | Set-Acl -Path 'C:TempTest' # TODO Aufräumen: Remove-Item -Path 'C:TempTest' -Recurse -Force
  • 12. C12_Sicherheit-an-PowerShell.md 7/11/2020 12 / 18 ACL-Objekte sind mit unter oft kryptisch zu lesen (gacutil.exe) aber lesen und auswerten bekommen wir über das Cmdlet ConvertFrom-SddlString Unterstützung. # ? Berechtigungen von ACL-Objekten auswerten: Get-Acl -Path $env:USERPROFILE | Select-Object -ExpandProperty 'Sddl' | ConvertFrom-SddlString Umfassende/aufwendige Möglichkeiten ergeben sich mit .NET oder Sie schauen Sich das Modul NtfsSecurity aus der PowerShall-Gallery einmal genauer an. Install-Module -Name 'NTFSSecurity' -Scope 'CurrentUser' -SkipPublisherCheck - Force -PassThru -Verbose Get-Command -Module 'NTFSSecurity' Get-NTFSAccess -Path 'C:Temp' # TODO Aufräumen: Remove-Module -Name 'NTFSSecurity' -Force Uninstall-Module -Name 'NTFSSecurity' -AllVersions -Force Admin-Aufgaben an Nicht-Admins delegieren (JEA) Neben den bereits beschriebenen PowerShell Sicherheit-Mechaniken ist die Königsdisziplin, um die PowerShell Sicherheit auf ein Maximum zu heben das Feature "Just Enough Administration". Dieses vereint die bereits aufgeführten Funktionen und ergänzt diese. Just Enough Administration (JEA => Gerade genug Administration) ist ein Feature, das ab Windows 10 und Server 2016 zur Verfügung steht. Mit JEA (Just Enough Administration) können Systemverwalter mittels PowerShell granular administrative Aufgaben an Nicht-Administratoren delegieren. Diese Nicht-Administrator erhalten, unabhängig von der Gruppenmitgliedschaft über eine Remote-Session mittels "Just Enough Administration"-Zugriff auf vorher festgelegte Komponenten (PSProvider, Cmdlets, Cmdlet-Parameter, Ausführbare Dateien, etc.). Das damit realisierte Prinzip "Least Privilege" sieht vor, nur noch die tatsächlich minimalen Rechte für bestimmte Aufgaben und Dienste an administrative Mitarbeiter zu erteilen. Die Architektur basiert auf "Just Enough Administration"-Endpoints, mit denen sich der Bediener via Enter- PSSession verbindet und remote Befehle mit höheren Rechten auf Systemen ausführen kann. Umfassende Details finden Sie in der Microsoft Dokumentation Just Enough Administration. HINWEIS - Sollten Sie dieses Beispiel unter PowerShell 7 auf Windows-Rechnern ausführen sind folgende Schritte nötig. Import-WinModule -Name 'NetAdapter' Import-WinModule -Name 'NetConnection' Import-WinModule -Name 'Microsoft.PowerShell.LocalAccounts'
  • 13. C12_Sicherheit-an-PowerShell.md 7/11/2020 13 / 18 1. JEA Voraussetzungen prüfen Just Enough Administration ist ein in Feature ab PowerShell 5.0. Dazu gesellen sich noch weitere Voraussetzungen, die wir zuerst einmal abklopfen sollten. # ? PowerShell-Version: $PSVersionTable.PSVersion -ge [Version]"5.0.0.0" # ? OS-Version: Get-ComputerInfo | ForEach-Object { if(($_.OsName -IMatch 'Windows 10' -and $_.WindowsVersion -ge 1607) -or $_.OsName -IMatch 'Windows Server 2016' -or $_.OsName -imatch 'Windows Server 2019') { $true } else { $false } } # ? PS Remoting aktiviert: try { Invoke-Command -ComputerName 'localhost' -ScriptBlock { 1 | Out-Null } - Credential (Get-Credential) -ErrorAction Stop ; $true } catch { $false } In diesem Artikel Just Enough Administration Voraussetzungen werden die Voraussetzungen erläutert, die erfüllt sein müssen, um "Just Enough Administration" verwenden zu können. 2. Vorbereitungen für "Just Enough Administration" treffen Im folgenden Code-Block treffen wir die Vorbereitungen für das Testszenario. Dieses Szenario kann komplett lokal ausgeführt werden ohne dass eine Domänenmitgliedschaft nötig ist. # TODO Remoting auf Bediener-PC und Wartungs-Server aktivieren: Get-NetAdapter -Physical | Set-NetConnectionProfile -NetworkCategory 'Private' - PassThru Enable-PSRemoting -Force Set-Item -Path 'WSMan:localhostClientTrustedHosts' -Value '*' -Force # !TODO Auf dem Wartungs-Server bzw. AD-Domäne Nicht-Admin-Benutzer und -Gruppe festlegen / erstellen die Verwaltungsaufgaben erledigen müssen: $NewUser = @{ Name = 'DruckerHorst' AccountExpires = (Get-Date).AddHours(24) Description = "24h Demo-Drucker-Managers ohne Admin-Rechte." Password = (Read-Host -Prompt "Passwort für DruckerHorst" - AsSecureString) PasswordNeverExpires = $true UserMayNotChangePassword = $true } New-LocalUser @NewUser New-LocalGroup -Name 'LocalPrinterManagerGroup' -Description 'JEA-Demo: DruckerManager-Gruppe für nicht Admins' Add-LocalGroupMember -Group 'LocalPrinterManagerGroup' -Member 'DruckerHorst'
  • 14. C12_Sicherheit-an-PowerShell.md 7/11/2020 14 / 18 3. Module-Ordner erstellen Den JEA-PowerShell-Module-Ordner auf dem Wartungsserver erstellen in dem später die Rollenfunktionsdateien (Role Capabilities) gesucht werden. WICHTIG - Der folgende Modul-Ordner muss vor Manipulation geschützt werden, Stichwort ACL. # Für PowerShell 7: $ModulePath = "$env:ProgramFilesPowerShellModulesAbcFirma" # Für Windows PowerShell: $ModulePath = "$env:ProgramFilesWindowsPowerShellModulesAbcFirma" New-Item -Path $ModulePath -ItemType 'Directory' New-ModuleManifest -Path "$ModulePathAbcFirma.psd1" -RootModule 'AbcFirma' 4. Rollenfunktions-Datei erstellen In dieser/n Rollenfunktionsdatei(en) (PowerShell Role Capability File .PSRC) legen Sie fest welche Rolle was auf dem Wartungs-Server machen darf. New-Item -Path "$ModulePathRoleCapabilities" -ItemType 'Directory' $Parameter = @{ Path = "$ModulePathRoleCapabilitiesPrinterManagerRoleCapability.psrc" Author = 'Attila Krick' CompanyName = 'ATTILAKRICK.COM' Description = 'Benötigte Tools für Drucker-Manager.' ModulesToImport = 'Microsoft.PowerShell.Management', 'Microsoft.PowerShell.Core', 'Microsoft.PowerShell.Utility' VisibleProviders = 'FileSystem', 'Environment', 'Registry' VisibleCmdlets = 'Clear-Host', 'Exit-PSSession', 'Get-Command', 'Get- ChildItem', 'Get-FormatData', 'Get-Help', 'Measure-Object', 'Out-Default', 'Out- String', 'Select-Object', ` @{ Name = 'Restart-Computer'; Parameters = @{ Name = 'ComputerName' ; ValidatePattern = 'VDId+' } }, ` @{ Name = 'Restart-Service' ; Parameters = @{ Name = 'Name' ; ValidateSet = 'Dns', 'Spooler' } } FunctionDefinitions = @{ Name = 'Get-UserInfo' ; ScriptBlock = { $PSSenderInfo } } VisibleExternalCommands = 'C:WindowsSystem32WhoAmI.exe' } New-PSRoleCapabilityFile @Parameter # TODO Kontrolle: Start-Process -FilePath "$ModulePathRoleCapabilitiesPrinterManagerRoleCapability.psrc"
  • 15. C12_Sicherheit-an-PowerShell.md 7/11/2020 15 / 18 Weitere Details finden Sie in der Microsoft Dokumentation Erstellen einer Rollenfunktionsdatei. 5. Sitzungskonfigurations-Datei erstellen In dieser Sitzungskonfigurations-Datei (PowerShell Session Configuration File .PSSC) wird die Nicht-Admin- Gruppe(n) mit der entsprechenden Rolle verknüpft. New-Item -Path "$env:ProgramDataJEASessionConfigurations" -ItemType 'Directory' $JEAConfigParams = @{ Path = "$env:ProgramDataJEASessionConfigurationsJEAPrintServerSession.pssc" Author = 'Attila Krick' Description = 'Verbindet die Rollen (u.a. Drucker-Manager) mit dieser Session (JEAPrintServerSession)' CompanyName = 'ATTILAKRICK.COM' SessionType = "Default" # ! PROBLEM: "RestrictedRemoteServer" RunAsVirtualAccount = $true TranscriptDirectory = "$env:ProgramDataJEASessionConfigurationsTranscripts" RoleDefinitions = @{ 'LocalPrinterManagerGroup' = @{RoleCapabilities = 'PrinterManagerRoleCapability'}} Full = $true } New-PSSessionConfigurationFile @JEAConfigParams # ! Kontrolle: Test-PSSessionConfigurationFile -Path "$env:ProgramDataJEASessionConfigurationsJEAPrintServerSession.pssc" Start-Process -FilePath "$env:ProgramDataJEASessionConfigurationsJEAPrintServerSession.pssc" Weitere Details finden Sie in der Microsoft Dokumentation JEA-Sitzungskonfigurationen sowie unter Get- Help -Name 'about_Session_Configuration_Files' -ShowWindow. 6. Die Sitzungskonfiguration registrieren und etablieren Jetzt können wir Sitzungskonfiguration registrieren und den Endpoint etablieren, um so JEA für den Bediener zu aktivieren. Register-PSSessionConfiguration -Name 'JEAPrintServerSession' -Path "$env:ProgramDataJEASessionConfigurationsJEAPrintServerSession.pssc" -Force Restart-Service WinRM # ! Kontrolle - Übersicht der registrierten Sitzungskonfigurationen: Get-PSSessionConfiguration | Select-Object Name, Permission Weitere Details finden Sie in der Microsoft Dokumentation Registrieren von JEA-Konfigurationen. 7. Just Enough Administration als Bediener/Verwalter verwenden
  • 16. C12_Sicherheit-an-PowerShell.md 7/11/2020 16 / 18 Jetzt zeigt es sich, wie es um die PowerShell Sicherheit gestellt ist. # TODO 1. Per Just Enough Administration (JEA) sich mit dem zu verwalten Server als Nicht-Admin per Remote verbinden: $cred = Get-Credential -UserName 'DruckerHorst' -Message 'Credential für localhost' # ! Administrator-Remote-Verbindung ist NICHT erlaubt: Enter-PSSession -ComputerName 'localhost' -Credential $cred # * JEA-Remote-Verbindung ist ERLAUBT: Enter-PSSession -ComputerName 'localhost' -ConfigurationName 'JEAPrintServerSession' -Credential $cred # ! 2. Eine Übersicht der Rechte für Benutzer X: Get-PSSessionCapability -ConfigurationName "JEAPrintServerSession" -Username "DruckerHorst" -Full # ! 3. Just Enough Administration testen: C:WindowsSystem32WhoAmI.exe # * erlaubt Get-ChildItem -Path Hkcu: # * erlaubt Restart-Service -Name Spooler # * erlaubt Restart-Service -Name AudioSrv # ! Nicht erlaubt Restart-Computer -ComputerName localhost # ! Nicht erlaubt Restart-Computer -ComputerName VDI009 # * erlaubt Get-UserInfo # * erlaubt Get-Command # * erlaubt exit # * erlaubt Weitere Details finden Sie in der Microsoft Dokumentation [Verwenden von JEA] (https://docs.microsoft.com/de-de/powershell/scripting/learn/remoting/jea/register-jea). 8. Aufgezeigt Konfiguration zurücksetzen Aufgezeigt Konfiguration wieder rückgängig machen und sämtliche Spuren beseitigen Unregister-PSSessionConfiguration -Name 'JEAPrintServerSession' Restart-Service -Name 'WinRM' Remove-Item -Path "$env:ProgramDataJEASessionConfigurationsJEAPrintServerSession.pssc" -Force Remove-Item -Path "$env:ProgramFilesPowerShellModulesAbcFirma" -Recurse -Force Remove-Item -Path "$env:ProgramFilesWindowsPowerShellModulesAbcFirma" -Recurse -Force Remove-LocalGroup -Name 'LocalPrinterManagerGroup' Remove-LocalUser -Name 'DruckerHorst' Set-Item -Path "WSMan:localhostClientTrustedHosts" -Value ([String]::Empty) - Force Disable-PSRemoting -Force Get-NetAdapter -Physical | Set-NetConnectionProfile -NetworkCategory "Public"
  • 17. C12_Sicherheit-an-PowerShell.md 7/11/2020 17 / 18 PowerShell Sicherheit per GPO verteilen PowerShell Sicherheit per GPO in der ActiveDirectory-Domäne verteilen. EdgeUI.admx User / Windows Components / Edge UI / Prevent users from replacing the Command Prompt with Windows PowerShell in the menu they see when they right-click the lower-left corner or press the Windows logo key+X HKCUSoftwarePoliciesMicrosoftWindowsEdgeUI!ShowCommandPromptOnWinX PowerShellExecutionPolicy.admx Machine / Windows Components / Windows PowerShell / Turn on PowerShell Script Block Logging HKLMSoftwarePoliciesMicrosoftWindowsPowerShellScriptBlockLogging!EnableScriptBlockLo gging HKLMSoftwarePoliciesMicrosoftWindowsPowerShellScriptBlockLogging!EnableScriptBlockIn vocationLogging User / Windows Components / Windows PowerShell / Turn on PowerShell Script Block Logging HKCUSoftwarePoliciesMicrosoftWindowsPowerShellScriptBlockLogging!EnableScriptBlockLo gging HKCUSoftwarePoliciesMicrosoftWindowsPowerShellScriptBlockLogging!EnableScriptBlockIn vocationLogging Machine / Windows Components / Windows PowerShell / Turn on PowerShell Transcription HKLMSoftwarePoliciesMicrosoftWindowsPowerShellTranscription!EnableTranscripting HKLMSoftwarePoliciesMicrosoftWindowsPowerShellTranscription!OutputDirectory HKLMSoftwarePoliciesMicrosoftWindowsPowerShellTranscription!EnableInvocationHeader User / Windows Components / Windows PowerShell / Turn on PowerShell Transcription HKCUSoftwarePoliciesMicrosoftWindowsPowerShellTranscription!EnableTranscripting HKCUSoftwarePoliciesMicrosoftWindowsPowerShellTranscription!OutputDirectory HKCUSoftwarePoliciesMicrosoftWindowsPowerShellTranscription!EnableInvocationHeader Epilog Von mir gibt es noch weitere PowerShell-Fachartikel und Guides. Und jetzt Neu, abonnieren Sie meinen PowerShell-YouTube-Kanal. Oder Wissen vom Trainer mit vielen praxisbezogenen Übungen, Wissenstests und Frage und Antwort-Runden. Jetzt in meinen PowerShell-Seminaren und -Workshops. Wenn Sie diesen Artikel als hilfreich empfunden haben würde ich mich über eine Erwähnung und einen Verweis auf diesen Artikel in den sozialen Medien sehr freuen. Als Dankeschön bekommen Sie ein von mir erstelltes hochwertiges A1-PowerShell-7-Poster mit den wichtigsten Informationen für die tägliche Arbeit per Post zugesendet. Hierzu schreiben Sie mir an info at attilakrick.com einfache eine E-Mail mit dem Link der Erwähnung sowie Ihre Adresse. Aber nur solange der
  • 18. C12_Sicherheit-an-PowerShell.md 7/11/2020 18 / 18 Vorrat reicht. Ihre Daten (E-Mail, Adresse) werden nur zum Zweck des Poster-Versandes benötigt und anschließend gelöscht. [site_reviews_form title="Bitte bewerten Sie diesen Artikel" category="121" assign_to="258" id="kcb17qh9" hide="title,content,name,email,terms"]