Blog

Azure Credentials und wo sie zu finden sind

15.1.2023 | 4 minutes read
Share this:

Einleitung

Inspiriert von diesem Blog-Eintrag und diesem Blog-Eintrag, habe ich einmal versucht herauszufinden, wo im Betriebssystem überall Azure-Zugangsdaten, also JWTs oder Refresh-Tokens, gespeichert werden, wenn die Anwender bestimmte Tools, die mit Azure interagieren, verwenden.

Ein JWT (JSON Web Token) ist eine Möglichkeit, wie ein Client Anmeldeinformationen speichern und an den Server übertragen kann. Die Informationen werden in einem JSON-Objekt gespeichert und dann mithilfe einer digitalen Signatur geschützt. Diese Signatur verhindert, dass die Informationen auf dem Client oder während der Übertragung verändert werden. Der Server kann die Signatur prüfen und die angefragten Daten bereitstellen, bzw. die gewünschten Aktionen ausführen. Genaue Details zu JWT oder Refresh-Tokens können hier gefunden werden.

Das spannende an dem Thema ist, dass im Gegensatz zu den Single-Sign-On Informationen (Kerberos & NT-Hash) in einem on-premise Active Directory, die nur mit Administrator-Rechte ausgelesen werden können, hier im Benutzerkontext auf die Daten zugegriffen werden kann.

Azure PowerShell

Die Azure PowerShell von Microsoft ist eines von vielen Werkzeugen mit denen Administratoren auf Azure und vor allem auf die Ressourcen darin zugreifen und verwalten können. Bevor die Azure PowerShell verwendet werden kann, muss der Benutzer eine Anmeldung an Azure durchführen. Der Befehl dazu lautet Connect-AzAccount.

Wenn der Befehl ausgeführt wird, kann in Procmon beobachtet werden, dass zwei Dateien von PowerShell geschrieben werden.

AzPowerShell-Procmon

Die AzureRMContext.json enthält JSON-Daten, die unter Umständen ein AccessToken enthalten können. Unter welchen Umständen ein Azure Token vorhanden ist, konnte ich nicht nachvollziehen.

AzPowerShell-AzureRMContext

Weiterhin wird die Datei msal.cache geschrieben. Beim Betrachten der Datei fällt zunächst auf, dass sie nicht lesbar ist. Wer allerdings genauer hinsieht und die Datei in einem Hex-Editor öffnet, der erkennt eine bekannte Signatur am Beginn der Datei. Der HEX-Wert 01000000d08c ist charakteristisch für einen DPAPI-Blob. Das bedeutet, dass die Datei mit der DPAPI verschlüsselt wurde. Das Gute an einem DPAPI-Blob ist, dass er mit einem PowerShell Skript entschlüsselt werden kann, zumindest solange es der Eigene ist.

AzPowerShell_MSALCACHE

Add-Type -AssemblyName System.Security;
$Path = <Pfad zur msal.cache Datei>

$data = Get-Content -Path $Path -Encoding Byte
$scope = [System.Security.Cryptography.DataProtectionScope]::CurrentUser
$plaintext = [System.Security.Cryptography.ProtectedData]::Unprotect($data, $null, $scope )
[System.Text.UTF8Encoding]::UTF8.GetString($plaintext)

Im Anschluss kann der Inhalt der Datei gelesen werden. Die Datei enthält ein JSON-Objekt, mit diversen Access- und RefreshTokens.

Azure CLI

Die Azure CLI ist ein in Python geschriebenes Framework, das die plattformübergreifende Verwaltung und Steuerung von Azure erlaubt. Für die Anmeldung in der Azure CLI wird der Befehl az login verwendet. Nach bzw. während der Anmeldung werden unter Windows mehrere Dateien geschrieben.

AzCLILogin

In der Datei accessTokens.json werden diverse Access- und RefreshTokens gespeichert, die für die Azure CLI notwendig sind.

AzCLIToken

M365 Office

Die Frage, wo Office seine Tokens/Zugangsdaten speichert, wurde in einem der genannten Artikel am Anfang schon beleuchtet. Hier nochmal kurz die Zusammenfassung: Office Anwendungen speichern die Zugangsdaten in %LOCALAPPDATA%\Microsoft\TokenBroker\Cache. Hier liegen eine ganze Reihe an Dateien mit der Endung .tbres. Jede Datei enthält ein JSON-Objekt, die wiederum aus weiteren JSON-Objekten bestehen, unter anderem eines mit dem Namen ResponseBytes, dass den Wert IsProtected enthält. Wenn man die Zeichenkette hinter Value anschaut, erkennt man wieder einen alten bekannten: AQAAAN.

Office1

Das entspricht der Base64-enkodierten Version vom oben genannten DPAPI-Header. Um den Wert im Klartext ausgeben zu können, müssen wir das Skript von eben etwas modifizieren.

Add-Type -assembly System.Security
$data = "AQAAANCMnd8B [...]"
$decodedData = [Convert]::FromBase64String($data)
$decryptedData = [System.Security.Cryptography.ProtectedData]::Unprotect($decodedData, $null, [System.Security.Cryptography.DataProtectionScope]::LocalMachine )
$enc = [system.text.encoding]::Default
$enc.GetString($decryptedData)

Die Daten, die dabei rauskommen, sehen zwar etwas weniger strukturiert aus. JWT-Tokens mit dem bekannten Start eyJ0 können darin trotzdem erkannt werden.

Office2

Prozesse

Der nächste Ort, an dem Azure-Tokens gefunden werden können, sind alle möglichen Prozesse, die mit Azure interagieren. Am einfachsten kommt ihr an die Tokens, wenn ihr ein Speicherabbild von Prozessen wie teams.exe und co. erstellt. Dafür könnt ihr beispielsweise den Task-Manager verwenden. Im Anschluss können die Abbilder mit Tools wie strings aus den Sysinternals analysiert werden. Hier könnt ihr einfach nach eyJ0 suchen und schauen, ob die Tokens noch gültig sind.

In Kombination mit findstr kann das Ganze noch etwas beschleunigt werden.

strings.exe teams.dmp | findstr /i eyJ0eX

Process1

So das waren die Orte, die ich finden konnte und die ohne administrative Rechte zugänglich sind. Das Betriebssystem selbst speichert natürlich auch Informationen ab, die für Single-Sign-On in AZure genutzt werden können. Das ist aber Stoff für einen weiteren Eintrag. Für die ungeduldigen unter euch, kann ich folgende beiden Blogs empfehlen: hier und hier.

Damit ihr das ganze nicht händisch machen müssten, habe ich ein kleines Tools dafür programmiert. Das findet ihr hier.

Falls ihr noch Ideen habt, wo JWT-Tokens gefunden werden können, dürft ihr mir gerne eine Nachricht senden. Wie immer gilt, falls ihr Fragen, Anmerkungen oder Verbesserungsvorschläge zu dem Artikel habt, schreibt eine Mail an info@hackmich.net.

Quellen