
Eine statische Analyse-Engine ohne Symbole, die die Windows-RPC-Angriffsfläche extrahiert und mithilfe eines AHP-basierten Risikomodells mathematisch einstuft.
Statisch vs. dynamisch – bitte zuerst lesen. Es lohnt sich, die Grenze zwischen dynamischer und statischer Analyse vorab klarzustellen: Dieses Tool bewertet ausschließlich durch statische Analyse. Es liest die kompilierten MIDL-/NDR-Strukturen direkt aus der Binärdatei und führt niemals etwas aus.
Statische Triage für die Windows-RPC-Angriffsfläche. Richten Sie es auf einen Ordner mit PE-Binärdateien; es findet jede Datei, die einen RPC-Server registriert, rekonstruiert die NDR-Methodensignaturen jeder Schnittstelle, Transportbindungen und Registrierungsflags direkt aus den kompilierten MIDL-Strukturen, und bewertet anschließend jede Schnittstelle nach Erreichbarkeit x Gefahr – mit einer vollständigen, arithmetischen Beweisaufstellung zu jedem Score, sodass Sie die Mathematik von Hand nachprüfen können.
Bestehende RPC-Werkzeuge können problemlos die Methodensignaturen einer Schnittstelle und ihre Registrierungsflags wiederherstellen. Was keines von ihnen tut, ist, beides zu nehmen und die eine Frage zu beantworten, die tatsächlich darüber entscheidet, wo Sie Ihre Zeit verbringen: Angenommen, ich kann diese Schnittstelle erreichen, und angesichts dessen, was ihre Methoden als Eingabe akzeptieren – wie dringend sollte ich sie mir im Vergleich zu allem anderen auf dem System ansehen? Diese Lücke füllt dieses Tool.
Filtert den Zielordner, sodass Ghidra nur Binärdateien automatisch analysiert, die tatsächlich einen RPC-Server registrieren (sie importieren rpcrt4.dll und rufen eine der RpcServerRegisterIf\*-APIs auf). Bei System32 ist das der Unterschied zwischen einem Nachmittag und einer Woche.
Extrahiert pro Schnittstelle: UUID, die RPC_SERVER_INTERFACE- / MIDL_SERVER_INFO-Kette, die maßgebliche DispatchTableCount, Opnum + Parameterrichtungen + dekodierte NDR-Opcodes jeder Methode, die Registrierungsflags (R9), das Vorhandensein des Sicherheits-Callbacks („Bouncer"), die Sicherheitsbeschreibung (Best-Effort) sowie die Endpunkt-/Transportbindungen.
Bewertet jede saubere Schnittstelle auf zwei unabhängigen Achsen und multipliziert sie zu einem zusammengesetzten 0-100-Wert, eingeteilt in Kritisch / Hoch / Mittel / Niedrig.
Erklärt sich selbst: Jeder Score wird mit einer Beleg-Zeichenkette geliefert, die jede Komponente und die Arithmetik auflistet, die zur endgültigen Zahl geführt hat.
Zielverzeichnis --(pefile-Filter)--> nur RPC-registrierende PEs
--(Ghidra headless Auto-Analyse)--> analysierte Programm-DB
--(extract_rpc_interfaces.py-Skript)--> Schnittstellen + NDR + Flags + Endpunkte
--(Zwei-Achsen-AHP-Ranking-Engine)--> bewertete Schnittstellen + Belege
--> einzelner JSON-Bericht
Null-Symbol-Abhängigkeit: Ein entscheidendes technisches Unterscheidungsmerkmal dieser Engine ist, dass sie vollständig ohne Debug-Symbole arbeitet. Indem das Tool programmatisch die Dispatch-Tabellen durchläuft und die rohen NDR-Bytesequenzen (Network Data Representation) sowie die kompilierten MIDL-Strukturen direkt aus dem Speicher parst, umgeht es die Notwendigkeit von Microsofts .pdb-Dateien oder Live-Endpoint-Mapper-Abfragen. Dadurch funktioniert die Engine garantiert sofort mit gestrippten, produktiven System32-Binärdateien, genau so, wie sie ausgeliefert werden.
Ghidra 11.x (nutzt das mitgelieferte support/analyzeHeadless). Benötigt ein JDK 17+ im PATH.
Python 3.8+ auf der Treiberseite, mit pefile.
Das Extraktionsskript läuft unter Ghidras gebündeltem Jython 2.7 – keine Drittanbieter-Importe, nichts zu installieren.
Zielobjekte: Windows-x64-PE-Dateien. Die Analyse selbst ist betriebssystemunabhängig (Ghidra ist plattformübergreifend), Sie müssen dies also nicht unter Windows ausführen.
git clone https://github.com/talha-nazeef-ahmed/RPC-Triage
cd RPC-Triage/
python -m pip install -r requirements.txt # nur pefile
requirements.txt: pefile>=2023.2.7
Alles wird von orchestrator.py gesteuert: Es filtert, importiert, analysiert und führt den Extraktor für Sie aus.
python orchestrator.py \
-t \"C:\Windows\System32\" \
-g \"C:\ghidra_12.1.2_PUBLIC\" \
-s \".\extract_rpc_interfaces.py\" \
-o \".\out\report.json\" \
--stagedir \".\out\staged\" \
--projdir \".\out\ghidra_proj\" \
--projname RPC_Atlas
| Flag | Bedeutung |
|---|---|
-t / --target | Ordner mit zu scannenden Binärdateien |
-g / --ghidra | Ghidra-Installationsordner (derjenige, der support/analyzeHeadless enthält) |
-s / --script | Pfad zu extract_rpc_interfaces.py |
-o / --output | Pfad des zu schreibenden JSON-Berichts |
--stagedir | Ordner, in den die gefilterten RPC-Binärdateien kopiert werden (bleibt erhalten) |
--projdir | Ordner für das persistente Ghidra-Projekt |
--projname | Ghidra-Projektname (z. B. RPC_Atlas) |
Erster Lauf vs. erneuter Lauf (wichtig). Der erste Lauf erledigt den langsamen Teil: Er filtert, importiert die passenden Binärdateien, führt die vollständige Auto-Analyse aus und legt anschließend einen .analysisComplete-Marker in --projdir ab. Jeder spätere Lauf gegen dasselbe Projekt überspringt Import/Analyse (-process -noanalysis) und führt nur das Skript erneut über die bereits analysierten Programme aus. Die Analyse von System32 ist also eine einmalige Investition, und die Iteration über die Ausgabe ist günstig. Wenn die Analyse unterbrochen wird, wird der Marker nicht geschrieben; löschen Sie das Teilprojekt (.rep / .gpr) und beginnen Sie neu.
Eine JSON-Datei: eine Liste von Binärdateien, jede mit einem Interfaces-Array. Ein vollständiger Lauf über System32 ist in diesem Repository unter output/FullBatchRun.json enthalten – es ist die rohe, unredigierte Ausgabe, sodass Sie genau sehen können, was das Tool im großen Maßstab produziert. Pro Schnittstelle:
| Feld | Bedeutung |
|---|---|
CallSite | Adresse des RpcServerRegisterIf\*-Aufrufs |
Tag / TagDesc | Datenqualitäts-Eimer (siehe unten) |
Rank | \"{Tier}/{Composite}\", z. B. Critical/91 |
RankDetail | die vollständige Bewertungsaufstellung (siehe unten) |
UUID | Schnittstellen-UUID |
InterfaceAddress / DispatchAddress | rekonstruierte Strukturadressen |
FunctionsCount | maßgebliche gespeicherte Methodenanzahl; kann (FLAG: Walked X != Stored Y) tragen |
Endpoints | Transport-/Endpunktbindungen |
Security | HasBouncer, SecurityDescriptor, SecureOnly, LocalCallOnly |
Methods | Parameterliste pro Opnum mit dekodierten NDR-Opcodes |
Tags; das Datenhygiene-Gate:
Clean: sauber rekonstruiert; normal bewertet.
Needs-Review: bewertet, aber der Dispatch-Tabellen-Durchlauf hat die gespeicherte Anzahl überschritten (normalerweise ein abschließender Thunk-Block). Der Score ist real, trägt aber [Provisional]; verifizieren Sie die Methodenanzahl, bevor Sie ihn zitieren.
Diagnostics / Diagnostics (2): Die Zeile ist ein Extraktionsartefakt (ein ASCII-String, der fälschlich als UUID erkannt wurde, und/oder ein beschädigter MIDL-Zeiger). Nicht bewertet (Rank: N/A). Diese werden absichtlich behalten: Sie berichten über die Werkzeuggesundheit, sie sind keine Angriffsfläche.
Der Hinweis FLAG: Walked X != Stored Y . Die gespeicherte DispatchTableCount ist maßgeblich und wird für jeden Score verwendet. Die durchlaufene Anzahl ist eine unabhängige Ausführbarkeits-Gegenprüfung; wenn die beiden abweichen (häufig ein sauberer Faktor 2), wird die Schnittstelle als Needs-Review markiert, damit Sie sie in Augenschein nehmen. Sie ändert niemals stillschweigend einen Score.
Das ist der Teil, der einen Score vertretbar macht: