Scripting: Das sichere Speichern von Passwörtern

Um seine privaten Passwörter zu speichern gibt es ja mittlerweile viele Tools wie z.B. PasswortDepot, Keepass, oder Lastpass die ein verschlüsseltes speichern ermöglichen.
Im Firmenumfeld gibt es aber unter Umständen einige Gründe in denen man Passwörter in Powershell oder Batch Scripten ablegen muss.
Jetzt gibt es verschiedene Wege ein Passwort zu speichern und zu nutzen:
1. Im Klartext
Leider ist es immer noch viel zu oft gängige Praxis, das Passwort aufgrund von Faulheit einfach im Klartext in einer Textdatei abzuspeichern.
2. Verschlüsselt via MD5/SHA-1
Die Verschlüsselung des Passwortes sollte auf jeden Fall im Umgang mit Kundendaten oder zum Beispiel für Logindaten erfolgen.
Wenn man ein automatischen Cronjob erzeugt der Remote Daten abgreift, bringt dies allerdings nichts, da ja immer noch das Kennwort (zum Entschlüsseln) irgendwo gespeichert bzw. eingegeben werden muss.
Weitere Infos zum Hashen von Passwörter findet ihr hier sehr schön beschrieben.
3. Verwendung des PSCredential (unter Windows)
Mit der Powershell wurde das PSCredential-Objekt eingeführt – ein Objekt in dem Username + Passwort verschlüsselt abgelegt werden.
Diese Funktion basiert auf der Windows Data Protection Api (DPAPI) wie auch alle anderen Windows-Anwendungen wie z.B. Internet Explorer usw.
Das erzeugen eines PSCredentials funktioniert zum Beispiel so:

$pw = Get-Credential

Wie man sieht besteht das Objekt aus Benutzernamen und dem Passwort welches als „System.Security.SecureString“ gespeichert wird:

PS C:\Users\Constey> $pw
UserName                                                               Password
--------                                                               --------
asd                                                System.Security.SecureString

Um das Passwort jetzt abspeichern zu können muss es in einen String konvertiert werden. Dieser String ist bereits verschlüsselt und sieht ungefähr so aus:

PS C:\Users\Constey> $pw.Password | ConvertFrom-SecureString
01000000d08c9ddf0115d1118c7a00c04fc297eb01000000cbd08902a5e36247a761f726c190898
f00000000020000000000106600000001000020000000db8dea5f0d8c77a856c7a156f2a0ebfc19
ce82a95bfc0877192fe3771178ae2f000000000e8000000002000020000000d172638c2edc9eeca
2b764e052fc94b2671d3b62fdcfb2edd98fac306a22d65670000000bbd1fb42c2f91ffc4f9abac5
4c1fc5cdf0396fee5db1f9bc1d21070c2cc07f1911c0f8af85c9eef1019bc50fd382bb120fb8826
7a51115677520452d6eb5347a615218419e3d5803170a3c71e58b5789f1de597082d5d9eb68af66
598590a1607b7975d3c70d6ae09c70ce781cb0f8e8400000001a1c3903abcc486186818c9695b88
b6c54acfb973a7e6670bd08f78653a275791b42b88d823db04348262908b37fdb03bd6d719a05f5
ea35917e69ab96a44a32

Zum Speichern in einer Datei kann man die Ausgabe per Pipe umleiten:

PS C:\Users\Constey> $pw.Password | ConvertFrom-SecureString | out-file c:\temp\test.txt

Wie liest man ein gespeichertes Passwort aus einer Datei wieder ein ?

$username = "test"
$pw = cat c:\temp\test.txt | ConvertTo-SecureString
$credential = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $pw

Hier sollte beachtet werden, dass man den Usernamen explizit nochmal von Hand angeben muss, das Kennwort aber aus der Datei importiert wird.
Die $credential Variable ist nun wieder unser PSCredential-Objekt und kann normal weiter verwendet werden.

Get-WmiObject -Query "Select * FROM Win32_OperatingSystem" -Credential $credential

Wenn man nur das Passwort als SecureString über die Konsole einlesen möchte geht dies alternativ auch so:

$pwOnly = read-host -assecurestring

[stextbox id=“info“]Seit Powershell 3.0 gibt es auch die Möglichkeit vollständige Objekte als XML-Datei zu exportieren. Dies kann unter Umständen einfacher sein, da dass Passwort automatisch konvertiert wird und das Objekt auch den Usernamen enthält.[/stextbox]

$pw = Get-Credential
$pw | Export-Clixml C:\temp\test.xml

Der Import funktioniert ebenso simple:

$pwNeu = Import-Clixml C:\temp\test.xml
PS C:\Users\Constey> $pwNeu
UserName                                                               Password
--------                                                               --------
asdasd                                             System.Security.SecureString

Die XML Datei ist wie folgt aufgebaut:

