
Eine eigenständige DLL, die nach der Injektion in den KeePass-Prozess Datenbanken im Klartext exportiert.
Eine eigenständige DLL, die Datenbanken im Klartext exportiert, sobald sie in den KeePass-Prozess injiziert wurde.
Stark inspiriert von den großartigen Projekten KeeFarce, KeeThief und KeePassHax.
Vor einigen Jahren veröffentlichte @denandz KeeFarce, das erste offensive Tool, das entwickelt wurde, um KeePass-Datenbanken im Klartext zu extrahieren. Es funktioniert, indem es eine DLL in den laufenden Prozess injiziert und dann mit ClrMD den Heap durchläuft, um die notwendigen Objekte zu finden und KeePass' eingebaute Exportmethode per Reflektion aufzurufen. Sein einziger Nachteil damals war, dass mehrere Dateien auf dem Zielsystem abgelegt werden mussten (die Extraktions-DLL + ClrMD-DLL + der Injector + eine Bootstrap-DLL).
Ein Jahr später veröffentlichten @tifkin_ und @harmj0y eine ausführliche Analyse offensiver Techniken gegen KeePass (obwohl sie nicht mehr auf harmj0ys Blog verfügbar sind, sind die Artikel über die Wayback Machine zu finden: Teil 1, Teil 2). Dies führte zur Veröffentlichung von KeeThief, einem Tool, das in der Lage ist, KeePass' Masterkey zu entschlüsseln (auch wenn alternative Authentifizierungsmethoden verwendet werden). Es funktionierte so gut, dass die KeePass-Entwickler einen Parameter hinzufügten, um diese Technik abzuschwächen (er kann deaktiviert werden, indem man die KeePass-Konfigurationsdatei bearbeitet, sofern der Benutzer über ausreichende Rechte verfügt, was recht häufig vorkommt).
Diese Tools wurden während Penetrationstests schnell zu meinen bevorzugten Werkzeugen, aber sie wurden bald obsolet, da ihre Injektionstechniken (namentlich die berüchtigte Win32-API-Gang aus VirtualAllocEx, WriteProcessMemory, CreateRemoteThread, WriteProcessMemory, usw.) mittlerweile sofort Erkennung auslösen. @snovvcrash ging dieses Problem an, indem er KeeThief forkte (jetzt in einem privaten Repo, aber weiterhin hier zugänglich), um den Injektionsmechanismus mit D/Invoke zu verbessern, und schrieb einen großartigen Artikel, der den von ihm verfolgten Prozess detailliert beschreibt. Auch wenn dies die Machbarkeit der Pflege von KeeThief demonstrierte, fällt es mir schwer, regelmäßig neue Injektionstechniken zu implementieren, da KeeThiefs Code eng mit seinem Injector verknüpft ist.
@holly-cracker veröffentlichte außerdem KeePassHax, das als einzelne DLL daherkommt und ausschließlich Reflektion verwendet, um KeePass' Masterkey zu entschlüsseln. Inspiriert von dieser Arbeit entschied ich mich, dasselbe mit KeeFarce zu tun und mein eigenes KeePass-Extraktionstool mit den folgenden Funktionen zu schreiben:
KeeFarce Reborn bietet außerdem eine KeePass-Plugin-DLL, damit KeePass sich selbst injiziert, ohne sich mit Injectoren herumschlagen zu müssen!
Da der Code ausschließlich auf .NET Framework ohne externe Abhängigkeiten basiert, sollte er problemlos mit Visual Studio 2015 und höher kompilieren.
KeeFarce Reborn enthält keinen Injector, um die DLL in den KeePass-Prozess zu laden. Das ist beabsichtigt, da Injectoren alle paar Monate veralten – du musst also deinen eigenen verwenden. Die folgenden Abschnitte zeigen zwei typische Möglichkeiten, eine Injektion durchzuführen.
Voraussetzung: Schreibzugriff auf das KeePass-Plugin-Verzeichnis.
KeePass verfügt über ein Plugin-Framework, um Benutzern zusätzliche Funktionen bereitzustellen. Es funktioniert, indem eine DLL in den KeePass-Prozess geladen wird, was Plugin-Entwicklern ermöglicht, Aktionen innerhalb der KeePass-Anwendungsdomäne auszuführen.
Folglich können wir diese Funktionalität missbrauchen, um KeeFarce Reborn als Plugin zu laden, ohne überhaupt einen externen Injector verwenden zu müssen! Du musst nur das Projekt KeeFarceRebornPlugin kompilieren und die DLL in das Plugin-Verzeichnis kopieren (das sich im KeePass-Wurzelverzeichnis befindet, nämlich "C:\Program Files\KeePass Password Safe 2\Plugins" bei einer globalen Installation).
Damit das Projekt korrekt erstellt wird, musst du die jeweilige KeePass.exe-Assemblyversion in das Verzeichnis KeeFarceRebornPlugin kopieren oder die PLGX verwenden, wenn das resultierende Plugin mit jeder KeePass-Version kompatibel sein soll.
Beim nächsten Start von KeePass und dem Entsperren einer Datenbank wird die DLL geladen und die Injektion durchgeführt. Wenn KeePass bereits läuft, musst du auf den nächsten Neustart warten, damit die Injektion erfolgt (oder den Neustart selbst erzwingen).
⚠️ Sobald ein Plugin geladen ist, ist die DLL-Datei bis zum Schließen von KeePass schreibgeschützt. Denke daran, um sicherzustellen, dass du bei Assessments keine schädlichen Plugins hinterlässt.
Wenn du keinen Schreibzugriff auf das KeePass-Plugin-Verzeichnis hast, wirf einen Blick auf Quarkslabs Artikel, der zeigt, wie Plugins mit weniger Rechten über den Plugin-Cache geladen werden können.
Voraussetzung: KeePass läuft + eine Datenbank ist vom Benutzer entsperrt + du hast ausreichende Rechte, um in den KeePass-Prozess zu injizieren.
Da ich persönlich es einfacher finde, Shellcode unauffällig zu injizieren als eine DLL in einen entfernten Prozess, beginne ich typischerweise damit, positionsunabhängigen Shellcode aus unserer DLL zu erzeugen. Es scheint, dass das donut-Projekt von @odzhan und @TheWover perfekt unsere Bedürfnisse erfüllt!
Wir kompilieren donut von einem Commit im Dev-Branch, da dieser ein Problem in der Anwendungsdomänenverwaltung behebt, das uns daran hindern würde, Reflektion in der Standarddomäne durchzuführen.
git clone https://github.com/TheWover/donut/
cd donut
git checkout 9d781d8da571eb1499122fc0e2d6e89e5a43603c
Wir können es problemlos aus der x64 Native Tools Command Prompt von Visual Studio mit dem Dienstprogramm nmake erstellen:
nmake -f Makefile.msvc
Das Erzeugen des Shellcodes ist so einfach wie:
.\donut.exe "C:\KeeFarceReborn\KeePassReborn\bin\Release\KeeFarceReborn.dll" -c KeeFarceReborn.Program -m Main -e 1
[ Donut shellcode generator v0.9.3
[ Copyright (c) 2019 TheWover, Odzhan
[ Instance type : Embedded
[ Module file : "C:\KeeFarceReborn\KeePassReborn\bin\Release\KeeFarceReborn.dll"
[ Entropy : None
[ File type : .NET DLL
[ Class : KeeFarceReborn.Program
[ Method : Main
[ Target CPU : x86+amd64
[ AMSI/WDLP : continue
[ Shellcode : "loader.bin"
Beachte, dass
-e 1erforderlich ist, um Entropie zu deaktivieren, andernfalls befindet sich der injizierte Prozess nicht in der Standard-Anwendungsdomäne.
Komprimieren wir es mit PowerShell, um die Integration in den Code des Injectors zu erleichtern:
$bytes = [System.IO.File]:https://raw.githubusercontent.com/d3lb3/keefarcereborn/HEAD/:ReadAllBytes(%22C:%5Cdonut%5Cloader.bin%22)
[System.IO.MemoryStream] $outStream = New-Object System.IO.MemoryStream
$deflateStream = New-Object System.IO.Compression.DeflateStream($outStream, [System.IO.Compression.CompressionLevel]::Optimal)
$deflateStream.Write($bytes, 0, $bytes.Length)
$deflateStream.Dispose()
$outBytes = $outStream.ToArray()
$outStream.Dispose()
$b64 = [System.Convert]::ToBase64String($outBytes)
Write-Output $b64 | clip
Du hast jetzt einen Payload, der bereit ist, mit deiner Lieblingstechnik injiziert zu werden. Wenn du nicht weißt, was du jetzt tun sollst, empfehle ich dir, die Code- und Prozessinjektions-Seite von ired.team anzusehen, um dich mit dem Konzept vertraut zu machen. Die Malware-Entwicklungskurse von @SEKTOR7 sind voller großartiger Lerninhalte, falls du sie dir leisten kannst.
Als Beispiel injizieren wir unseren Payload mit dem VeraCryptThief-Code von snovvcrash (selbst von den SEKTOR7-Kursen inspiriert), der D/Invoke verwendet. Zur Demonstration habe ich sein Projekt in den Ordner SampleInjector kopiert; wir müssen nur unseren komprimierten Shellcode einfügen und dann in x64 kompilieren.
Obwohl es aktuell (November 2022) immer noch Defender umgeht, wird es natürlich nötig sein, einen eigenen Injector zu basteln, um moderne EDRs zu umgehen. Dieser Beispiel-Injektor dient nur dazu, zu zeigen, dass alles wie erwartet funktioniert.
Indem du .\SampleInjector.exe bei einer geöffneten KeePass-Datenbank ausführst, wird die DLL geladen und die Injektion durchgeführt.
Sobald die Injektion durchgeführt ist, siehst du Debug-Meldungen, die in MessageBox ausgegeben werden (die offensichtlich entfernt werden sollten, wenn sie in einem echten Penetrationstest-Szenario verwendet werden). Anschließend findest du die exportierte Datenbank im %APPDATA%-Verzeichnis des aktuellen Benutzers (standardmäßig gewählt, da KeePass sicherlich Schreibzugriff hat). Die exportierte XML-Datei kann später ohne Passwortabfrage in jede KeePass-Datenbank importiert werden.
Wenn Plugin- oder Exportfunktionen durch die Richtlinie deaktiviert sind, können sie dennoch aktiviert werden, indem du die KeePass.config.xml bearbeitest, sofern du Schreibzugriff hast:
<Policy>
<Plugins>true</Plugins>
<Export>true</Export>
</Policy>
Während das Hauptproblem bei der Erkennung von KeePass-Extraktionstools die Injectoren sind, können auch In-Memory-Scans Alarm auslösen, wenn der Shellcode oder die Plugin-DLL analysiert wird. Möglicherweise musst du den Shellcode verschleiern und/oder verschlüsseln, um ihn mit deinem Injector zu verwenden.
Wenn Plugin-DLLs schließlich von der statischen Analyse erkannt werden, kannst du weiterhin KeePass' PLGX-Plugin-Format verwenden, um eine Erkennung zu vermeiden.
DISM.exe einrichten.Pull Requests sind willkommen. Zögere nicht, ein Issue zu eröffnen oder mir auf Twitter eine DM zu schicken, um Verbesserungen vorzuschlagen.
Code-Teile wurden aus den Projekten KeeFarce, KeeThief und KeePassHax übernommen.
Der Beispiel-Injektionsmechanismus wurde direkt aus den Projekten von snovvcrash übernommen.