If MMP-C is what you want, all you have to do is close your eyes and enroll your device into MDE Attach V2

Last Updated on July 24, 2023 by rudyooms

In this blog (title inspired by some Slipknot lyrics this time.. “If rain is what you want“) I will guide you through my MDE Attach V2 (Security Management) journey. While doing so I will explain which “service” is used to deliver the Intune policies to your NOT AADJ (or entra) Windows Server 2019.

If you think those policies are directly delivered by Intune or WinAtp you are dead wrong! Besides showing you the enrollment and the policy delivery, I am also going to show you how this journey helped me figure out what broke last Sunday (16-07-2023) with this new MDE Attach Version 2.

I will divide this blog into multiple parts

  1. Introduction
  2. The Simple Flow
  3. Me talking you through the Enrollment
  4. Me again talking, but this time about the Policy Delivery
  5. The corresponding big-ass flow
  6. How this blog helped me to debug a big issue
  7. The Leviathan Token

1. Introduction

So let’s kick off with a small introduction, shall we? Some time ago Microsoft introduced MDE Attach. What was really cool right? I didn’t spend much time looking at it but somehow something caught my attention lately.

When taking a look at the docs and especially the “troubleshooting” page, I noticed something

Troubleshoot onboarding issues related to Security Management for Microsoft Defender for Endpoint | Microsoft Learn

I copy paste the image below from the link above. Microsoft mentioned the enrollment status, which could give you an idea about what is going on if you are experiencing issues with the enrollment but I was focused on something else.

When taking a look at the enrollmentpayload, I noticed the checkinrurl: checkin.dm.microsoft.com

Okay…okay that got my attention… why? Because dm.microsoft.com refers to the new infrastructure (or maybe just Intune V2?) called: Microsoft Managed Platform Cloud (MMP-C) which is also used by EPM and believe me I spend some time looking at that!

MMP-C | Dual Enrollment | Microsoft Managed Platform Cloud (call4cloud.nl)

So yeah… it got my attention! From there on I started reading the docs a bit and asking myself a lot of questions.

Thinking Out Loud GIFs | Tenor

While reading the docs, I noticed some interesting parts in the MSdocs mentioning how to enroll/onboard your device into MDE attach v2

Use Intune to manage Microsoft Defender for Endpoint security settings on devices not enrolled with Microsoft Intune | Microsoft Learn

As shown below, they are indeed mentioning the fact that a synthetic device identity will be created and the policies will be retrieved from Microsoft Intune

Huh…. So we have dm.microsoft.com which is used for enrollment and checking in (policy retrieval) If you have read my other blogs about MMP-C you will know that the enrollment requires an AAD token, so I was like… how are we getting that token without an actual Azure Ad Join (yeah Entra…blahblahblah)

So I started looking at the corresponding files (mssense.exe,sensecm.exe,mssense.dll) and took some WPR traces while doing so. While onboarding a lot of VMS and placing the tag to enroll them with MDE security management, something also changed last Sunday.

Of course, I made sure I configured everything to enroll the device into MDE Attach V2, and onboarded my device to MDE ATP ready to be enrolled!

2. The Simple flow

Before I am going to talk you through the Enrollment and show you the big-ass Flow, I will start by showing the simple version of the Enrollment flow to get a good understanding about what I am going to talk about.

3. Me talking you through the Enrollment

Now, with this simple flow in the back of our minds, let me start talking about the details of what is going on during the enrollment!

While onboarding and enrolling the device I made sure I had my WPR trace (MDE analyzer tool has some nice WPR files in it so thank you Microsoft!) configured and enabled the Procmon trace.

When the “mde-management tag” is placed, a configuration payload will be delivered to your device. This payload contains the sensecmconfiguration (the name is obvious) and will be stored in the Windows Advanced Threat Protection registry key.

When we take a closer look at this payload we will notice that it contains some funny stuff. As shown below, the payload contains all of the certificates required and the corresponding and required certificate chain.

