Benutzer mit den meisten Antworten
Variablen-Werte löschen, so dass sie im RAM auch gelöscht sind

Frage
-
Hi,
ich habe ein Skript geschrieben, das mir beim Passwort-Wechsel meiner vielen Accounts im AD sehr hilft.
Damit ich z. B. die Länge der neuen Passwörter prüfen kann, muss ich die Passwörter auch im Klartext in Variablen speichern.Nun würd ich gern am Ende des Skripts diese Variablen löschen/überschreiben, so dass insbesondere die Klartext-Passwörter auch im RAM nicht mehr auslesbar sind (z.B. von Malware oder sonstigen Tools). So lange die Shell nicht beendet wird, wären die Kennwörter ja noch auslesbar.
Ich weiß im Detail nicht, wie Powershell Variablen im RAM anlegt und was es beim Überschreiben und beim Löschen von Variablen genau macht.
Zum besseren Verständnis der Vergleich mit dem Filesystem: Eine Datei zu löschen löscht ja nicht den Inhalt der Datei auf der Festplatte, sondern nur den Eintrag in der MFT. Die Daten sind also erst mal noch vollständig vorhanden (klar, bis sie dann mal überschrieben werden). Richtig löschen heißt also die Daten auf der Platte überschreiben.
Wie mach ich das also in Posh? Remove-Variable? Variablen mit "xXxX..." überschreiben?
Oder meint Ihr, dass ich mir das sparen kann, weil eine Malware sich z. B. mit Key-Logging die Kennwörter holen kann, so dass das Aufräumen am Ende eh nix mehr bringt?
Danke & Gruß
Walter
Antworten
-
Ich denke du machst die zu viel Gedanken um ein theoretisches Problem. Ich garantiere dir, es gibt mindestens 5 deutlich wahrscheinlichere, deutliche simplere Angriffsmethoden, mit denen jemand ein Passwort für euer AD herausbekommt, wenn er denn will.
Die meisten relevanten Angriffe funktionieren über social engineering oder -ganz ohne Passwort- über ungefixte Sicherheitslücken.Das heisst nicht das man sorglos sein sollte, aber es bringt auch nichts, sich bei einem Cabrio zu viel Gedanken um das Türschloss zu machen.
Benutze secure strings und da wo das nicht geht schlaues scoping, und entferne damit automatisch Variablen sobald sie nicht mehr benötigt werden. Mehr musst du nicht tun.Denniver
Blog: http://bytecookie.wordpress.com
Powershell Codesnippet Manager: Link
Hilf mit und markiere hilfreiche Beiträge mit dem "Abstimmen"-Button (links) und Beiträge die eine Frage von dir beantwortet haben, als "Antwort" (unten).
Warum das Ganze? Hier gibts die Antwort.- Als Antwort markiert WalterFMB Freitag, 23. Mai 2014 11:37
-
oder einfacher, wenn es dir nur um die Laenge geht und nicht auch um die Zusammensetzung (Buchstaben, Ziffern, ...)
$PwdHorst = Read-Host -Prompt 'Passwort Eingeben für den Account "Horst"' -AsSecureString $PwdHorst.Length
denn System.Security.SecureString besitzt das Property Length!
http://msdn.microsoft.com/de-de/library/system.security.securestring(v=vs.110).aspxBeste Gruesse
brima- Als Antwort vorgeschlagen Alex Pitulice Freitag, 2. Mai 2014 09:42
- Als Antwort markiert Alex Pitulice Mittwoch, 7. Mai 2014 08:03
-
Hallo Peter,
danke für die Einladung zur Posh-Konferenz. Ich kann aber leider nicht kommen.
Die alten und neuen Passwörter lass ich natürlich als SecureString einlesen, also mit Read-Host-AsSecureString.
Und die Rückumwandlung von Secure in Plaintext String mach ich auch schon.
Muss ich auch, weil ich z. B. die Passwortlänge bei einem SecureString ja nicht prüfen kann.Und dann hab ich eben Variablen mit dem Passwort im Klartext.
Diese Variablen, genauer: deren Werte möchte ich im Speicher/RAM überschreiben, damit nach Skriptende, wenn die Shell noch länger läuft, die Klartext-Passwörter nicht mehr auslesbar sind.Wie mach ich das?
Ganz Einfach!
Indem du das Klartext Passwort NIEMALS einer Variablen zuweist sonder IMMER direct mit dem SecureString Arbeitest.
Etwa so:
$PwdHorst = Read-Host -Prompt 'Passwort Eingeben für den Account "Horst"' -AsSecureString # Wir besorgen uns die Adresse (pointer) zu dem SecureString im Speicher $PasswordPointer = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($PwdHorst) # Nun wird der SecureString im Klartext ausgelesen "Die Länge vom Passwort ist: " + ([Runtime.InteropServices.Marshal]::PtrToStringAuto($PasswordPointer)).Length
PowerShell Artikel, Buchtipps und kostenlose PowerShell Tutorials + E-Books
auf der deutschsprachigen PowerShell Community
Mein 21 Teiliger PowerShell Video Grundlehrgang
Deutsche PowerShell Videos auf Youtube
Folge mir auf:
Twitter | Facebook | Google+- Als Antwort vorgeschlagen Alex Pitulice Freitag, 2. Mai 2014 09:42
- Als Antwort markiert Alex Pitulice Mittwoch, 7. Mai 2014 08:03
Alle Antworten
-
Hallo,
es gibt Leute die koennen dein Auto, deine Haustuer aufbrechen, auch wenn sie verschlossen sind. Ich denke nicht das Du dir deswegen das Zusperren in der Zukunft ersparst. :-)
Variablen kannst Du so loeschen
$a = 5 Remove-Variable a
Es gilt aber auch folgendes zu beachten
Get-Help about_Scopes
Also Variablen im Script's/Functionen die nicht den Scope GLOBAL haben sind nach beenden eh weg.
Ev. ist sinnvoll nach dem Beenden des Scripts noch den Speicher "aufzuraeumen" mit einer sogeannten Garbage Collection .
Dies kannst Du so ausloesen:
[GC]::Collect()
Beste Gruesse
brima -
Ein Wort zu Garbage Collection:
Powershell macht am Ende eines Scriptes automatisch eine Garbage Collection, daher ist ein manuelles aufrufen überflüssig.
Innerhalb eines Scriptes (man könnte ja auf die Idee kommen, z.b. wegen zu wenig Speicher...) benutzt, hat eine manuelle Garbage Collection ebenfalls in der Regel nicht die gewünschte Konsequenz, nur das das Script oft nicht mehr vernünftig bzw. wie erwartet funktioniert.
Generell würde ich strengstens davon abraten [GC]::Collect() überhaupt zu benutzen, es sei denn man ist absolut sicher das man ganz genau weiss was man tut.
(Wers genau wissen möchte: LINK )
Grüße, Denniver
Blog: http://bytecookie.wordpress.com
Powershell Codesnippet Manager: Link
Hilf mit und markiere hilfreiche Beiträge mit dem "Abstimmen"-Button (links) und Beiträge die eine Frage von dir beantwortet haben, als "Antwort" (unten).
Warum das Ganze? Hier gibts die Antwort.
- Bearbeitet Denniver ReiningMVP, Moderator Mittwoch, 30. April 2014 00:01
-
Hallo Walter!
Ich halte über das Thema Passwörter einen Vortrag auf der PowerShell Community Konferenz in Oberhausen am 6.-8.5.2014.
Dort zeige ich auch wie man Passwörter ‚sicher‘ Abspeichert.
Siehe: http://www.powershell.de
Ihr seid alle eingeladen dorthin zu kommen ;-)
Passwörter sollte man in der PowerShell IMMER in einer Variablen vom Typ SecureString ablegen.
Dann ist das Passwort im Speicher geschützt!
Zitat Dokumentation SecureString:
„Aus Datenschutzgründen wird der Text bei Verwendung verschlüsselt und, wenn er nicht mehr benötigt wird, aus dem Computerspeicher gelöscht.
Eine Instanz der System.String-Klasse ist unveränderlich und kann, wenn sie nicht mehr benötigt wird, nicht programmgesteuert für die Garbage Collection geplant werden. Dies bedeutet, dass die Instanz nach dem Erstellen schreibgeschützt ist und dass nicht vorhersagbar ist, wann die Instanz aus dem Computerspeicher gelöscht wird. Wenn ein String-Objekt vertrauliche Informationen wie Kennwörter, Kreditkartennummern oder persönliche Daten enthält, besteht daher ein Risiko, dass nach der Verwendung auf die Informationen zugegriffen werden kann, da die Anwendung die Daten nicht aus dem Computerspeicher löschen kann.
Ein SecureString-Objekt ähnelt einem String-Objekt darin, dass es einen Textwert besitzt. Der Wert eines SecureString-Objekts wird jedoch automatisch verschlüsselt und kann geändert werden, solange er von der Anwendung nicht als schreibgeschützt markiert wurde. Außerdem kann er von der Anwendung oder dem Garbage Collector von .NET Framework aus dem Computerspeicher gelöscht werden.
Der Wert einer Instanz von SecureString wird automatisch verschlüsselt, wenn die Instanz initialisiert oder der Wert geändert wird. Ihre Anwendung kann die Instanz als unveränderlich festlegen und weitere Änderungen durch Aufrufen der MakeReadOnly-Methode verhindern.
Beachten Sie, dass SecureString keine Member besitzt, die den Wert von SecureString überprüfen, vergleichen oder konvertieren. Das Fehlen solcher Member erleichtert es, den Wert der Instanz vor versehentlicher oder böswilliger Verfügbarmachung zu schützen. Verwenden Sie geeignete Member der System.Runtime.InteropServices.Marshal-Klasse, z. B. die SecureStringToBSTR-Methode, um den Wert eines SecureString-Objekts zu ändern.
Die SecureString-Klasse wird von der CriticalFinalizerObject-Klasse abgeleitet und implementiert die IDisposable-Schnittstelle. Weitere Informationen zum Implementieren der IDisposable-Schnittstelle finden Sie unter Garbage Collection.
Die SecureString-Klasse und ihre Member sind für COM nicht sichtbar. Weitere Informationen finden Sie unter ComVisibleAttribute.
“
….Ende Zitat
Siehe: http://msdn.microsoft.com/de-de/library/system.security.securestring%28v=vs.110%29.aspx
Damit sollten sich deine Schmerzen erledigt haben.
Du kannst dir mit Get-Credential mehrere Accounts + Passwörter in Variablen Ablegen
Oder du nimmst Read-Host –AsSecureString.
# Credentials einlesen $CredHorst = Get-Credential -Message 'Passwort Eingeben für den Account "Horst"' $CredWilly = Get-Credential -Message 'Passwort Eingeben für den Account "Willy"' $CredWerner = Get-Credential -Message 'Passwort Eingeben für den Account "Werner"' # oder nur Passwort einlesen $PwdHorst = Read-Host -Prompt 'Passwort Eingeben für den Account "Horst"' -AsSecureString $PwdWilly = Read-Host -Prompt 'Passwort Eingeben für den Account "Willy"' -AsSecureString $PwdWerner = Read-Host -Prompt 'Passwort Eingeben für den Account "Werner"' -AsSecureString
Nur der Prozess der das Passwort im Speicher als SecureString abgelegt hat kommt an diese wieder heran!
Deshalb kann nur der eine Prozess das Passwort wieder in Klartext umwandeln!
Den Klartext von Credentials kannst du so auslesen
# Credentials einlesen $CredHorst = Get-Credential -Message 'Passwort Eingeben für den Account "Horst"' $CredHorst.GetNetworkCredential().Password
Den Klartext von SecurString kannst du so auslesen:
$PwdHorst = Read-Host -Prompt 'Passwort Eingeben für den Account "Horst"' -AsSecureString # Wir besorgen uns die Adresse (pointer) zu dem SecureString im Speicher $PasswordPointer = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($PwdHorst) # Nun wird der SecureString im Klartext ausgelesen $PlainTextPassword = [Runtime.InteropServices.Marshal]::PtrToStringAuto($PasswordPointer) $PlainTextPassword
PowerShell Artikel, Buchtipps und kostenlose PowerShell Tutorials + E-Books
auf der deutschsprachigen PowerShell Community
Mein 21 Teiliger PowerShell Video Grundlehrgang
Deutsche PowerShell Videos auf Youtube
Folge mir auf:
Twitter | Facebook | Google+- Bearbeitet Peter Kriegel Mittwoch, 30. April 2014 08:18
-
Hallo Denniver,
ich selbst habe nur ein Script, wo ich [GC]::Collect() nutze.
Das entsprechende Script laeuft nachts bedienerlos als System User. Es befuellt bzw. Updated eine groessere Excel Datei mit Daten.
Mir ist ausgefallen, das nicht immer aber oft im TaskManger EXCEL - Prozesse fuer den System User vorhanden waren, obwohl das Script schon lange beendet war.
Durch loeschen der entsp. Variablen fuer das EXCEL COM Objekt am Ende des Scripts (also nach dem beenden von Excel) trat das verhalten bereits seltener auf und seit ich auch noch eine GC ausloese habe ich Ruhe.
Beste Gruesse
brima -
Hi Brima,
ich kenne Remove-Variable auch. Aber ich weiß nicht, ob damit auch der Speicherbereich im RAM, den die Variable belegt, mit z. B. 0x0 überschrieben wird.
Genau darum geht es mir.
Ich könnte auch den Wert der Variable zuerst mit "xXxX" überschreiben, bevor ich sie mit Remove-Variable lösche. Aber auch hier weiß ich nicht, ob der vorher belegte Speicherbereich wirklich überschrieben wird oder einfach auf einen neuen Speicherbereich gezeigt wird, der den neuen Wert enthält. -
Walter ich glaube hier steht alles was du wissen musst:
Fazit: Keiner kann dir Garantieren wann ein Objekt (Variable) zerstört wird!
Nimm den SecureString!
PowerShell Artikel, Buchtipps und kostenlose PowerShell Tutorials + E-Books
auf der deutschsprachigen PowerShell Community
Mein 21 Teiliger PowerShell Video Grundlehrgang
Deutsche PowerShell Videos auf Youtube
Folge mir auf:
Twitter | Facebook | Google+- Bearbeitet Peter Kriegel Mittwoch, 30. April 2014 13:25
-
Ich denke du machst die zu viel Gedanken um ein theoretisches Problem. Ich garantiere dir, es gibt mindestens 5 deutlich wahrscheinlichere, deutliche simplere Angriffsmethoden, mit denen jemand ein Passwort für euer AD herausbekommt, wenn er denn will.
Die meisten relevanten Angriffe funktionieren über social engineering oder -ganz ohne Passwort- über ungefixte Sicherheitslücken.Das heisst nicht das man sorglos sein sollte, aber es bringt auch nichts, sich bei einem Cabrio zu viel Gedanken um das Türschloss zu machen.
Benutze secure strings und da wo das nicht geht schlaues scoping, und entferne damit automatisch Variablen sobald sie nicht mehr benötigt werden. Mehr musst du nicht tun.Denniver
Blog: http://bytecookie.wordpress.com
Powershell Codesnippet Manager: Link
Hilf mit und markiere hilfreiche Beiträge mit dem "Abstimmen"-Button (links) und Beiträge die eine Frage von dir beantwortet haben, als "Antwort" (unten).
Warum das Ganze? Hier gibts die Antwort.- Als Antwort markiert WalterFMB Freitag, 23. Mai 2014 11:37
-
Hallo Peter,
danke für die Einladung zur Posh-Konferenz. Ich kann aber leider nicht kommen.
Die alten und neuen Passwörter lass ich natürlich als SecureString einlesen, also mit Read-Host-AsSecureString.
Und die Rückumwandlung von Secure in Plaintext String mach ich auch schon.
Muss ich auch, weil ich z. B. die Passwortlänge bei einem SecureString ja nicht prüfen kann.Und dann hab ich eben Variablen mit dem Passwort im Klartext.
Diese Variablen, genauer: deren Werte möchte ich im Speicher/RAM überschreiben, damit nach Skriptende, wenn die Shell noch länger läuft, die Klartext-Passwörter nicht mehr auslesbar sind.Wie mach ich das?
- Bearbeitet WalterFMB Mittwoch, 30. April 2014 14:07
-
Hallo Peter,
danke für die Einladung zur Posh-Konferenz. Ich kann aber leider nicht kommen.
Die alten und neuen Passwörter lass ich natürlich als SecureString einlesen, also mit Read-Host-AsSecureString.
Und die Rückumwandlung von Secure in Plaintext String mach ich auch schon.
Muss ich auch, weil ich z. B. die Passwortlänge bei einem SecureString ja nicht prüfen kann.Und dann hab ich eben Variablen mit dem Passwort im Klartext.
Diese Variablen, genauer: deren Werte möchte ich im Speicher/RAM überschreiben, damit nach Skriptende, wenn die Shell noch länger läuft, die Klartext-Passwörter nicht mehr auslesbar sind.Wie mach ich das?
Ganz Einfach!
Indem du das Klartext Passwort NIEMALS einer Variablen zuweist sonder IMMER direct mit dem SecureString Arbeitest.
Etwa so:
$PwdHorst = Read-Host -Prompt 'Passwort Eingeben für den Account "Horst"' -AsSecureString # Wir besorgen uns die Adresse (pointer) zu dem SecureString im Speicher $PasswordPointer = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($PwdHorst) # Nun wird der SecureString im Klartext ausgelesen "Die Länge vom Passwort ist: " + ([Runtime.InteropServices.Marshal]::PtrToStringAuto($PasswordPointer)).Length
PowerShell Artikel, Buchtipps und kostenlose PowerShell Tutorials + E-Books
auf der deutschsprachigen PowerShell Community
Mein 21 Teiliger PowerShell Video Grundlehrgang
Deutsche PowerShell Videos auf Youtube
Folge mir auf:
Twitter | Facebook | Google+- Als Antwort vorgeschlagen Alex Pitulice Freitag, 2. Mai 2014 09:42
- Als Antwort markiert Alex Pitulice Mittwoch, 7. Mai 2014 08:03
-
oder einfacher, wenn es dir nur um die Laenge geht und nicht auch um die Zusammensetzung (Buchstaben, Ziffern, ...)
$PwdHorst = Read-Host -Prompt 'Passwort Eingeben für den Account "Horst"' -AsSecureString $PwdHorst.Length
denn System.Security.SecureString besitzt das Property Length!
http://msdn.microsoft.com/de-de/library/system.security.securestring(v=vs.110).aspxBeste Gruesse
brima- Als Antwort vorgeschlagen Alex Pitulice Freitag, 2. Mai 2014 09:42
- Als Antwort markiert Alex Pitulice Mittwoch, 7. Mai 2014 08:03
-
Super Prima, Brima!
Das habe ich übersehen!
PowerShell Artikel, Buchtipps und kostenlose PowerShell Tutorials + E-Books
auf der deutschsprachigen PowerShell Community
Mein 21 Teiliger PowerShell Video Grundlehrgang
Deutsche PowerShell Videos auf Youtube
Folge mir auf:
Twitter | Facebook | Google+