
Proyecto de investigación de ingeniería inversa de las interfaces COM de Windows Security Center para rastrear el registro de AV a través de ATL, vtable, WSCAPI y RPC, con verificación en tiempo de ejecución mediante WMI.
OWN-Defender es un proyecto de investigación de seguridad de Windows centrado en comprender cómo el Centro de seguridad de Windows (WSC) representa y gestiona los productos de seguridad antivirus a través de sus interfaces COM.
El proyecto comenzó como una investigación sobre el comportamiento demostrado por DefendNot, pero en lugar de tratar la implementación existente como una caja negra, lo utilicé como punto de partida para una ingeniería inversa independiente y su verificación.
El objetivo de este proyecto es comprender la ruta de ejecución completa:
COM
↓
CLSID / IID
↓
CoCreateInstance
↓
QueryInterface
↓
Mapa de interfaces ATL
↓
vtable
↓
IWscAVStatus4
↓
CWscIsv
↓
WSCAPI.dll
↓
RPC
↓
Centro de seguridad de Windows
El proyecto se desarrolló y probó en un entorno de investigación de Windows controlado.
Solo para investigación / uso educativo
Este proyecto está destinado a la investigación de internals de Windows, ingeniería inversa, educación en seguridad y pruebas de seguridad autorizadas. No lo utilices para interferir con software de seguridad en sistemas que no poseas o para los que no tengas permiso explícito de prueba.
La pregunta inicial era simple:
¿Cómo sabe el Centro de seguridad de Windows que existe un producto antivirus?
En lugar de detenerme en la documentación pública de la API, quería entender qué ocurre debajo de la API.
Esto llevó a varias preguntas:
QueryInterface() la interfaz?__int64 a1 para un método?Register() es realmente la función de registro de AV?El primer paso fue identificar la clase COM del Centro de seguridad de Windows.
El proyecto utiliza la clase COM de WSC:
CLSID_WscIsv
F2102C37-90C3-450C-B3F6-92BE1693BDF2
La implementación también contiene lógica para localizar el CLSID dinámicamente desde el registro de Windows en lugar de depender exclusivamente de un valor codificado.
Conceptualmente:
HKLM
└── SOFTWARE
└── Classes
└── CLSID
└── {CLSID}
└── API ISV del Centro de seguridad de Windows
Esto proporcionó la primera relación importante:
Registro
↓
CLSID
↓
API ISV del Centro de seguridad de Windows
El siguiente desafío fue determinar qué interfaz COM debía solicitarse.
El proyecto utiliza:
IWscAVStatus4
con:
4DCBAFAC-29BA-46B1-80FC-B8BDE3C0AE4D
Una de las lecciones importantes de la investigación fue:
Un nombre de GUID por sí solo no es evidencia suficiente.
Verifiqué la relación mediante ingeniería inversa en lugar de asumir que el nombre de la interfaz y el GUID eran correctos.
La investigación incluyó:
QueryInterface_ATL_INTMAP_ENTRYQueryInterfaceUno de los pasos de reversión más útiles fue seguir la implementación de:
CComAggObject<CWscIsv>::QueryInterface()
que finalmente llega a:
ATL::CComObjectRootBase::InternalQueryInterface()
El mapa de interfaces ATL se utiliza para comparar el IID solicitado con las entradas de interfaz registradas.
Conceptualmente:
IID solicitado
↓
QueryInterface()
↓
InternalQueryInterface()
↓
Mapa de interfaces ATL
↓
Comparación de GUID
↓
Interfaz coincidente
↓
Puntero de interfaz
Esto proporcionó evidencia independiente de que el GUID investigado correspondía realmente a la interfaz COM esperada.
Register()Uno de los mayores desafíos de la reversión fue comprender por qué IDA/Ghidra no siempre mostraba la firma del método que esperaba.
La interfaz reconstruida contiene:
virtual HRESULT __stdcall Register(
BSTR path,
BSTR name,
unsigned int,
unsigned int
) = 0;
Sin embargo, el descompilador podría mostrar una implementación como:
_IWscAVStatus4<CWscIsv>::Register(__int64 a1)
Al principio esto parecía inconsistente.
Una investigación más profunda mostró que la representación del descompilador describía un wrapper/thunk y la llamada indirecta subyacente a la vtable, en lugar de presentar la firma lógica completa de la interfaz.
Esto se convirtió en una lección importante:
La salida del descompilador es una interpretación del código máquina, no la verdad original a nivel de código fuente.
Para resolver estas discrepancias, comparé:
Definición de la interfaz COM
↓
Diseño de la vtable
↓
Ensamblador
↓
Wrapper/thunk
↓
Convención de llamada
↓
Función objetivo real
Register()Otra fuente de confusión fue la presencia de múltiples funciones con nombres como:
IWscAVStatus2::Register
IWscAVStatus4::Register
IWscFWStatus2::Register
RegisterAV
La comprensión importante fue que nombres similares no significan interfaces idénticas.
Por ejemplo:
AV
↓
IWscAVStatus4
↓
Registro de AV
mientras que:
Firewall
↓
IWscFWStatus2
↓
Registro de firewall
El número de interfaz y la implementación circundante tuvieron que verificarse en lugar de seleccionar una función simplemente porque su nombre contenía Register.
Esta fue una de las partes más útiles de la investigación porque me obligó a correlacionar:
Interfaz
+
IID
+
vtable
+
implementación
+
diseño de parámetros
+
objetivo de llamada
Después de identificar la interfaz correcta, rastreé la operación de registro más profundamente en el binario.
La ruta observada fue aproximadamente:
IWscAVStatus4::Register()
↓
CWscIsv
↓
RegisterSecurityProductFunction
↓
wscRegisterSecurityProduct()
↓
WSCAPI.dll
↓
s_wscRegisterSecurityProduct()
↓
NdrClientCall3()
↓
RPC
↓
Centro de seguridad de Windows
Esto fue particularmente importante porque el método COM en sí no era la operación final.
La llamada finalmente cruzaba un límite de RPC.
Eso cambió mi forma de ver la arquitectura:
COM
≠
implementación final
En su lugar:
COM
↓
implementación local
↓
API de WSC
↓
cliente RPC
↓
componente de Windows
WSCAPI.dllLa siguiente capa era WSCAPI.dll.
La ruta con ingeniería inversa alcanzó:
wscRegisterSecurityProduct()
que finalmente invocaba:
s_wscRegisterSecurityProduct()
y luego:
NdrClientCall3()
Este fue el punto donde la investigación pasó de una llamada COM normal a la infraestructura RPC de Windows.
Comprender esta capa ayudó a explicar por qué el comportamiento no podía entenderse completamente mirando solo el DLL COM original.
El análisis estático fue solo una parte de la investigación.
Después de reconstruir la interfaz y la ruta de llamada relevantes, creé mi propia implementación controlada y comparé el comportamiento resultante con el Centro de seguridad de Windows.
Utilicé información del Centro de seguridad de Windows / WMI como:
ROOT\SecurityCenter2
AntiVirusProduct
para observar de forma independiente la información del producto registrado.
El proceso de verificación fue:
Ingeniería inversa
↓
Reconstrucción de la interfaz
↓
Implementación propia
↓
Ejecución en tiempo de ejecución
↓
Centro de seguridad de Windows
↓
Observación WMI
↓
Comparación de resultados
Esto me permitió verificar que las conclusiones del análisis estático correspondían con el comportamiento observable de Windows.
Este proyecto me enseñó considerablemente más que cómo interactuar con una interfaz COM.
CoCreateInstanceQueryInterfaceWSCAPI.dllNdrClientCall3Lo más importante fue aprender a evitar depender de una sola evidencia.
En su lugar:
Símbolo
↓
Descompilador
↓
Ensamblador
↓
GUID
↓
Mapa de interfaces
↓
vtable
↓
Grafo de llamadas
↓
RPC
↓
Verificación en tiempo de ejecución
Cada capa aumenta la confianza en la conclusión.
La implementación de la investigación consta de dos componentes principales.
OWN-Defender
│
├── OWN-Defender.cpp
│ ├── Interacción COM con WSC
│ ├── Descubrimiento de CLSID
│ ├── Inicialización COM
│ ├── Interacción con IWscAVStatus4
│ ├── Registro
│ ├── Actualización de estado
│ └── Limpieza
│
└── dllmain.cpp
├── Punto de entrada del DLL
├── Cargador de investigación
├── Ejecución controlada
└── Manejo de limpieza/detención
El repositorio es intencionalmente pequeño para que la relación entre el comportamiento con ingeniería inversa y la implementación siga siendo fácil de seguir.
Este proyecto se construyó en torno a preguntas en lugar de simplemente reproducir funcionalidad:
¿Cómo identifica WSC la clase COM?
¿Cómo se asigna el IID a la interfaz?
¿Cómo localiza QueryInterface la interfaz?
¿Por qué IDA muestra firmas de función diferentes?
¿Dónde está la vtable real?
¿Qué Register() es la implementación de AV?
¿Qué ocurre después del método COM?
¿Dónde entra WSCAPI.dll en la cadena de llamadas?
¿Dónde comienza RPC?
¿Cómo se puede verificar el resultado de forma independiente?
Estas preguntas fueron finalmente más valiosas que la implementación final en sí.
El proyecto también proporciona un punto de partida útil para estudiar el límite de seguridad entre:
Aplicación
↓
COM
↓
Centro de seguridad de Windows
↓
Información del proveedor de seguridad
Una distinción importante es que registrar información de productos de seguridad no equivale automáticamente a deshabilitar el motor de Defender ni a eludir sus mecanismos de protección.
Por lo tanto, este proyecto debe verse principalmente como:
Investigación de ingeniería inversa del Centro de seguridad de Windows / COM
en lugar de como una afirmación de que el registro en WSC por sí solo constituye una vulnerabilidad de Defender.
Cualquier impacto de seguridad requiere una investigación y validación separadas.
Esta investigación se inspiró en parte en el trabajo demostrado en DefendNot por es3n1n.
Un agradecimiento especial al autor por proporcionar un punto de partida útil para comprender el mecanismo de WSC.
Proyecto original: https://github.com/es3n1n/defendnot
El propósito de este repositorio no es reclamar la investigación original como propia, sino documentar mi propio proceso de ingeniería inversa, implementación independiente y verificación del comportamiento subyacente de Windows.
Este repositorio se proporciona para:
Utiliza este proyecto solo en sistemas que poseas o para los que estés explícitamente autorizado a probar.
El autor no es responsable del uso indebido, daños, pérdida de datos, interferencia con controles de seguridad o despliegue no autorizado.
Este proyecto está licenciado bajo la GNU General Public License v3.0.
Consulta LICENSE para más detalles.
El objetivo principal de OWN-Defender no es simplemente reproducir una técnica de registro de AV.
Es demostrar una metodología de ingeniería inversa repetible:
Encontrar
↓
Mapear
↓
Reversar
↓
Reconstruir
↓
Rastrear
↓
Implementar
↓
Verificar
Lo que comenzó con una pregunta sobre el Centro de seguridad de Windows se convirtió en una exploración más profunda de COM, ATL, mapeo GUID/IID, vtables, código generado por el compilador, WSCAPI, RPC y la arquitectura de seguridad de Windows.
La implementación es el resultado. El proceso de ingeniería inversa es el proyecto real.