In den Niederungen von SecureString mittels Powershell


Im ersten Blogbeitrag zu SecureString bin ich auf die allgemeine Anwendung von SecureStrings in Powershell und indirekt im .Net-Framework eingegangen. https://newyear2006.wordpress.com/2012/12/30/spa-mit-net-securestring-und-powershell-oder-sicheres-speichern-und-einlesen-von-passwrtern/

Wenn man mit den SecureStrings herumspielt, fällt einem schnell auf, dass diese quasi immer einen gleichen Header verwenden. Dieser beginnt immer mit der folgenden Zeichenfolge:

01000000d08c9ddf0115d1118c7a00c04fc297eb

Ab hier wird es nun interessant. Wenn man Google bemüht, kommen nicht all zu viele Treffer bei raus: https://www.google.de/search?q=01000000d08c9ddf0115d1118c7a00c04fc297eb. Aber unter den wenigen Treffern, sind wahre Perlen dabei! Denn es geht um nichts anderes als um eine eindeutige Kennung für DPAPI BLOBs welche von Windows seit Windows 2000 verwendet werden um Passwörter sicher in der Registrierung, Festplatte und Speicher abzulegen. DPAPI steht für Data Protection API. http://msdn.microsoft.com/en-us/library/ms995355.aspx.

Bleiben wir zunächst bei Powershell. Michal Grzegorzewski hat auf seiner Seite die Einträge mittels Debugger auseinandergenommen, hier die englische Übersetzung mittels Google: http://translate.googleusercontent.com/translate_c?depth=1&hl=de&prev=_dd&rurl=translate.google.de&sl=auto&tl=en&u=http://zine.net.pl/blogs/mgrzeg/archive/2011/03/11/dpapi-internals-a-securestring-w-powershellu.aspx&usg=ALkJrhhOdJ83W5rHYAcEnuML-v-KZ1KqNw. Dabei hat er festgestellt, dass Powershell die Methode Protect aus der ProtectedData Klasse aus dem .Net-Framework verwendet. http://msdn.microsoft.com/de-de/library/system.security.cryptography.protecteddata.protect.aspx. Protect verwendet wiederum CryptProtectData aus Crypt32.dll. http://msdn.microsoft.com/en-us/library/windows/desktop/aa380261(v=vs.110).aspx. Ein Punkt der bei Powershells ConvertFrom-SecureString und ConvertTo-SecureString zu kurz kommt, ist die Sache dass es sich um benutzerbezogene Verschlüsselungen handelt. D. h. ein Passwort welches mittels ConvertFrom-SecureString als verschlüsselter Standardstring konvertiert und gespeichert wurde, kann nur von dem selben Benutzer auf dem ursprünglichen Rechner wieder gelesen und verwendet werden! Um die Sache dann noch weiter zu komplizieren, sei noch darauf hingewiesen, dass das verwendete Passwort des Benutzers auch noch eine Rolle spielt, was wiederum beim Zurücksetzten von Passwörtern wichtig werden kann: http://support.microsoft.com/kb/309408. Zu welchen Probleme das benutzerbezogene Speichern führen kann, schildert schön dieser Artikel: http://blog.codeassassin.com/2012/05/17/powershell-remoting-user-profiles-delegation-and-dpapi/.

Im zweiten Bereich seines ersten Blogeintrags unter “DAPI Internals” streift Grzegorzewski noch die Geschichte von Masterkeys und dass auf jedem Windows immer die vorhergehenden Keys gespeichert sein müssen, um auf ältere, verschlüsselte Daten zurückgreifen zu können. Thema CREDHIST. Aber das Thema lassen wir außen vor. Im zweiten Blog-Artikel geht er dann noch näher auf die Internas von DAPI Blobs ein http://translate.google.de/translate?hl=de&sl=auto&tl=en&prev=_dd&u=http%3A%2F%2Fzine.net.pl%2Fblogs%2Fmgrzeg%2Farchive%2F2011%2F03%2F30%2Fdpapi-internals-a-securestring-w-powershellu-cz-2.aspx. Dort nennt er Picod and Bursztein, welche das Tool libDPAPIck.dll, zu finden unter http://dpapick.com/ entwickelt haben. Das Tool erlaubt das Lesen von EFS-verschlüsselten Laufwerken von Linux oder anderen Offlinesystemen aus.