I love it and hate it at the same time…Why? Because we now have some certificate pinning, that prevents me from looking at it with Fiddler…

With certificate pinning, we will only notice Sense reaching out to WinAtp with an HTTP request. The MMP-C service would check if the certificates provided by the client (hardcoded) match, if not…the rest of the traffic that comes after will die in the process.

Please note: Certificate pinning is of course way safer and prevents people like me from looking at the traffic.

Besides the certificates, it also contains some other very important information.

  • The Enrollment URL : enrollment.dm.microsoft.com
  • The Discovery URL: discovery.dm.microsoft.com
  • The Checkin URL: checkin.dm.microsoft.com

MMP-C rules them all!!!!… that’s for sure when looking at those URLs! But besides those URLS, something else is mentioned: SenseCmModeSwitch. More on this great setting later on! But believe me, it’s very very important!

So now the device has the payload with the enrollment information, the actual enrollment will start!

With the enrollment start, Sensecm would first check the status of the enrollment to determine the status… so it checks the enrollmentstatus… Duhhh, without knowing what is set, how would you know what to do?

Now “sensecm” knows the status of the device, it will parse the actual sensecmconfiguration payload it got to know which “version” it needs to enroll the device with.

This part is called: SIAM (I assume that stands for Service Integration and Management or maybe something totally different but who knows?). We have got the old SIAM version (V1) and the new SIAM version (v2).

In the code, SIAM is hardly used, in the code they are referring to SenseCmMode. So with this “switch”, sensecm knows if the device needs to start the AADRegistration V2 (synthetic) or use the old AADregistration (AADJ)

In the sensecmconfiguration payload, I showed you, that setting was configured to 2, so it will perform a “fake” AAD register (it’s not fake or synthetic…but it doesn’t perform a real AADJ.). At that point in time we will notice NO WinHttp requests…so nothing is being sent over to WInatp at that point in time.

If the “fake” AAD registration is successful, it will log an event mentioning that the device will probably be in V2 (yep… we are!! as we didn’t perform an Azure Ad Join with the use of the AAD Runtime AADRT.Dll)

So no Azure Ad joined device, but it continues the MEM enrollment. To do so, it will kick off a discovery with the URL (discovery.dm.microsoft.com) it got from the payload. (please note that it doesn’t have the Intune or aadDeviceID’at this point in time)

But besides this information, we also notice something else in the request!

Again the SenseCmModeSwitch to tell if the device needs to use v1 or v2 is mentioned in it and of course the sensemachineid itself. As expected in the discovery response we will notice the URL.

Afbeelding met tekst, Lettertype, schermopname, lijn

Automatisch gegenereerde beschrijving

Sounds a lot like the MMP-C/EPM discovery and enrollment, right? Please read this blog to fully understand the flow behind it!

MMP-C Discovery failed | No valid Endpoint | EPM (call4cloud.nl)

With the enrollment URIs in our pockets, Sensecm would reach out to this service

Buttttt..do you remember?

Do You Remember GIFs | Tenor

As mentioned before, MMP-C requires an AAD token for a silent (linked) MMP-C enrollment when we want to enroll our device into EPM.

so what the “F” does it use now? Let me let you in on a little secret! Just a few milliseconds before the Winhttp request is sent, a function that is called “GetLeviathanToken” kick-ins. If you want to know more about this token please read part 6:

If we take a closer look at the enrollment request, we will notice that it contains the same token (leviathan) in the request

Afbeelding met tekst, schermopname, Lettertype, nummer

Automatisch gegenereerde beschrijving

And of course the senseidmachine guid and as always the sensecmmodeswitch is also mentioned! With the enrollment being sent to the device, guess what we get back?

We suddenly have our “Checkin” URL and the required IntuneDeviceID! (which we didn’t have before) So it created the device object on the fly!

With this last step, the MEM (MMP-C Enrollment) is finished and we have a nice synthetic object being created in Azure/Entra/Intune

So far so good right? MMP-C will take care of the enrollment, but what about the policies? When reading the docs, they are only mentioning Intune, right? Let me show you

4. Me again talking, but this time about the policy delivery

So we have our Window 2019 server onboard to MDE and got it enrolled into MMP-C (which is nowhere mentioned in the docs… ) to make sure the server could receive some Intune Policies.

Before talking you through the policy delivery, let’s take a look at the Microsoft documentation and how they are mentioning how the device reports to Microsoft Endpoint Manager(MEM)

Conceptual diagram of the Microsoft Defender for Endpoint security configuration management solution

So nothing new to see here! Well “it depends”. Let us take a look at what I think happens! If we configured some policies and press the sync button, the policies will be delivered to the device when it checks in!

Afbeelding met tekst, schermopname, Lettertype, algebra

Automatisch gegenereerde beschrijving

Of course, we can also wait 90 minutes on the background scheduler as shown below but I am not that patient

When you are curious how this 90 minutes background schedule is being set, please read my blog about LAPS and the threadpooltimer!

After pressing the sync button or waiting on the background schedule, the device would reach out to the service after getting the notification to “CheckIn” to winatp-gw-weu.microsoft.com

As always when we need to authenticate ourselves to a service, we need a token. When we take a look at that request, we will notice that it again sends out the Leviathan token to authenticate itself to the service!

Afbeelding met tekst, schermopname, Lettertype, lijn

Automatisch gegenereerde beschrijving

When we take another good look, we will notice that instead of the Winatp url it reaches out to checkin.dm.microsoft.com (MMP-C) URL. In this request to MMP-C, we will notice that it also sends out the aadDeviceId and the intuneDeviceId that it got

After receiving the request MMP-C would send out the payload that contains the policies

These policies will be checked and merged when needed. After the merge was successful, sensecm would enforce those policies on the device.

But where are those policies stored? When I was taking a look at Procmon something caught my eye

Procmon was showing the fact that sensecm.exe was querying a file named: RunPsScript.dll. So from there, I started paying attention to ps1 and psm1 files being created

As shown above, Sensecm, would create the additional PowerShell modules and the JSON with all the policies in it! So I made sure I got myself elevated to System and opened this folder. If you are quick you can spot them (and copy them.. I did…).

The Zip file with the files on it, so you can take a look yourself!


With the PowerShell modules and the Policy JSON on the device, Sensecm will now check the policies that are configured in the JSON file and which policies are already configured. From there it would kick off the PolicyEnforcer PowerShell script and the modules that determine what to enforce.

So no nodecache, CSP, or WinDC stuff for us this time just some good old written PowerShell scripts to deploy some settings aka policies (Antivirus, ASR, EDR, Firewall) to our device (and being reapplied)

So to resume, MMP-C is used to enroll the device, and create the synthetic object, and it now also delivers the Intune policies to the device! Isn’t that just beautiful!

So maybe if you didn’t want to read the whole flow… please take a look at the flow!

5. The corresponding big-ass flow

This big-ass flow will show you everything you need to know and will show you way more details than the simple flow I showed you earlier(I will update it along the way as it still misses some pieces). Click on it to get the large BMP version you can download

6. How this blog helped me debug a big issue

Maybe you are following me on Twitter or maybe you don’t but if you are following me I hope you noticed this tweet.

I onboarded a dozen VMs to MDE and enrolled them in MMP-C and it all went fine. As it was Saturday my girlfriend was getting mad at me, so I decided to leave a VM but with all logging enabled.

The next day (Sunday) I woke up and somehow I had a previous MDE attach v2 enrolled Windows 2019 server, that now somehow got a dual state (we all know that from the pain HAADJ was called)

Somehow on 16-07-2023, my MDE-enrolled devices got instant Azure Ad joined!! And I didn’t do anything! That’s bad!!! Because this feature was the solution for our NOT AADJ devices (because we didn’t want them to be)

