macOS .Net Applications Injection
Dies ist eine Zusammenfassung des Beitrags https://blog.xpnsec.com/macos-injection-via-third-party-frameworks/. Überprüfen Sie ihn für weitere Details!
.NET Core Debugging
Einrichten einer Debugging-Sitzung
Die Kommunikation zwischen Debugger und Debuggee in .NET wird von dbgtransportsession.cpp verwaltet. Dieses Komponente richtet pro .NET-Prozess zwei benannte Pipes ein, wie in dbgtransportsession.cpp#L127 zu sehen ist, die über twowaypipe.cpp#L27 initiiert werden. Diese Pipes sind mit -in
und -out
suffixiert.
Wenn man das Verzeichnis $TMPDIR
des Benutzers besucht, findet man Debugging-FIFOs, die für das Debuggen von .Net-Anwendungen verfügbar sind.
DbgTransportSession::TransportWorker ist für die Verwaltung der Kommunikation von einem Debugger verantwortlich. Um eine neue Debugging-Sitzung zu starten, muss ein Debugger eine Nachricht über die out
-Pipe senden, die mit einer MessageHeader
-Struktur beginnt, die im .NET-Quellcode detailliert beschrieben ist:
Um eine neue Sitzung anzufordern, wird diese Struktur wie folgt ausgefüllt, wobei der Nachrichtentyp auf MT_SessionRequest
und die Protokollversion auf die aktuelle Version gesetzt wird:
Dieser Header wird dann über das write
-Syscall an das Ziel gesendet, gefolgt von der sessionRequestData
-Struktur, die eine GUID für die Sitzung enthält:
Eine Leseoperation auf der out
-Pipe bestätigt den Erfolg oder Misserfolg des Debugging-Sitzungsaufbaus:
Lesen des Speichers
Sobald eine Debugging-Sitzung hergestellt ist, kann der Speicher mithilfe des MT_ReadMemory
-Nachrichtentyps gelesen werden. Die Funktion readMemory
ist detailliert beschrieben und führt die erforderlichen Schritte aus, um eine Leseanfrage zu senden und die Antwort abzurufen:
Der vollständige Proof of Concept (POC) ist hier verfügbar.
Schreiben von Speicher
Ebenso kann Speicher mithilfe der Funktion writeMemory
geschrieben werden. Der Prozess besteht darin, den Nachrichtentyp auf MT_WriteMemory
festzulegen, die Adresse und Länge der Daten anzugeben und dann die Daten zu senden:
Der dazugehörige POC ist hier verfügbar.
Ausführung von .NET Core-Code
Um Code auszuführen, muss man einen Speicherbereich mit rwx-Berechtigungen identifizieren, was mit vmmap -pages durchgeführt werden kann:
Um eine Stelle zum Überschreiben eines Funktionszeigers zu finden, ist es notwendig, das Dynamic Function Table (DFT) in .NET Core anzuzielen. Diese Tabelle, die in jithelpers.h
detailliert beschrieben ist, wird vom Laufzeitsystem für JIT-Kompilierungshilfsfunktionen verwendet.
Für x64-Systeme kann die Signatursuche verwendet werden, um eine Referenz auf das Symbol _hlpDynamicFuncTable
in libcorclr.dll
zu finden.
Die Debugger-Funktion MT_GetDCB
liefert nützliche Informationen, einschließlich der Adresse einer Hilfsfunktion, m_helperRemoteStartAddr
, die den Speicherort von libcorclr.dll
im Prozessspeicher angibt. Diese Adresse wird dann verwendet, um nach dem DFT zu suchen und einen Funktionszeiger mit der Adresse des Shellcodes zu überschreiben.
Der vollständige POC-Code für die Injektion in PowerShell ist hier verfügbar.
Referenzen
Last updated