So nach dem kleinen Ausflug, wieder zurück zum Thema SecureStrings und Powershell. Im ersten Artikel https://newyear2006.wordpress.com/2012/12/30/spa-mit-net-securestring-und-powershell-oder-sicheres-speichern-und-einlesen-von-passwrtern/ wurde ja schon gezeigt, wie man ein Passwort wiederherstellen und sichtbar machen kann. Nun wollen wir die von Grzegorzewski verwendete Methode mittels Powershell auf den verschlüsselten Standardstring anwenden.

Wir haben also aus unserem ersten Artikel die Zeichenfolge

01000000d08c9ddf0115d1118c7a00c04fc297eb01000000d13e0b3adb59f6469325c229ee5b0d520000000002000000000003660000c0000000100
00000d57efc5b5ccd1e52e71296ec9b91a3530000000004800000a0000000100000006b946cd8b1c877db8c8ae6f39f4932bd10000000858fb31747
0ef57f405d954a5857409a14000000e2154da0885013dc5dbf21097c61c1d429f1e8ce

Dabei handelt es sich um einen Hexstring. Für den Aufruf von Unprotect http://msdn.microsoft.com/en-us/library/system.security.cryptography.protecteddata.unprotect wird als Parameter ein Bytearray benötigt. Dazu benötigen wir als erstes eine Hilfsfunktion, welche den verschlüsselten Standardstring in ein ByteArray umwandelt, diese gibt es hier: http://www.sans.org/windows-security/2010/02/11/powershell-byte-array-hex-convert und nennt sich Convert-HexStringToByteArray. Also los gehts:

# $es enthält obigen String
Import-Module .\HexHelper.PS1
$eb=Convert-HexStringToByteArray $es
$mb=[System.Security.Cryptography.ProtectedData]::Unprotect($eb,$null,"CurrentUser")
[System.Text.Encoding]::Unicode.GetString($mb)

Zurück bekommen wir dann das ursprüngliche “Hallo”.

Dabei gibt es noch ein paar Dinge zu beachten. Der Aufruf von Unprotect funktioniert erst, wenn davor ConvertFrom-SecureString bereits benutzt wurde! Falls dies nicht der Fall ist, bekommt man die Fehlermeldung

Der Typ [System.Security.Cryptography.ProtectedData] wurde nicht gefunden: Vergewissern Sie sich, dass die Assembly, die diesen Typ usw…

Zum Warmlaufen kann man diesen Befehl vorher verwenden:

Read-Host – AsSecureString | ConvertFrom-SecureString

Wie oben bereits geschrieben, die Strings sind immer benutzerbezogen, wenn man also den String auf einer anderen Maschine versucht zu verarbeiten, erhält man die Meldung:

Ausnahme beim Aufrufen von "Unprotect" mit 3 Argument(en):  “Schlüssel ist im angegebenen Status nicht gültig."

3 Antworten to “In den Niederungen von SecureString mittels Powershell”

  1. Wifi Netzwerksicherheitsschlüssel unter Windows per Powershell auslesen « Das nie endende Chaos! Says:

    […] Noch etwas mehr Hintergrund, wie man in den tiefen von SecureString die DPAPI benutzt: https://newyear2006.wordpress.com/2012/12/30/in-den-niederungen-von-securestring-mittels-powershell/ […]

  2. Quirel Says:

    Zum „Warmlaufen“ kann man aber auch einfach Add-Type -assembly System.Security aufrufen anstatt Read-Host – AsSecureString | ConvertFrom-SecureString.

  3. Quirel Says:

    Interessant zur Recovery des Windows Vault wird auch DPAPI benötigt. Hier eine Anleitung, wie man einen gesicherten Tresor auf einem anderen Rechner auslesen kann: https://technet.microsoft.com/en-us/library/ee681624(v=ws.10).aspx
    Dazu gibt es ein Programm DPAPIMG.EXE, welches dabei hilft.

Schreibe einen Kommentar

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s


%d Bloggern gefällt das: