Thursday, 1 November 2012

Windows Deployment Services Clear Text Domain Creds

Dave, Rel1k, Kennedy's talk 'Owning One To Rule Them All' at Defcon 20 Las Vegas opened my eyes to using a client's PXEBoot service, normally Windows Deployment Services, to infiltrate their network. The gist of the attack is simple, network boot a computer, retrieve the corporate image, and use that to gain information/credentials for the corporate domain.

The easiest way to do this, other than bringing a seperate machine, is to use a VM, but a lot of the windows boot images do not have drivers for the latest VMWare network interfaces. To get around this we can force a PXEBoot VM Image to use an older NIC by editing the VMX file with the following:

Add: ethernet0.virtualDev = "e1000" after ethernet0.present = "TRUE"

The next step is to network boot, obtain a PXEBoot response, and a Windows Boot Image is sent over TFTP to our machine.

Depending on the configuration two things may occur:

You may be asked for a password to connect to the image share - unfortunately you need a valid domain account at this stage and probably wont get further without it.

Alternatively you get a choice of a number of different images, they all could contain goodies, and are all worth checking out, but installing one can take a significant amount of time.

When you have the installed machine loaded, there's a number of possibilities for obtaining credentials:

a) The image could have been cloned from an existing machine, all post exploitation steps are viable to obtain credentials: hashdump the local accounts or Mimikatz/WCE to retrieve in memory credentials (the machine will often be configured to AutoLogin etc). If you don't have admin credentials on the machine you can mount the VM harddrive and copy the SYSTEM and SAM files to your host machine for cracking. Local credentials will often be the same for many client workstations/laptops and they may even be valid on servers.

b) The image could be automatically joined to the domain - we can now enumerate users, group policy preference files, logon scripts and domain shares to discover credentials.

c) Find the unattend.xml or imageunattend.xml file used to configure the image. If the process has worked correctly most credentials will be wiped from the XML file as they are applied. You may have some luck pausing the VM at certain points after installation but before it boots and mounting the virtual disk to obtain the unprocessed unattend.xml.

All of the above, is generally pretty easy, but can be very time consuming. You may not have set your VM harddrive large enough for the image, you may not have enough room spare to host the VM, errors with drivers may occur as they are meant for specific hardware, and it takes time to boot over the network and install each operating system they have available.

To ease my pain when performing these checks, I started writing some Metasploit modules to speed up the process:  auxiliary/scanner/pxe/pxe_servers which simply sends out DHCP Requests and listens for a DHCP Response containing the location of the PXEBoot server.

I need to do some more work on this - you may find this python more useful:

We can verify this is a Windows Deployment Service with the following command (if you have installed Impacket or use Metasploit's auxiliary/scanner/dcerpc/endpoint_mapper): 135/TCP |grep -i "1a927394-352e-4553-ae3f-7cf4aafca620"
1A927394-352E-4553-AE3F-7CF4AAFCA620/Version: 1
1A927394-352E-4553-AE3F-7CF4AAFCA620/StringBindings: ncacn_ip_tcp:[5040]

(1a927394-352e-4553-ae3f-7cf4aafca620 being the GUID identifying the Windows Deployment Services RPC Endpoint)

The goal of my investigations now, was to discover how to obtain the unadulterated unattend file without going through the rigmarole of performing a full PXEBoot install. After setting up my own WDS it is obvious that two SMB shares are often used to deploy the windows images, and unattend files:

\\server\RemInst  is the default folder used by Windows Deployment Services and should always have this name no matter which drive or folder they store images in.
\\server\DeploymentShare$  is the default folder used by Microsoft Deployment Toolkit, but this can be renamed but should generally always have a comment of 'MDT Deployment Share'.

When we gain access to these shares, it is simple to do a search for *unattend.xml but I believe they are generally located in the following paths:


These shares need a domain login, which is why we get prompted at the start of the process if the administrator hasn't set the installation to be completely unattended or 'zero-touch'. Fortunatly administrators often do configure WDSthis way and if this is the case TWO unattend files are actually used:
Windows Deployment Services client unattend file. This file uses the Unattend.xml format and is stored on the Windows Deployment Services server in the \WDSClientUnattend folder. It automates the Windows Deployment Services client user interface screens (such as entering credentials, choosing an install image, and configuring the disk).

Image unattend file. This file uses either the Unattend.xml or Sysprep.inf format, depending upon the version of the operating system in the image. It is used to configure unattended installation options during Windows Setup and is stored in a subfolder (either $OEM$ structure or \Unattend) in the per-image folder. It automates the remaining phases of Setup (for example, offline servicing, Sysprep specialize, and mini-setup).

That first WDS client unattend file may contain valid domain credentials, but how do we view it?

Microsoft decided this would be a good file to send in clear text without requiring authentication making it trivial to recover if we monitor the traffic of our VM install with the following Wireshark filter 'ip.addr==x.x.x.x && dcerpc':

I didn't want to have to boot up a VM to recover this file everytime,  it can take some time for TFTP to transfer the boot files, and the process can really eat into your testing time so I went about creating a tool to recover the unattend file directly from this service.

Fortunately for us this protocol is all documented on technet and is the Windows Deployment Services Control Protocol (WDSCP) running on TCP/5040.

It also uses the Windows Deployment Services Operation System Deployment Protocol Specification (WDSOSDPS) where anyone digging deep enough into the documentation may have discovered this issue by RTFM:

To that end I have created a metasploit module:


It will retrieve the unattend files for all architectures and store as loot. It will then parse the XML to retrieve the credentials and store as creds.


What if I protect my WDS installation by setting it to 'Respond only to known client computers' or even 'Do not respond to any client computers'?

As you can see from the tab name this only prevents the server from responding to DHCP/BOOTP PXE Requests, the RPC endpoint is still active, and will still respond to requests for the unattend file without any verification of the client. Requests for the unattend file do not show up in the 'Pending Devices', this only occurs if you download and load the boot file, making this method more stealthy than a VM boot.

Finally to make use the gained credentials, and hopefully obtain further credentials I created auxiliary/gather/windows_deployment_services_shares. This will enumerate the shares on the host and search through for unattend files and then extract credentials from them: