
Saubere indirekte Syscalls mit Syscall-Tampering.
SyscallRevenant ist eine neue Methode zur Durchführung sauberer indirekter Syscalls.
Die Hauptkomponente löst System Service Numbers (SSNs) und syscall-Instruktionsadressen dynamisch auf.
Dies geschieht durch Aktivieren des Trap-Flags während der Ausführung.
Die sekundäre Komponente ist Manipulation durch Parameterersetzung vor einem syscall.
Diese Kombination ist darauf ausgelegt, Userland-Hooks während des nachfolgenden Syscall-Aufrufs zu umgehen und dabei die ursprünglich übergebenen Parameter zu ersetzen.
Haftungsausschluss: Der Zweck dient ausschließlich Bildungs- und Testzwecken. Verwenden Sie dies nicht auf Maschinen, für die Sie keine Berechtigung haben. Verwenden Sie dies nicht, um Maschinen auszunutzen und mit ihnen zu kommunizieren, für die Sie keine Autorisierung haben.
Indirekte Syscalls sind eine Methode, syscall-Instruktionen im vertrauenswürdigen Userland-Speicher auszuführen.
Wenn ein Benutzer eine syscall-Instruktion findet, kann er indirekt dorthin springen.
Ein während einer Tracing-Sitzung aktiviertes Ereignis kann die Rücksprungadresse unmittelbar nach der Instruktion offenlegen.
Dies berücksichtigt keine Userland-Hooks von Endpoint Detection & Response (EDR).
Ein EDR kann Hooks in ntdll.dll einfügen und dadurch den Suchprozess für SSNs und syscall-Instruktionen entwerten.
Das Eintreten in einen Hook kommt dem besitzenden Thread zugute und erhöht nicht den Malicious-Score.
Das Beobachten eines Eintritts in eine Funktion und das Beobachten der daraus resultierenden Operation sind verschiedene Dinge.
RevenantSyscalls untersucht diese Lücke.
Die folgenden Abschnitte beschreiben die beiden Hauptkomponenten des Projekts.
Die erste Komponente löst Funktionsadressen aus der vom Prozess geladenen ntdll.dll auf.
Anschließend kann ein Trap-Walk durchgeführt werden, falls Syscall-Informationen benötigt werden.
Die zweite Komponente führt einen indirekten Sprung zu den gespeicherten Funktionsinformationen aus.
Durch Lesen aus dem Segmentregister kann der Process Environment Block (PEB) abgerufen werden.
LoaderData ist ein Feld im PEB, das mit jedem Prozess geladene Daten enthält.
LoaderData enthält Informationen über Module, die zusammen mit jedem Prozess geladen werden.
Modulnamen und Basisadressen sind in Moduleinträgen vorhanden.
Die Exportinformationen einer Dynamically Linked Library (DLL) beschreiben die von ihr exportierten Symbole. Export-Metadaten unterstützen das Auffinden exportierter Symbole. Der Index einer Funktion gilt nur für Namen und Namensordinalzahlen. Das Hashen eines Funktionsnamens ist die beste Wahl für Umgebungen mit wenig Speicher.
Ein Vectored Exception Handler ist ein Ausnahmebehandlungsmechanismus, der Ausnahmen von überall innerhalb eines Prozesses abfängt.
Das Aktivieren des Trap-Flags verursacht eine EXCEPTION_SINGLE_STEP-Ausnahme bei der nächsten ausgeführten Instruktion.
Ein benutzerdefinierter Vectored Exception Handler kann den RIP inspizieren und auf einen syscall prüfen.
Durch wiederholtes Zurücksetzen des Trap-Flags wird die syscall-Adresse entdeckt und die SSN gespeichert.
Syscall-Lookup
|
Syscall-Ausführung
|
Jeder Syscall hat den anfänglichen Syscall-Informations-Lookup; Hooks werden betreten, um Syscall-Informationen abzurufen. Anschließend wird ein indirekter Sprung zum Syscall ausgeführt. Es erfolgt ein zugehöriger RIP-Spoof (vom ursprünglichen Eintritt). Beim Wiedereintritt wurden die ursprünglichen Parameter manipuliert.
Aus der Perspektive von Event Tracing for Windows (ETW) sind die möglicherweise ausgegebenen Ereignisse: SysEnter, SysExit und StackWalk für beide.
Wenn ein EDR ähnliche, vergleichbare Ereignisse erzeugt, werden diese nahezu identisch aussehen.
Die einzigen Unterschiede liegen in drastisch unterschiedlichen Zeitstempeln des Query Performance Counter (QPC).
src/AsmRevenant.asm REAL_RTN: DQ 0
FAKE_RTN: DQ 0
; If a syscall information lookup is in progress, the
; initial entry return address needs to be preserved.
MOV RAX, QWORD PTR [RSP]
MOV QWORD PTR [FAKE_RTN], RAX
; Once the re-entry is made, the real return is saved,
; and the current is spoofed with initial return.
MOV RAX, QWORD PTR [RSP]
MOV QWORD PTR [REAL_RTN], RAX
MOV RAX, QWORD PTR [FAKE_RTN]
MOV QWORD PTR [RSP], RAX
src/Revenant.cLONG VectoredExceptionHandler(EXCEPTION_POINTERS *BreakPoint) {
...
// If a syscall information lookup is being made, the
// syscall instruction address is saved, the SSN is
// saved, and the return is rerouted.
if (LookupInProgress && *(USHORT*)BreakPoint->Address == 0x050F) {
SyscallInstruction = BreakPoint->Address;
SyscallSSN = BreakPoint->Context->Rax;
BreakPoint->Context->Rip = SyscallExit;
}
// When re-entered, if the previous instruction was
// a syscall, reset return address, and exit.
if (!LookupInProgress && *(USHORT*)(BreakPoint->Address - 2) == 0x050F) {
*(VOID**)BreakPoint->Context->Rsp = REAL_RTN;
BreakPoint->Context->Rip = SyscallExit;
}
...
}