<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
  <Obj RefId="0">
    <TN RefId="0">
      <T>System.Management.Automation.PSCredential</T>
      <T>System.Object</T>
    </TN>
    <ToString>System.Management.Automation.PSCredential</ToString>
    <Props>
      <S N="UserName">asdasd</S>
      <SS N="Password">01000000d08c9ddf0115d1118c7a00c04fc297eb01000000cbd08902a5e36247a761f726c190898f00000000020000000000106600000001000020000000aa344345ba7c169386795f88c4631bde7834256b4d5f65023cf3a8520683b789000000000e8000000002000020000000b219a67d828f8fe0391687af3ca7ccfc96dfd21546b5ad45915745aed130bcd280000000bf438824b21f066088a69a8bf6c0b2286f50c2ff68b1c881b55d98d6b300d3407be4eb2de0521c21b03bdeec2cf60729ff97ead3217f592ab01954641d0c445c9a0ca77e73d83d949425613dcb51c97c917610a61239cb2aa4017141b2139a0ae7d80d738de22c0545019d38af1811dc8d89476d273f578b776cf0e7addc847c40000000bda7b710327a37477bc6db816a7ca7a3553f44fd71aff73bfa6bbaf1b16b9cc4a400fbc8c536dc08d23ed126547c3b5a049105ef8bb8ca487933755c8565aa8b</SS>
    </Props>
  </Obj>
</Objs>

[stextbox id=“info“]Wichtig: Das PSCredential bzw. der SecureString den man erzeugt wird auf Basis von der PC-Hardware aber auch von Werten des aktuellen Benutzers erzeugt. Das heißt, dass dieser String nicht unter einem anderem User funktioniert.
Das hat zudem den Vorteil, dass man ohne Zugangsdaten des Users nichts mit dem gespeichertem Passwort anfangen kann.
Eine Nutzung zum Beispiel über den Task Scheduler wäre dennoch möglich, denn man kann dort sein Script unter einem anderem Benutzer ausführen lassen. Dafür müssen bei der Erstellung des Tasks die Zugangsdaten des Benutzers einmalig angegeben werden. Diese werden dann wiederum verschlüsselt von Windows’s Credential Manager gespeichert.[/stextbox]
Abschließend gilt zu sagen, dass Sicherheit natürlich auch viel mit Bequemlichkeit zu tun hat – dennoch sollte man im Firmenumfeld seine Kennwörter nicht im Klartext in irgendwelchen Dateien abspeichern, jedenfalls sofern es nicht anders möglich ist.
Falls man dennoch mal mit unsicheren Programmen wie Net-Use, FTP etc. arbeiten muss, die keine -Credential Objekte unterstützen gibt es noch das Tool „Get-PSCredential“ von Thomas Franke, welche auch den Umgang mit solchen Programmen zumindest so Sicher wie möglich macht.

Putty Portable – Sessions in Datei speichern

Putty kennt wohl jeder Techi – ein kleines schlankes Tool um entweder Serielle, RAW, Telnet oder SSH Verbindungen aufzubauen.
In Putty kann man sich beliebige Sitzungsprofile (Sessions) also die Verbindungsdaten sowie Konfiguration abspeichern.
Putty speichert dies aber von Haus aus nur in der Registry unter folgendem Pfad:

[HKEY_CURRENT_USER\Software\SimonTatham\PuTTY]

putty-portable

Möchte man jetzt aber ein Putty Portable auf einem USB-Stick haben – half bisher nur der Workaround die Registry vorher zu exportieren und wieder zu importieren.
Dies ist hier beschrieben, aber für meinen Geschmack keine so saubere Lösung.
Möchte man automatisch Sessions starten via plink, geht das auch nur sehr schlecht – weil man vorher ja auch wieder die Registry importieren muss.
Da Putty Open-Source ist und das Problem offensichtlich schon mehrere Leute beschäftigte, hat Jakub Kotrla den Session Teil neu gecoded und hat die Speicherung der Konfiguration in einer Datei umgebaut. Somit hat man ein wirkliches Putty Portable und keine 10 Batch-Files die vorher noch das im/exportieren der Registry erledigen.
Ihr findet die kompilierte Variante hier: http://jakub.kotrla.net/putty/
Das coole ist wie gesagt: Die komplette Konfiguration wird in Dateien gespeichert . Zusätzlich bekommt man auch alle Sessions die in der Registry gespeichert sind angezeigt und kann diese auch verwenden.
Der Fix umfasst auch die Putty anhängsel wie: pageant.exe, plink.exe, pscp.exe, psftp.exe.
Wer auf Nummer sicher gehen will kann sich auch den Sourcecode anschauen und selbst kompilieren.
Über die putty.conf des Putty Portable kann man die Speicherorte der verschiedenen Objekte zusätzlich angeben. In den meisten Fällen sollte aber die Default-Einstellung ausreichen. (Speichern im gleichen Ordner wie die putty.exe)

;Save config relatively to putty.exe. you can use absolute path like to to D:\Windows Settings\PuTTY as well.
sessions=.\ssh\ses
sshhostkeys=.\ssh\hostkeys
seedfile=.\putty.rnd
sessionsuffix=.session
keysuffix=.hostkey
jumplist=jumplist.txt

Finde ich ein sehr nützlicher Patch und somit ist jetzt auch Putty Portable auf meinem Multiboot Stick zu finden 🙂