
Projet de recherche rétro-ingénierie des interfaces COM du Centre de sécurité Windows pour tracer l'enregistrement des antivirus via ATL, vtable, WSCAPI et RPC, avec vérification à l'exécution via WMI.
OWN-Defender est un projet de recherche sur la sécurité Windows axé sur la compréhension de la manière dont le Centre de sécurité Windows (WSC) représente et gère les produits de sécurité antivirus via ses interfaces COM.
Le projet a débuté comme une investigation sur le comportement démontré par DefendNot, mais plutôt que de traiter l'implémentation existante comme une boîte noire, je l'ai utilisée comme point de départ pour une rétro-ingénierie indépendante et une vérification.
L'objectif de ce projet est de comprendre le chemin d'exécution complet :
COM
↓
CLSID / IID
↓
CoCreateInstance
↓
QueryInterface
↓
ATL Interface Map
↓
vtable
↓
IWscAVStatus4
↓
CWscIsv
↓
WSCAPI.dll
↓
RPC
↓
Centre de sécurité Windows
Le projet a été développé et testé dans un environnement de recherche Windows contrôlé.
Usage exclusivement destiné à la recherche / à l'éducation
Ce projet est destiné à la recherche sur les internals Windows, à la rétro-ingénierie, à l'éducation en sécurité et aux tests de sécurité autorisés. Ne l'utilisez pas pour interférer avec des logiciels de sécurité sur des systèmes que vous ne possédez pas ou pour lesquels vous n'avez pas d'autorisation explicite de test.
La question initiale était simple :
Comment le Centre de sécurité Windows sait-il qu'un produit antivirus existe ?
Au lieu de m'arrêter à la documentation publique de l'API, je voulais comprendre ce qui se passe sous l'API.
Cela a conduit à plusieurs questions :
QueryInterface() résout-il l'interface ?__int64 a1 pour une méthode ?Register() est réellement la fonction d'enregistrement AV ?La première étape consistait à identifier la classe COM du Centre de sécurité Windows.
Le projet utilise la classe COM WSC :
CLSID_WscIsv
F2102C37-90C3-450C-B3F6-92BE1693BDF2
L'implémentation contient également une logique permettant de localiser dynamiquement le CLSID dans le registre Windows au lieu de se fier exclusivement à une valeur codée en dur.
Conceptuellement :
HKLM
└── SOFTWARE
└── Classes
└── CLSID
└── {CLSID}
└── API ISV du Centre de sécurité Windows
Cela a fourni la première relation importante :
Registre
↓
CLSID
↓
API ISV du Centre de sécurité Windows
Le défi suivant consistait à déterminer quelle interface COM devait être demandée.
Le projet utilise :
IWscAVStatus4
avec :
4DCBAFAC-29BA-46B1-80FC-B8BDE3C0AE4D
L'une des leçons importantes de la recherche était :
Un nom de GUID seul ne constitue pas une preuve suffisante.
J'ai vérifié la relation par rétro-ingénierie plutôt qu'en supposant que le nom de l'interface et le GUID étaient corrects.
L'investigation comprenait :
QueryInterface_ATL_INTMAP_ENTRYQueryInterfaceL'une des étapes de rétro-ingénierie les plus utiles a été de suivre l'implémentation de :
CComAggObject<CWscIsv>::QueryInterface()
qui atteint finalement :
ATL::CComObjectRootBase::InternalQueryInterface()
La table des interfaces ATL est utilisée pour comparer l'IID demandé aux entrées d'interface enregistrées.
Conceptuellement :
IID demandé
↓
QueryInterface()
↓
InternalQueryInterface()
↓
Table des interfaces ATL
↓
Comparaison GUID
↓
Interface correspondante
↓
Pointeur d'interface
Cela a fourni une preuve indépendante que le GUID étudié correspondait effectivement à l'interface COM attendue.
Register()L'un des plus grands défis de rétro-ingénierie a été de comprendre pourquoi IDA/Ghidra n'affichait pas toujours la signature de méthode que j'attendais.
L'interface reconstruite contient :
virtual HRESULT __stdcall Register(
BSTR path,
BSTR name,
unsigned int,
unsigned int
) = 0;
Cependant, le décompilateur pouvait afficher une implémentation telle que :
_IWscAVStatus4<CWscIsv>::Register(__int64 a1)
Au premier abord, cela semblait incohérent.
Des investigations plus poussées ont montré que la représentation du décompilateur décrivait un wrapper/thunk et l'appel vtable indirect sous-jacent plutôt que de présenter la signature d'interface logique complète.
C'est devenu une leçon importante :
La sortie d'un décompilateur est une interprétation du code machine, pas la vérité au niveau du code source original.
Pour résoudre ces divergences, j'ai comparé :
Définition de l'interface COM
↓
Disposition de la vtable
↓
Assembleur
↓
wrapper/thunk
↓
Convention d'appel
↓
Fonction cible réelle
Register()Une autre source de confusion était la présence de plusieurs fonctions portant des noms tels que :
IWscAVStatus2::Register
IWscAVStatus4::Register
IWscFWStatus2::Register
RegisterAV
La prise de conscience importante était que des noms similaires ne signifient pas des interfaces identiques.
Par exemple :
AV
↓
IWscAVStatus4
↓
Enregistrement AV
tandis que :
Pare-feu
↓
IWscFWStatus2
↓
Enregistrement du pare-feu
Le numéro d'interface et l'implémentation environnante devaient être vérifiés au lieu de sélectionner une fonction simplement parce que son nom contenait Register.
C'était l'une des parties les plus utiles de la recherche car elle m'a obligé à corréler :
Interface
+
IID
+
vtable
+
implémentation
+
disposition des paramètres
+
cible d'appel
Après avoir identifié la bonne interface, j'ai tracé l'opération d'enregistrement plus profondément dans le binaire.
Le chemin observé était approximativement :
IWscAVStatus4::Register()
↓
CWscIsv
↓
RegisterSecurityProductFunction
↓
wscRegisterSecurityProduct()
↓
WSCAPI.dll
↓
s_wscRegisterSecurityProduct()
↓
NdrClientCall3()
↓
RPC
↓
Centre de sécurité Windows
C'était particulièrement important car la méthode COM elle-même n'était pas l'opération finale.
L'appel franchissait finalement une frontière RPC.
Cela a changé ma façon de voir l'architecture :
COM
≠
implémentation finale
Au lieu de cela :
COM
↓
implémentation locale
↓
API WSC
↓
client RPC
↓
composant Windows
WSCAPI.dllLa couche suivante était WSCAPI.dll.
Le chemin rétro-ingénié atteignait :
wscRegisterSecurityProduct()
qui invoquait finalement :
s_wscRegisterSecurityProduct()
puis :
NdrClientCall3()
C'était le point où l'investigation passait d'un appel COM normal à l'infrastructure RPC Windows.