
BOF POC del proyecto DSCourier / invocando WinGet mediante COM
Esta es una implementación BOF del proyecto DSCourier de Dylan Davis y Matthew Schramm. Utiliza la interfaz COM de WinGet para ejecutar código arbitrario de PowerShell en un proceso firmado y de confianza de Microsoft. Su blog de investigación completo se encuentra aquí.
A diferencia de la mayoría de los proyectos que publico, esto NO es una herramienta operativamente lista, sino más bien una POC. Decidí no continuar con esto después de descubrir varios problemas que impiden que sea un BOF fácilmente desplegable. El código fue casi totalmente improvisado. Varios problemas permanecen sin resolver y se discuten a continuación.
Coloca tu código arbitrario de PowerShell en el archivo dist/rev.yml. Por defecto contiene un simple reverse shell de PowerShell del repositorio original. Si decides usarlo, asegúrate de reemplazar la IP en el ejemplo existente con tu IP deseada.
Ejemplo usando el reverse shell de PowerShell:


Sin un orden particular, aquí hay algunos problemas/limitaciones de esta herramienta.
Microsoft.Management.Configuration.winmd debe estar presente en el mismo directorio que el ejecutable que realiza las llamadas COM. Esto representa un problema inmediato al ejecutar un Beacon desde un proceso de system32 vaciado, por ejemplo, donde los usuarios normales no tienen permisos de escritura. Para solucionarlo, el archivo se coloca en %APPDATA%\temp y se engancha la función WinTypes!RoGetMetaDataFile que recupera la ruta del archivo winmd con un inline hook para poder proporcionar la ubicación temporal. Esto permite que el archivo winmd sea leído/las llamadas COM tengan éxito, pero implica llamadas a VirtualProtect y sobrescritura de memoria de DLL, lo que genera IOCs.pwsh dentro de WinGet, se genera un proceso conhost.exe bajo ConfigurationRemotingServer.exe. Claude sugirió que sería posible cargar un módulo binario personalizado como recurso en lugar de invocar pwsh, lo que resolvería el problema de conhost, pero esto requiere colocar archivos adicionales en disco y no pude hacerlo funcionar. Quizás no sea posible. Si lo fuera, abriría la puerta a colocar un DLL .NET genérico en disco que podría ser cargado por y ejecutar shellcode/parámetros/etc. pasados.Esta herramienta fue escrita sin el uso de declaraciones normales de API de BOF (por ejemplo, un archivo bofdefs.h). Como se describe en este artículo de blog de Matt Ehrnschwender, es posible usar objcopy para parchear los símbolos correctos con el formato DLL$API en el BOF después de la compilación.
He escrito una herramienta llamada BOFPatcher que automatiza este proceso. Esto permite a los usuarios escribir BOFs como C normal sin preocuparse por engorrosas declaraciones de API:

Esta herramienta está disponible para quienes compren mi curso BOF Development and Tradecraft.
Aunque la herramienta BOFPatcher no está incluida en este repositorio, el Makefile de esta herramienta llama a objcopy, pasando un archivo imports_dscourier64.txt que contiene los reemplazos de símbolos adecuados, lo que hace que el BOF sea utilizable.
ConfigurationRemotingServer.exeConfigurationRemotingServer.exe termine; con el ejemplo simple del reverse shell, esto significaría que el Beacon no volvería a comunicarse hasta que el shell se cerrara. Cambiar a las interfaces Async evita este problema, pero introduce algunos problemas de sincronización. Hay un sleep fijo de 3 segundos que ha funcionado en la práctica para retrasar entre llamadas específicas, pero claramente no es la forma adecuada de implementarlo..msixbundle de winget-cli desde Github, extrayéndolo, extrayendo el .msix y encontrando el archivo .winmd. Luego se usó winmdidl.exe para extraer los archivos IDL. Después se utilizó midlrt.exe para convertir el IDL en archivos de cabecera/.c, que luego fueron reducidos por Claude para contener solo las definiciones necesarias. Sigue siendo un lío de código. Este enlace de Microsoft probablemente sea útil para entender mejor este proceso.winget configure --enable debe ejecutarse al menos una vez en la máquina objetivo antes de que el BOF funcione. Rastreé la razón de esto hasta el hecho de que el directorio DotNet que contiene ConfigurationRemotingServer.exe ni siquiera existe hasta que se haya ejecutado el comando / se haya descargado el binario. Estos archivos residen en C:\Program files\WindowsApps\... y por lo tanto no son editables por un usuario con pocos privilegios, por lo que ni siquiera podemos colocar estos archivos nosotros mismos con el BOF y hacer que funcione.configure --enable no se ha ejecutado, te quedas completamente detenido. Para fines de post-explotación podría tener valor, pero estás algo limitado por el hecho de que es un proceso fijo que generará/ejecutará tu código, y al ser pwsh, AMSI estará presente.