[ad_1]
Microsoft started talking about an Azure-specific version of Windows Server 2022 back in 2021. So what is it? As Orin’s blog post describes it:
Windows Server Azure Edition is a special version of Windows Server built specifically to run either as an Azure IaaS VM in Azure or as a VM on an Azure Stack HCI cluster. Unlike the traditional Standard or Datacenter editions, you can’t install Azure Edition on bare metal hardware, run it under client or Windows Server Hyper-V, or run it on third party hypervisors or within 3rd party Clouds.
OK, so you can run it in Azure or on-prem as part of Azure Stack HCI, but otherwise you can’t get it — you have to stick with the normal Windows Server 2022 Datacenter edition that it is based on. How is it different? The Microsoft docs spell out the feature differences:
OK, so apart from Azure Extended Network (an obvious cloud-only feature), the noticeable differences are hotpatching (being able to patch some things in the OS without rebooting, described here) and SMB over QUIC (where QUIC is [over-simplistically] HTTPS over UDP, making it a lighter-weight protocol designed for use over the internet).
Interestingly, even though you can use Azure AD Join with Windows Server VMs in Azure, that’s not actually a feature of the Windows Server 2022 Datacenter Azure Edition. More on that later.
Behind the scenes, the edition ID for this SKU/edition of Windows Server 2022 is “ServerTurbine”:
This is a standalone edition, meaning that it can’t be transformed to or from anything else. The upgrade matrix (C:WindowsservicingUpgradeMatrix.xml) indicates that you can upgrade ServerTurbine to or from any other Windows Server 2022 edition, but since there is no ServerTurbine media available it doesn’t matter much.
So what about Azure AD Join?
I was initially looking at the ability for a Windows Server 2022 virtual machine in Azure manages to join itself to Azure AD. That ability is documented, and easy enough to enable in the Azure portal when creating a new VM:
But since non-Azure Windows Server installs can’t do this, I wondered how this actually worked. That requires digging into the Azure VM provisioning process a little. Effectively, it’s just like any other Windows installation, processing an unattend.xml answer file, SetupComplete.cmd batch file, etc. The main difference is that Azure can dynamically inject these files into the OS as it is being provisioned. So what does it inject related to Azure AD? Looking at the C:WindowsPantherunattend.xml doesn’t provide any significant clues, beyond a call to a C:WindowsOEMUnattend.wsf or Unattend.cmd script, as well as an Install.cmd file at the root of a virtual floppy/ISO/disk with an appropriate tag:
It is funny that the Azure unattend.xml file uses SkipMachineOOBE and SkipUserOOBE even though Microsoft says not to use those:
There’s also the C:WindowsSetupScriptsSetupComplete.cmd, which is super-simple:
So the real work is obviously happening in the C:WindowsOEM files:
It’s funny that Microsoft is still heavily using VBScript (.wsf, .vbs) in this whole process, especially since they are going to make VBScript an removable feature in the future. I guess they’re in no hurry to reimplement this setup in PowerShell.
Alright, but where is the Azure AD Join logic in all of this? We’re not deep enough yet. The C:WindowsOEM scripts reference C:WindowsAzure, so we have to look at more stuff there:
Opening the first XML file in the Config folder points to an interesting “AADLoginForWindows” plugin:
So it downloads some stuff, extracts it, and executes it. But what does it actually do? Fortunately, it leaves the plugin files behind in the C:Packages folder, but it’s mostly a .NET Framework executable, so that’s not directly useful. But it also creates some logs in the “C:WindowsAzureLogsPlugins” folder structure:
Now we’re getting somewhere:
In the middle of that, it says “Starting Dsregcmd with argumets /AzureSecureVMJoin /debug”. So it appear to be running Dsregcmd.exe with some undocumented arguments, and then monitoring what happens (the “low-tech integration” approach, but hey, at least it isn’t more VBScript).
Of course the first thing I have to try is the same command on a non-Azure Windows Server 2022 Datacenter VM. And not surprisingly, it fails:
So it tried to find something in the registry, but it wasn’t there. A quick check in ProcMon tells us what that something was:
So HKLMSoftwareMicrosoftWindowsCurrentVersionCDJ is what it tried to find, and that doesn’t exist in my on-prem VM. So what does it contain in the Azure VM? Probably something that the plugin created:
So what do these URLs point to? The Azure Instance Metadata Service, which provides information from Azure about the VM to the VM itself. Looking at the details of what those URLs return (the first and third are easy to query from the VM; the second fails, probably because it’s not around forever, but the log shows that it does indeed return a token), it likely gets the computer name from the first URL, the Azure AD bearer token from the second, and the Azure AD tenant to join in the third. So Dsregcmd knows how to query those URLs to get the information it needs to complete the Azure AD Join.
Checking after the fact confirms that the VM is indeed joined:
So could this mechanism be used for non-Azure VMs? Possibly, by substituting your own web services to take the place of AIMS, returning exactly the same data as the those URLs would, in effect impersonating AIMS.
It’s surprising how much of this configuration “stuff” (scripts, configuration files, executables, etc.) is left around in the VM after the fact. At least there are no secrets/passwords exposed. But it is useful for anyone who wants to see what’s going on behind the scenes.
[ad_2]
Source link