This blogpost is based on an evil thought I have had. After all, I have been a pentester for several years, so «evil» ideas are a part of my mindset. Let’s say I want to plant a backdoor on future machines, where would I put my backdoor? Inside the WIM that is used to deploy Windows of course. In this post I will walk you through the steps for injecting backdoors into a WIM file and how to detect if someone has changed the WIM file. In my lab I have a running MDT solution to deploy machines and I will manipulate on the WIM that is used to deploy Windows 7 machines. You will need Windows Assessment and Deployment Kit (ADK), and in particular the dism.exe.
First I navigate to the file in CMD. In my example the file is stored in D:\Deployment\Operating Systems\REFW7X64-001.wim.
Next, we need to mount the file to a folder on the machine. First I create a new folder for this purpose using this command:
Mkdir D:\mount
When the folder is created I use the following command to mount the image:
dism /mount-image /ImageFile:”D:\Deployment\Operating Systems\REFW7X64-001\REFW7X64-001.wim” /index:1 /MountDir:d:\mount
When the WIM file is mounted, it is time to plant the backdoor. In this example I will use a simple «backdoor». I will replace the Utilman.exe with the cmd.exe file. A detailed blogpost about this is explained in detail here:
http://msitpros.com/?p=1714
When I navigate to the d:\mount\windows\system32 folder and try to delete Utilman.exe I get an access denied. This is due to the fact that you have no permissions. This is the default permission on the files:
In order to delete/replace the file you will have to take ownership under the advanced tab and then adjust the permissions. Then you can delete file and replace it with cmd.exe
After I have done my adjustments I can dismount the image with this command to apply the changes:
dism /unmount-image /MountDir:D:\mount /commit
I have had some troubles with committing, but it is often resolved by running the command from this path:
c:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Deployment Tools\amd64\DISM
After the commit is successful I deploy a machine to confirm the change I have made. And yes, it works:
This was of course a simple example, but an evil attacker could do much worse things to the image. The big question is how do we detect if someone has changed the image?
Detecting/monitoring WIM changes:
There are many ways to detect changes and for all I know, someone could already have better solution than what I have made. I chose to create a PowerShell script that runs on a regularly basis and saves the hash of the file to a «CSV database File» for comparing.
The script I made has been uploaded to my GitHub account here:
https://github.com/api0cradle/PowershellScripts/blob/master/MDT/Monitor-WIMHashChanges_0.9.ps1
In order to adjust the script to your environment you will need to change the $MDTShare and the $ChecksumDBFile variable inside the script. After the parameters is adjusted, you must save the script to an appropriate location.
After the save is complete you will need to create a scheduled task so that the script runs at wanted intervals. I suggest once a day. In my lab I have not focused on hardening of the account that is going to run the script, but I would strongly recommend to only allow necessary permissions in production.
Here are the screenshots from when I made my scheduled task using the GUI (Can be done with PowerShell):
Command: Powershell.exe -ep unrestricted -file d:\Monitor-WIMHashChanges_0.9.ps1
Answer YES if you want to put it in as arguments to Powershell.exe and do next, next, finish….
After it is created you will have to change it so it runs with the highest privileges. (Script needs Admin privileges)
The script will now run every night at 22:00. The script will calculate the hash value of each of the WIM files and store it to the ChecksumDB CSV file. The first time the script runs it will not write anything to the eventlog. The next time the script runs it will compare the current values with the latest value in the ChecksumDB CSV file. If the hash has changed since the last timed it ran it will generate an error alert in the event log. When the hash is the same as last run it will generate an information in the event log. The script can take a long time to complete if you have many WIM files. With one normal sized WIM file it can take 3 minutes to calculate the MD5 hash, so be patient.
No changes look like this in the eventlog (one event per WIM file):
If there are changes the eventlog will look like this:
And here is a screenshot of my ChecksumCSVFile:
Another thing you would like to do in order to full automate this solution is to add a step to your build and capture task sequence so it calculates the hash as a part of the task sequence and adds it to the ChecksumCSVFile. Remember to update your monitor solution to detect if an error event is triggered to detect any changes. Perhaps you will catch a hacker or detect unwanted changes to your WIM files. 😉