When taking a closer look at the device itself with dsregcmd, it indeed also showed me the Azure Ad join status! To be sure I wasn’t going mad (yeah maybe I already am) I enrolled some new VMS. Guess what happened to them! They all became AADJ!!! …For your information: If I have a certain flow to do something and to test something. Every single step I take will be the same every single time. So I knew something was off

I decided to dive in a bit more because, at that point in time, I didn’t understand the full flow but after spending some time in the mssense.dll I figured that the sensecmmodeswitch was the key. That simple setting tells the device to use SIAM (MDE attach) V1 or V2.

Guess what happens with a device that got a nice synthetic object and got that policy pushed? Yeah it will reenroll again but this time it will perform an Azure Ad join by using the wonderful aadrt.dll file (so no deviceenroller.exe or fight club this time) from the same defender folder (more on aadrt.dll in a later blog.. )

So I decided to spend some more time in the code and looking through the Procmon and WPR trace that was still running. After scrolling down and excluding a lot of false data, I noticed that somehow a new sensecmconfiguration payload was pushed to the device!

Looking at this payload and the WPR trace I got, it showed me the senseCmModeSwitch:1. This just means, USE THE OLD SHIT AND GET YOURSELF A NICE AADJ!!! Nothing more

Afbeelding met tekst, schermopname, Lettertype, nummer

Automatisch gegenereerde beschrijving

After reaching out to some people and MS PMs, they were made aware of this big issue quickly. Within a couple of hours, the fix was released and all new devices got enrolled and created a synthetic device as they should but…. The already enrolled devices were still AADJ… and that’s not going to get resolved!

But how did this happen? yeah, that’s probably something we will never know but If I need to put on my assuming hat

Microsoft changed/updated something on their end and needed to push down a new setting to the device but forgot to change the sensecmmodeswitch in the configuration file and with it moving the V2 devices back to V1 and enrolling them into AADJ

7. The Leviathan Token

I moved this background information about the Leviathan token to a separate part (it deserves it). The Leviathan token, yeah I also never heard of it…it sounds like a monster..ow wait

This token is used to authenticate to ATP (sevillegw). When we take a closer look at this function that gets the token we will notice some funny behavior

As shown below, this function will try to find the token in a specific registry key

When we take a closer look at this wonderful Token we can spot it with system privileges in the key below:(without system privileges, access will be denied!)

This token will be set by MsSense.exe when onboarding your device to ATP. It will do so by sending out a request to the Winatp URL during the onboarding process.

This function “GetToken” will be called upon and this one would fetch the Leviathan Token

This Leviathan token will be stored in the Windows ATP registry key

This registry key is protected and can’t be tampered with even not as SYSTEM! I even tried to initiate a live response and trying to launch a PowerShell script to change or delete that key but luckily it’s a good thing that’s not possible!



I guess I made my point now?

Yes-ryan GIFs - Get the best GIF on GIPHY

