macOS MIG - Mach Interface Generator
Last updated
Last updated
Lernen Sie AWS-Hacking:HackTricks Training AWS Red Team Expert (ARTE) Lernen Sie GCP-Hacking: HackTricks Training GCP Red Team Expert (GRTE)
MIG wurde erstellt, um den Prozess der Mach IPC-Codeerstellung zu vereinfachen. Es generiert im Wesentlichen den benötigten Code, damit Server und Client gemäß einer bestimmten Definition kommunizieren können. Selbst wenn der generierte Code hässlich ist, muss ein Entwickler ihn nur importieren, und sein Code wird viel einfacher sein als zuvor.
Die Definition wird in der Interface Definition Language (IDL) unter Verwendung der Erweiterung .defs
angegeben.
Diese Definitionen haben 5 Abschnitte:
Subsystem-Deklaration: Das Schlüsselwort subsystem
wird verwendet, um den Namen und die ID anzugeben. Es ist auch möglich, es als KernelServer
zu kennzeichnen, wenn der Server im Kernel ausgeführt werden soll.
Einschlüsse und Importe: MIG verwendet den C-Präprozessor, sodass er Importe verwenden kann. Außerdem ist es möglich, uimport
und simport
für benutzer- oder servergenerierten Code zu verwenden.
Typdeklarationen: Es ist möglich, Datentypen zu definieren, obwohl normalerweise mach_types.defs
und std_types.defs
importiert werden. Für benutzerdefinierte Typen kann eine bestimmte Syntax verwendet werden:
[in/out]tran
: Funktion, die von einer eingehenden oder zu einer ausgehenden Nachricht übersetzt werden muss
c[user/server]type
: Zuordnung zu einem anderen C-Typ.
destructor
: Diese Funktion aufrufen, wenn der Typ freigegeben wird.
Operationen: Dies sind die Definitionen der RPC-Methoden. Es gibt 5 verschiedene Typen:
routine
: Erwartet Antwort
simpleroutine
: Erwartet keine Antwort
procedure
: Erwartet Antwort
simpleprocedure
: Erwartet keine Antwort
function
: Erwartet Antwort
Erstellen Sie eine Definitiondatei, in diesem Fall mit einer sehr einfachen Funktion:
Beachten Sie, dass das erste Argument der Port ist, an den gebunden wird und MIG wird automatisch den Antwortport verwalten (es sei denn, mig_get_reply_port()
im Clientcode aufgerufen wird). Darüber hinaus werden die IDs der Operationen sequenziell sein, beginnend mit der angegebenen Subsystem-ID (sofern eine Operation veraltet ist, wird sie gelöscht und skip
wird verwendet, um ihre ID weiterhin zu verwenden).
Verwenden Sie nun MIG, um den Server- und Clientcode zu generieren, die in der Lage sein werden, miteinander zu kommunizieren, um die Subtract-Funktion aufzurufen:
Es werden mehrere neue Dateien im aktuellen Verzeichnis erstellt.
Ein komplexeres Beispiel finden Sie in Ihrem System mit: mdfind mach_port.defs
Und Sie können es aus dem gleichen Ordner wie die Datei kompilieren mit: mig -DLIBSYSCALL_INTERFACE mach_ports.defs
In den Dateien myipcServer.c
und myipcServer.h
finden Sie die Deklaration und Definition der Struktur SERVERPREFmyipc_subsystem
, die im Wesentlichen die Funktion definiert, die basierend auf der empfangenen Nachrichten-ID aufgerufen werden soll (wir haben eine Startnummer von 500 angegeben):
macOS MIG - Mach Interface Generator
Mach Interface Generator (MIG) is a tool used to define inter-process communication on macOS systems. It generates client and server-side code for message-based communication between processes. By defining interfaces in a .defs file, MIG creates the necessary code to handle messages, simplifying the development of IPC mechanisms.
MIG interfaces are defined using a domain-specific language that specifies the messages and data structures exchanged between processes. This language allows developers to define complex data structures and message formats, enabling efficient communication between processes.
When working with MIG, it is essential to understand the generated code's structure and how messages are handled between client and server components. By analyzing the MIG-generated code, security researchers can identify potential vulnerabilities related to inter-process communication and privilege escalation on macOS systems.
Example:
In this example, myipc_server
is a function generated by MIG that handles incoming messages from clients. Security analysis of this function can reveal insights into how inter-process communication is implemented and potential security weaknesses that could be exploited by attackers.
By understanding how M message-based communication is defined and implemented using MIG, security researchers can assess the security posture of macOS systems and develop appropriate countermeasures to protect against privilege escalation and unauthorized access through IPC mechanisms.
Basierend auf der vorherigen Struktur wird die Funktion myipc_server_routine
die Nachrichten-ID erhalten und die entsprechende Funktion zurückgeben, die aufgerufen werden soll:
In diesem Beispiel haben wir nur 1 Funktion in den Definitionen definiert, aber wenn wir mehr Funktionen definiert hätten, wären sie innerhalb des Arrays von SERVERPREFmyipc_subsystem
und die erste wäre der ID 500 zugewiesen worden, die zweite der ID 501...
Wenn erwartet wurde, dass die Funktion eine Antwort sendet, würde auch die Funktion mig_internal kern_return_t __MIG_check__Reply__<name>
existieren.
Tatsächlich ist es möglich, diese Beziehung in der Struktur subsystem_to_name_map_myipc
aus myipcServer.h
(subsystem_to_name_map_***
in anderen Dateien) zu identifizieren:
Schließlich wird eine weitere wichtige Funktion zur Funktionsweise des Servers myipc_server
sein, die tatsächlich die mit der empfangenen ID verbundene Funktion aufruft:
Überprüfen Sie die zuvor hervorgehobenen Zeilen, die auf die Funktion zugreifen, die anhand der ID aufgerufen werden soll.
Der folgende Code erstellt einen einfachen Server und Client, bei dem der Client die Funktionen vom Server abrufen kann:
macOS MIG - Mach Interface Generator
Mach Interface Generator (MIG) is a tool used to define inter-process communication (IPC) for macOS. It generates client-side and server-side code for message-based IPC. By using MIG, developers can define the messages that can be sent between processes and automatically generate the code needed to send and receive these messages.
MIG simplifies the process of IPC by abstracting the details of message passing and allowing developers to focus on defining the message formats and handling the messages. This makes it easier to implement secure and efficient communication between processes in macOS.
To use MIG for IPC in macOS, developers need to define an interface definition file that specifies the messages and data structures used for communication. This file is then processed by MIG to generate the necessary code for IPC. By following the MIG conventions and guidelines, developers can ensure that their IPC implementation is robust and follows best practices for macOS development.
Overall, MIG is a powerful tool for defining and implementing IPC in macOS, making it easier for developers to create secure and efficient inter-process communication in their applications.
Der NDR_record wird von libsystem_kernel.dylib
exportiert und ist eine Struktur, die es MIG ermöglicht, Daten so zu transformieren, dass sie unabhängig vom System sind, auf dem sie verwendet werden, da MIG dafür gedacht war, zwischen verschiedenen Systemen verwendet zu werden (und nicht nur auf derselben Maschine).
Dies ist interessant, weil wenn _NDR_record
als Abhängigkeit in einem Binärfile gefunden wird (jtool2 -S <binary> | grep NDR
oder nm
), bedeutet dies, dass das Binärfile ein MIG-Client oder -Server ist.
Darüber hinaus haben MIG-Server die Dispatch-Tabelle in __DATA.__const
(oder in __CONST.__constdata
im macOS-Kernel und __DATA_CONST.__const
in anderen *OS-Kerneln). Dies kann mit jtool2
ausgelesen werden.
Und MIG-Clients verwenden den __NDR_record
, um Nachrichten mit __mach_msg
an die Server zu senden.
Da viele Binärdateien jetzt MIG verwenden, um Mach-Ports freizulegen, ist es interessant zu wissen, wie man identifiziert, dass MIG verwendet wurde und die Funktionen, die MIG mit jeder Nachrichten-ID ausführt.
jtool2 kann MIG-Informationen aus einer Mach-O-Binärdatei analysieren, indem es die Nachrichten-ID angibt und die auszuführende Funktion identifiziert:
Darüber hinaus sind MIG-Funktionen nur Wrapper der tatsächlichen aufgerufenen Funktion, was bedeutet, dass Sie durch Disassemblierung und Grepping nach BL möglicherweise die tatsächliche aufgerufene Funktion finden können:
Es wurde zuvor erwähnt, dass die Funktion, die sich um den Aufruf der richtigen Funktion je nach empfangener Nachrichten-ID kümmern wird, myipc_server
war. Sie haben jedoch normalerweise nicht die Symbole der Binärdatei (keine Funktionsnamen), daher ist es interessant zu überprüfen, wie sie dekompiliert aussieht, da sie immer sehr ähnlich sein wird (der Code dieser Funktion ist unabhängig von den freigegebenen Funktionen):
Tatsächlich finden Sie im Funktionsaufruf 0x100004000
das Array der routine_descriptor
-Strukturen. Das erste Element der Struktur ist die Adresse, an der die Funktion implementiert ist, und die Struktur nimmt 0x28 Bytes ein, sodass Sie alle 0x28 Bytes (beginnend ab Byte 0) 8 Bytes erhalten können, und das wird die Adresse der Funktion sein, die aufgerufen wird:
Diese Daten können mit diesem Hopper-Skript extrahiert werden.
Der von MIG generierte Code ruft auch kernel_debug
auf, um Protokolle über Operationen beim Eintritt und Austritt zu generieren. Es ist möglich, sie mit trace
oder kdv
zu überprüfen: kdv all | grep MIG