
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
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:
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:
Moderate/35 | Gate:35 [ncacn_np:41, MultiEndpointBonus:15, HasBouncer:-46, BouncerIsNotCaching:25] | Surface:100 [HasBogusStruct:1x(opnums 5):[in]:61, HasCallerSizedBuffer:5x(opnums 0,6,11):[in]:49, InPtrs:6:18, Count:12:6 -> raw:134 [capped to 100] * 1.0 -> 100] | (35 * 100) / 100 = 35 [Provisional]
Lesen Sie ihn von links nach rechts:
Moderate/35: Stufe und zusammengesetzter Score.
Gate:35 [...]: die Erreichbarkeitsachse. Sie startet von der Transportbasis (ncacn_np:41, eine Named Pipe) und listet dann jeden Registrierungsmodifikator mit seinem vorzeichenbehafteten Beitrag auf: MultiEndpointBonus:15 (auf mehreren Transporten registriert), HasBouncer:-46 (ein Sicherheits-Callback ist vorhanden, was die Erreichbarkeit senkt) und BouncerIsNotCaching:+25. Summiert und dann auf [5,100] begrenzt -> 35.
Surface:100 [...]: die Gefahrenachse. Jedes ausgelöste Signal ist Name:count x(opnums):direction:weight, z. B. HasBogusStruct wurde bei 1 Parameter ausgelöst (opnums 5) und sein Gewicht ist 61. Dann folgt ein zahlenbasierter Beitrag: InPtrs:6:18 = 6 aufruferkontrollierte In-Zeiger mit +18, Count:12:6 = 12 Methoden ergaben +6. Das ist die Summe vor der Begrenzung, , ist der Konfidenzmultiplikator (sinkt auf 0,5, wenn Signaturen unsicher sind); endgültige Surface .
Ein zweites Beispiel, das die Begrenzung und den Niedrigkonfidenz-Abschlag zeigt:
Low/3 | Gate:5 [Dynamic / epmapper:29, LocalCallOnly:-100, SecureOnly:-65, HasBouncer:-46, BouncerIsNotCaching:25] | Surface:50 [... -> raw:140 [capped to 100] * 0.5 -> 50] | (5 * 50) / 100 = 3
LocalCallOnly:-100 allein treibt das Gate unter null, sodass es auf das Minimum von 5 begrenzt wird; die Signaturen waren unsicher, daher wird Surface halbiert (* 0.5); das Composite landet bei 3. Gefährlicher Eingaberaum, aber praktisch unerreichbar -> korrekt herabgestuft.
Kritisch >= 75, Hoch >= 50, Mittel >= 25, Niedrig andernfalls (eine Schnittstelle ohne rekonstruierte Oberfläche ist unabhängig vom Gate Niedrig). Die Schwellenwerte liegen auf dem Composite; das dahinterstehende Modell befindet sich in docs/Surface_Scoring_Methadology.md.
Alle drei Gewichtstabellen (Transportbasen, Gate-Modifikatoren, Oberflächensignale) werden mit dem Analytischen Hierarchieprozess abgeleitet; paarweise Vergleiche, geometrische Mittelgewichte und ein gemessenes Konsistenzverhältnis. Die vollständige Herleitung, Matrizen, Konsistenzzahlen und die handschriftlich ausgearbeiteten Notizen finden Sie in docs/Surface_Scoring_Methadology.md.
Damit die Extraktion nicht nur sich selbst bestätigt, wurden die von diesem Tool rekonstruierten Schnittstellen gegen einen unabhängigen, etablierten RPC-IDL-Extraktor (den RpcServer-Parser in James Forshaws NtObjectManager) geprüft, der auf denselben Binärdateien ausgeführt wurde. Referenz-Dumps für lsass, samsrv und winlogon befinden sich in validation/, und der vollständige Durchlauf in validation/VALIDATION.md. Vergleichen Sie eine beliebige davon mit der passenden Binärdatei in output/FullBatchRun.json: Die Schnittstellen-UUIDs, Methoden-/Opnum-Anzahlen und Parameterrichtungen stimmen überein (z. B. zeigt winlogons 12E65DD8-...-Schnittstelle in beiden fünf Methoden, Proc0-Proc4). Das Referenzwerkzeug stoppt bei der Rekonstruktion der IDL; dieses Tool nimmt dieselbe rekonstruierte Oberfläche und fügt die Erreichbarkeit-x-Gefahr-Bewertung hinzu. Keine Verbindung zu diesem Projekt; es wird ausschließlich als unabhängige Grundwahrheitsprüfung verwendet.
Nur statisch. Nichts wird ausgeführt. Erreichbarkeit wird aus der Registrierung abgeleitet, nicht zur Laufzeit.
Needs-Review-Scores sind vorläufig, bis die Methodenanzahl in Augenschein genommen wurde.
Dieses Tool ist Teil meiner laufenden Forschung zu ALPC/RPC und Windows-Interna. Ich werde in naher Zukunft weitere Erkenntnisse veröffentlichen und Begleitwerkzeuge herausbringen. Wenn Sie das nützlich fanden, erwägen Sie, mir auf GitHub oder über meine Social-Media-Kanäle unten zu folgen, um über zukünftige Veröffentlichungen benachrichtigt zu werden.
Ein statisches Triage-/Mapping-Werkzeug für Schwachstellenforschung an Systemen, die Ihnen gehören. Es berichtet Angriffs_oberfläche_, nicht Schwachstellen. Alles, was Sie anschließend in den hervorgehobenen Schnittstellen finden, sollte vor der Veröffentlichung von Details durch koordinierte Offenlegung (MSRC) gehen.
MIT
| 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) |
| 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 |
raw:134[capped to 100]* 1.0(35 * 100) / 100 = 35 [Provisional]: Composite = Gate x Surface / 100. Erreichbarkeit und Gefahr werden multipliziert, nicht gemittelt, denn Gefahr zählt nur, wenn man sie erreichen kann: Eine maximal gefährliche Schnittstelle, die man nicht berühren kann, darf nicht nach oben schwimmen. Das [Provisional]-Flag am Ende warnt davor, dass der dynamische Speicherdurchlauf die gespeicherte Methodenanzahl leicht abweichend ermittelt hat, sodass ein Mensch die Grenzen verifizieren sollte.