23 thoughts on “If MMP-C is what you want, all you have to do is close your eyes and enroll your device into MDE Attach V2

  1. Hi,

    Thanks for this amazing detailed blog !
    we can see now that this works properly, but with workgroup machines we still observe the Azure Joined (MDEJoined / MDEManaged) being done.
    Does it mean this works for domain joined machines only ?


    1. Hi. Thanks!
      The MDE attach v2 will work for Workgroup joined servers. With what kind of setup are you testing it?

      1. We have a mix of domain joined servers and workgroup servers (Linux and Windows)
        The domain joined servers and linux servers we see them created as synthetic (no jointype) with the workgroup server we still see them as Azure Joined.
        We are running several tests with limited access to only defender urls (EDL), this seem to be sufficient to onboard in all 3 services (MDE/Intune/Azure).

        1. This is what what the data shows from the Azure API:
          2 records with the same objectid are being created:

          displayName deviceId operatingSystem operatingSystemVersion trustType isManaged profileType systemLabels LastSyncDateTime LastLogonTimestamp

          SRVXXXXXX 08d8afbe-xxxx-xxxx-xxxx-1d1f5468c139 Windows Server 10.0.17763.3650 AzureAd TRUE Shared MDEManaged 20-7-2023 09:37
          SRVXXXXXX 08d8afbe-xxxx-xxxx-xxxx-1d1f5468c139 Windows Server 10.0.17763.3650 AzureAd TRUE Shared MDEJoined 20-7-2023 09:37

          with a domain joined machine (just server, id and windows,version):
          SRVDFCPZ002 448b9de8-xxxx-xxxx-xxxx-1c8b954a2492 Windows Server 10.0.17763.4645

          Can you confirm this from your side ?

          1. Also in the MDEclientAnalyzer results log (MdeConfigMgrRegInfo.txt) the following is registered
            SenseCmModeSwitch : 2

            This would suggest that V2 flow is followed…

          2. Yep… so the config that is deliverd to the device is the proper one. what is the sense (mssense.exe / dll ) version?

          3. That one should work as the minimum version would be: 10.8295.22621.1023 for v2.. so the first one 10.8210 isnt going to work

          4. ok, a newly deployed workgroup server seems to be ok now, a synthetic record is created.
            Will monitor this behavior, but seems to be fixed for now !

          5. As long as you indeed have the required sense version and if the config also mentions the sensemodeswitch 2 it should be alright.

  2. This all seems exceedingly over-complicated (a common situation with Windows), but at least it appears that the security and device management teams are cooperating to a degree.

  3. Dear Rudy,

    I enjoyed your insightful article, thank you. However, like a previous commentator, I’ve noticed that workgroup servers onboarded using Attach V2 seem to be Azure AD joined. Could this possibly be a bug?

    1. In the blogpost , in part 6 i was mentioning the bug you are also mentioning
      But that was causes because a bad config being pushed to the devices

      If the sensecmconfig mentions sensemodeswitch v2 it should create the fake synthetic object… but that also depends on other factors as well… for example the sense version on the device… that one needs to know the new version (latest windows updates will do so)

  4. Very nice article! Helped a lot in troubleshooting the process. Have a couple of odd devices that are showing SenceCM reg key enrollmentstatus 19 which is not documented anywhere

    1. Hi.. Thanks!.. that 19 value… if ia am not mistaken i had that same error when I manually changed the enrollmentstatus to 1 … at that time the enrollment pay load wasnt on the device. Did you found the root cause of that error?

      1. sort of. Had a bunch of servers with code 19, all 2016 ones. Ended up offboarding them, restarting, removing endpoint security client, restarting, installing client, restarting, onboarding and then changing key to 1, which I suspect what triggers the whole process.
        Another code that was giving hard time was code 36 or 35, affecting 2012 and 2016 only. After client install and onboarding, then restart and then installation of Microsoft Defender for Endpoint update for EDR Sensor. Then changing key from 35/36 to 1 which again triggers the process. 1 minute and evice appears in intune and code either changes to 0 or 1 or 43, all seem to be success codes.

      2. currently facing code 19 again on other 2016 servers, the below approach not working anymore 🙁 M$ support useless. So if you know any other tricks I could try that would be really appreciated as I’m loosing it

  5. A bit unrelated but using Procmon I am seeing mssense.exe locking up some files my Devs are working on. Thus causing the applications to error out. I have read all the exclusion articles for this issue at Learn.microsoft and deployed the fixes (Including GPO exclusion), but issue still remains. Can I really not fix this issue on my own and must open ticket Microsoft support?

    It appears to create exclusions for mssense.exe I need the MDE product group team? Is there another way to do this on my own?

    Issue I am facing : https://www.reddit.com/r/DefenderATP/comments/z2wecc/mssenseexe_locks_temporary_pdf_files_in_user_temp/

Leave a Reply

Your email address will not be published. Required fields are marked *

  +  67  =  74