
Forschungsprojekt zum Reverse-Engineering der COM-Schnittstellen des Windows Security Centers, um die AV-Registrierung über ATL, vtable, WSCAPI und RPC nachzuverfolgen, mit Laufzeitverifizierung über WMI.
OWN-Defender ist ein Windows-Sicherheitsforschungsprojekt, das sich darauf konzentriert zu verstehen, wie das Windows Security Center (WSC) Antiviren-Sicherheitsprodukte über seine COM-Schnittstellen darstellt und verwaltet.
Das Projekt begann als Untersuchung des Verhaltens, das von DefendNot demonstriert wurde, aber anstatt die vorhandene Implementierung als Blackbox zu behandeln, habe ich sie als Ausgangspunkt für unabhängiges Reverse Engineering und Verifikation genutzt.
Das Ziel dieses Projekts ist es, den vollständigen Ausführungspfad zu verstehen:
COM
↓
CLSID / IID
↓
CoCreateInstance
↓
QueryInterface
↓
ATL Interface Map
↓
vtable
↓
IWscAVStatus4
↓
CWscIsv
↓
WSCAPI.dll
↓
RPC
↓
Windows Security Center
Das Projekt wurde in einer kontrollierten Windows-Forschungsumgebung entwickelt und getestet.
Nur für Forschungs-/Bildungszwecke
Dieses Projekt ist für Windows-Interna-Forschung, Reverse Engineering, Sicherheitsbildung und autorisierte Sicherheitstests gedacht. Verwenden Sie es nicht, um Sicherheitssoftware auf Systemen zu beeinträchtigen, die Sie nicht besitzen oder für die Sie keine ausdrückliche Testberechtigung haben.
Die anfängliche Frage war einfach:
Woher weiß das Windows Security Center, dass ein Antivirenprodukt existiert?
Anstatt bei der öffentlichen API-Dokumentation stehen zu bleiben, wollte ich verstehen, was unterhalb der API geschieht.
Dies führte zu mehreren Fragen:
QueryInterface() die Schnittstelle auf?__int64 a1 für eine Methode?Register()-Funktion ist tatsächlich die AV-Registrierungsfunktion?Der erste Schritt war die Identifizierung der COM-Klasse des Windows Security Center.
Das Projekt verwendet die WSC-COM-Klasse:
CLSID_WscIsv
F2102C37-90C3-450C-B3F6-92BE1693BDF2
Die Implementierung enthält außerdem Logik, um die CLSID dynamisch aus der Windows-Registrierung zu ermitteln, anstatt sich ausschließlich auf einen hartcodierten Wert zu verlassen.
Konzeptionell:
HKLM
└── SOFTWARE
└── Classes
└── CLSID
└── {CLSID}
└── Windows Security Center ISV API
Dies lieferte die erste wichtige Beziehung:
Registry
↓
CLSID
↓
Windows Security Center ISV API
Die nächste Herausforderung bestand darin, zu bestimmen, welche COM-Schnittstelle angefordert werden sollte.
Das Projekt verwendet:
IWscAVStatus4
mit:
4DCBAFAC-29BA-46B1-80FC-B8BDE3C0AE4D
Eine der wichtigen Lektionen aus der Forschung war:
Ein GUID-Name allein ist kein ausreichender Beweis.
Ich habe die Beziehung durch Reverse Engineering verifiziert, anstatt anzunehmen, dass Schnittstellenname und GUID korrekt sind.
Die Untersuchung umfasste:
QueryInterface_ATL_INTMAP_ENTRYQueryInterfaceEiner der nützlichsten Reversing-Schritte war das Verfolgen der Implementierung von:
CComAggObject<CWscIsv>::QueryInterface()
die schließlich erreicht:
ATL::CComObjectRootBase::InternalQueryInterface()
Die ATL-Interface-Map wird verwendet, um die angeforderte IID mit registrierten Schnittstelleneinträgen zu vergleichen.
Konzeptionell:
Angeforderte IID
↓
QueryInterface()
↓
InternalQueryInterface()
↓
ATL Interface Map
↓
GUID-Vergleich
↓
Übereinstimmende Schnittstelle
↓
Schnittstellenzeiger
Dies lieferte unabhängige Beweise dafür, dass die untersuchte GUID tatsächlich der erwarteten COM-Schnittstelle entsprach.
Register()-VerwirrungEine der größten Reversing-Herausforderungen war das Verständnis, warum IDA/Ghidra nicht immer die von mir erwartete Methodensignatur anzeigte.
Die rekonstruierte Schnittstelle enthält:
virtual HRESULT __stdcall Register(
BSTR path,
BSTR name,
unsigned int,
unsigned int
) = 0;
Der Dekompiler konnte jedoch eine Implementierung wie folgt anzeigen:
_IWscAVStatus4<CWscIsv>::Register(__int64 a1)
Zunächst sah dies inkonsistent aus.
Weitere Untersuchungen zeigten, dass die Dekompiler-Darstellung einen Wrapper/Thunk und den zugrunde liegenden indirekten vtable-Aufruf beschrieb, anstatt die vollständige logische Schnittstellensignatur darzustellen.
Dies wurde zu einer wichtigen Lektion:
Die Dekompiler-Ausgabe ist eine Interpretation von Maschinencode, nicht die ursprüngliche Wahrheit auf Quellcode-Ebene.
Um diese Diskrepanzen aufzulösen, habe ich verglichen:
COM-Schnittstellendefinition
↓
vtable-Layout
↓
Assembly
↓
Wrapper/Thunk
↓
Aufrufkonvention
↓
Tatsächliche Zielfunktion
Register()-FunktionenEine weitere Quelle der Verwirrung war das Vorhandensein mehrerer Funktionen mit Namen wie:
IWscAVStatus2::Register
IWscAVStatus4::Register
IWscFWStatus2::Register
RegisterAV
Die wichtige Erkenntnis war, dass ähnliche Namen nicht identische Schnittstellen bedeuten.
Zum Beispiel:
AV
↓
IWscAVStatus4
↓
AV-Registrierung
während:
Firewall
↓
IWscFWStatus2
↓
Firewall-Registrierung
Die Schnittstellennummer und die umgebende Implementierung mussten verifiziert werden, anstatt eine Funktion nur deshalb auszuwählen, weil ihr Name Register enthielt.
Dies war einer der nützlichsten Teile der Forschung, weil es mich zwang, zu korrelieren:
Schnittstelle
+
IID
+
vtable
+
Implementierung
+
Parameterlayout
+
Aufrufziel
Nach der Identifizierung der korrekten Schnittstelle verfolgte ich die Registrierungsoperation tiefer in die Binärdatei.
Der beobachtete Pfad war ungefähr:
IWscAVStatus4::Register()
↓
CWscIsv
↓
RegisterSecurityProductFunction
↓
wscRegisterSecurityProduct()
↓
WSCAPI.dll
↓
s_wscRegisterSecurityProduct()
↓
NdrClientCall3()
↓
RPC
↓
Windows Security Center
Dies war besonders wichtig, weil die COM-Methode selbst nicht die endgültige Operation war.
Der Aufruf überschritt schließlich eine RPC-Grenze.
Das veränderte meine Sichtweise auf die Architektur:
COM
≠
endgültige Implementierung
Stattdessen:
COM
↓
lokale Implementierung
↓
WSC API
↓
RPC-Client
↓
Windows-Komponente
WSCAPI.dllDie nächste Ebene war WSCAPI.dll.
Der reverse-engineerte Pfad erreichte:
wscRegisterSecurityProduct()
die schließlich aufrief:
s_wscRegisterSecurityProduct()
und dann:
NdrClientCall3()
Dies war der Punkt, an dem sich die Untersuchung von einem normalen COM-Aufruf in die Windows-RPC-Infrastruktur verlagerte.
Das Verständnis dieser Ebene half zu erklären, warum das Verhalten nicht vollständig verstanden werden konnte, wenn man nur die ursprüngliche COM-DLL betrachtete.
Statische Analyse war nur ein Teil der Forschung.
Nach der Rekonstruktion der relevanten Schnittstelle und des Aufrufpfads erstellte ich meine eigene kontrollierte Implementierung und verglich das resultierende Verhalten mit dem Windows Security Center.
Ich verwendete Windows Security Center / WMI-Informationen wie:
ROOT\SecurityCenter2
AntiVirusProduct
um die registrierten Produktinformationen unabhängig zu beobachten.
Der Verifikationsprozess war:
Reverse Engineering
↓
Schnittstellenrekonstruktion
↓
Eigene Implementierung
↓
Laufzeitausführung
↓
Windows Security Center
↓
WMI-Beobachtung
↓
Ergebnisvergleich
Dies ermöglichte mir zu verifizieren, dass die Schlussfolgerungen aus der statischen Analyse mit dem beobachtbaren Windows-Verhalten übereinstimmten.
Dieses Projekt hat mir erheblich mehr beigebracht, als nur mit einer COM-Schnittstelle zu interagieren.
CoCreateInstanceQueryInterfaceWSCAPI.dllNdrClientCall3Am wichtigsten war, dass ich gelernt habe, mich nicht auf eine einzelne Beweisquelle zu verlassen.
Stattdessen:
Symbol
↓
Dekompiler
↓
Assembly
↓
GUID
↓
Interface Map
↓
vtable
↓
Call Graph
↓
RPC
↓
Laufzeitverifikation
Jede Ebene erhöht das Vertrauen in die Schlussfolgerung.
Die Forschungsimplementierung besteht aus zwei Hauptkomponenten.
OWN-Defender
│
├── OWN-Defender.cpp
│ ├── WSC-COM-Interaktion
│ ├── CLSID-Ermittlung
│ ├── COM-Initialisierung
│ ├── IWscAVStatus4-Interaktion
│ ├── Registrierung
│ ├── Statusaktualisierung
│ └── Bereinigung
│
└── dllmain.cpp
├── DLL-Einstiegspunkt
├── Forschungs-Loader
├── kontrollierte Ausführung
└── Bereinigungs-/Stoppbehandlung
Das Repository ist bewusst klein gehalten, damit die Beziehung zwischen dem reverse-engineerten Verhalten und der Implementierung leicht nachvollziehbar bleibt.
Dieses Projekt wurde um Fragen herum aufgebaut, anstatt einfach Funktionalität zu reproduzieren:
Wie identifiziert WSC die COM-Klasse?
Wie wird die IID auf die Schnittstelle abgebildet?
Wie findet QueryInterface die Schnittstelle?
Warum zeigt IDA unterschiedliche Funktionssignaturen?
Wo ist die tatsächliche vtable?
Welche Register() ist die AV-Implementierung?
Was passiert nach der COM-Methode?
Wo tritt WSCAPI.dll in die Aufrufkette ein?
Wo beginnt RPC?
Wie kann das Ergebnis unabhängig verifiziert werden?
Diese Fragen waren letztendlich wertvoller als die endgültige Implementierung selbst.
Das Projekt bietet auch einen nützlichen Ausgangspunkt für die Untersuchung der Sicherheitsgrenze zwischen:
Anwendung
↓
COM
↓
Windows Security Center
↓
Sicherheitsanbieter-Informationen
Eine wichtige Unterscheidung ist, dass das Registrieren von Sicherheitsproduktinformationen nicht automatisch gleichbedeutend ist mit dem Deaktivieren der Defender-Engine oder dem Umgehen ihrer Schutzmechanismen.
Daher sollte dieses Projekt in erster Linie betrachtet werden als:
Windows Security Center / COM-Reverse-Engineering-Forschung
und nicht als Behauptung, dass die WSC-Registrierung allein eine Defender-Schwachstelle darstellt.
Jegliche Sicherheitsauswirkung erfordert eine separate Untersuchung und Validierung.
Diese Forschung wurde teilweise durch die in DefendNot von es3n1n demonstrierte Arbeit inspiriert.
Ein besonderer Dank gilt dem Autor für die Bereitstellung eines nützlichen Ausgangspunkts zum Verständnis des WSC-Mechanismus.
Originalprojekt: https://github.com/es3n1n/defendnot
Der Zweck dieses Repositorys ist es nicht, die ursprüngliche Forschung als meine eigene auszugeben, sondern meinen eigenen Reverse-Engineering-Prozess, meine unabhängige Implementierung und die Verifikation des zugrunde liegenden Windows-Verhaltens zu dokumentieren.
Dieses Repository wird bereitgestellt für:
Verwenden Sie dieses Projekt nur auf Systemen, die Sie besitzen oder für die Sie ausdrücklich autorisiert sind, Tests durchzuführen.
Der Autor ist nicht verantwortlich für Missbrauch, Schäden, Datenverlust, Beeinträchtigung von Sicherheitskontrollen oder unbefugte Bereitstellung.
Dieses Projekt ist unter der GNU General Public License v3.0 lizenziert.
Siehe LICENSE für Details.
Das Hauptziel von OWN-Defender ist es nicht, einfach eine AV-Registrierungstechnik zu reproduzieren.
Es geht darum, eine wiederholbare Reverse-Engineering-Methodik zu demonstrieren:
Finden
↓
Abbilden
↓
Reverse
↓
Rekonstruieren
↓
Verfolgen
↓
Implementieren
↓
Verifizieren
Was mit einer Frage zum Windows Security Center begann, wurde zu einer tieferen Erkundung von COM, ATL, GUID/IID-Zuordnung, vtables, compiler-generiertem Code, WSCAPI, RPC und der Windows-Sicherheitsarchitektur.
Die Implementierung ist das Ergebnis. Der Reverse-Engineering-Prozess ist das eigentliche Projekt.