Restrict USB Storage Devices on Windows XP

This is one of those topics that are probably on the top 10 to do’s of anyone’s list when it comes to securing their Windows desktops. Whether it is plain dictatorship, security/confidentiality concerns/requirements, unpatched OS’s, weak/no AV solutions, the golden POLP (Principle Of Least Privileges) may force you to come up with a solution to this problem. If you are using anything else (XP, 2000, 2003 Server) except the newer versions of Windows (Vista, 7) which allow you to do this via a GPO setting, you are out of luck, there is no GPO setting or quick-fix that works.

As a short history, I went through CIA documents that were published (can’t find them anymore), Forums, Microsoft KB’s, Whitepapers, and finally came up at the other end of the tunnel with a working process.

The goal is to devise a process of denying access to USB Storage that meets following criteria:

  • Must be implemented at OS level
  • Must be deployed scripted/automatically and/or via GPO
  • Must not cripple other OS functionality (e.g. installing printer/scanner drivers)
  • Must be fully reversible by Administrators only
  • Must be working regardless if USB Storage was used before the process is put in place

The solution – explained

For disabling USB Storage there are 2 situations to cover:

  • No USB storage ever installed, user must not be able to install device
  • USB storage was previously installed by user or admin, user must not be able to use USB Storage again

Both scenarios are covered in these 6 steps:

  1. Copy usbstor.inf, usbstor.pnf, usbstor.sys to their default locations, as if a USB storage device would be installed.
  2. Restrict access to the 3 files mentioned above. We will use an implicit DENY for the local “SYSTEM” Account for these files.
  3. Remove Registry Keys that handle USB Storage device startup: HKLM\SYSTEM\CurrentControlSet\Services\USBSTOR and HKLM\SYSTEM\ControlSet001\Services\USBSTOR and HKLM\SYSTEM\ControlSet002\Services\USBSTOR
  4. Replace USB Storage related registry keys with specially crafted keys that disable startup of the USB Storage driver
  5. Apply an implicit DENY for the local SYSTEM Account on the Registry Keys mentioned above
  6. Insert USB Storage device, wait for it to be detected by OS and marvel at the fact it won’t let you install the device 🙁 🙂

For enabling USB Storage these steps must be taken from an Account that is member of the Administrators Group

  1. Remove restrictions placed on the ubstor.* files.
  2. Remove following specially crafted Registry Keys: HKLM\SYSTEM\CurrentControlSet\Services\USBSTOR and HKLM\SYSTEM\ControlSet001\Services\USBSTOR and HKLM\SYSTEM\ControlSet002\Services\USBSTOR
  3. Remove restrictions placed on the registry keys from above
  4. Delete incompletely installed USB storage devices fron Device Manager and Reboot Computer
  5. Insert USB Storage device, wait for it to be detected by OS/go to device manager and refresh device list and marvel at the fact it works 🙂

Implementation – explained

For implementing this in a scripted manner we will use batch scripting, I’m going for a low level approach, assuming you don’t have vbs / powershell on hand, vbs would be rather complicated anyway and Powershell is not installed by default on the OS. You do have some prerequisites:

  • reg.exe (available by default on XP)
  • A network share
  • set-acl (open source utility – get it, copy to a network share of choice and be happy it exists)

Disabling USB

  • The 3 usbstor files mentioned earlier, 2 are available by default (usbstor.inf and usbstor.pnf) under %WINDIR%\inf. The 3rd, usbstor.sys, unless a usb storage device was previously installed is not present. Find it under %WINDIR%\Driver Cache\i386\ or the other cab files there. Extract it from the cab file to the network share.
  • The piece of code that disables USB is written below, but requires that set-acl, the specified .txt, .reg, usbstor.sys files be present in the same directory from which it is executed
::Copy ubstor.sys
xcopy /R /H /Y %CD%\usbstor.sys %windir%\system32\drivers

::Secure USBSTOR.* files with ACE (only Local Administrators Full Control, local "SYSTEM" denied Full Control)
SetACL.exe -on "c:\windows" -ot file -actn restore -bckp "%CD%\usbstor_ACL.txt"

::Delete settings related to USBSTOR Service
REG DELETE HKLM\SYSTEM\CurrentControlSet\Services\USBSTOR /f

::Add special crafted registry keys
regedit /s "%CD%\disable_usb.reg"

::Secure keys from above with ACE (only Local Administrators Full Control, local "SYSTEM" denied Full Control)
SetACL.exe -on "hklm\SYSTEM" -ot reg -actn restore -bckp "%CD%\HKLM_ControlSet.txt"
  • Line 5 of the code uses a file that contains a specially formatted ACL applicable to the 3 usbstor files. To generate a different ACL, use the syntax below for each file you are interested in. When you are finished you can merge all text files in a single text file and add it to the script.
SetACL.exe -on "c:\windows\inf\usbstor.inf" -ot file -actn list -lst "f:sddl;w:d,s,o,g;s:b" -bckp "%CD%\usbstor_inf_ACL.txt"
  • REG command is used to delete any data that may exist in the specified registry keys (think previous installed USB Storage)
  • Once the Registry is clean of the keys, we then push a customized reg file (find it at the end of the post), that essentially changes this:

USBSTOR driver points to the file you defined (usbstor.sys, that you just set a restrictive ACL on)

DeviceCount equals zero 🙂

DeviceStartUp Type is set to Disabled (more details here)

Other standard settings for that key

  • Line 16 of code, similar to the ACL for USBSTOR Files, configures the security for the registry keys we added. To customize the ACL, change it to your liking then export the ACL using the command below and update the batch code to include it.
SetACL.exe -on "hklm\SYSTEM\CurrentControlSet\Services\usbstor" -ot reg -actn list -lst "f:sddl;w:d,s,o,g;s:b" -bckp "%CD%\HKLM_CurrentControlSet.txt"

Enabling USB

This is just a question of reversing the changes made by the Disabling process. The following piece of code does just that:

::enable inheritance of permissions
SetACL.exe -on "c:\windows\inf\usbstor.inf" -ot file -actn setprot -op "DACL:np;SACL:np"
SetACL.exe -on "c:\windows\inf\usbstor.pnf" -ot file -actn setprot -op "DACL:np;SACL:np"
SetACL.exe -on "c:\windows\system32\drivers\usbstor.sys" -ot file -actn setprot -op "DACL:np;SACL:np"

::clear any non-inherited ACE
SetACL.exe -on "c:\windows\inf\usbstor.inf" -ot file -actn clear -clr "dacl,sacl"
SetACL.exe -on "c:\windows\inf\usbstor.pnf" -ot file -actn clear -clr "dacl,sacl"
SetACL.exe -on "c:\windows\system32\drivers\usbstor.sys" -ot file -actn clear -clr "dacl,sacl"

::deleting custom Registry Keys
REG DELETE HKLM\SYSTEM\CurrentControlSet\Services\USBSTOR /f
  • As you can see we are enabling inheritance of permissions, clearing any ACE defined explicitly on that object (the ones we pushed actually) and removing the Registry keys we also pushed. Make sure the user running this enabling process has rights to change these objects (in our case he is member of the Local Administrators Group)
  • After this is done manually clean it of any hidden installed USB Storage devices and reboot the computer. After the reboot replugging the device should allow you to install and use it again.

Phew, this was also a long post, but believe me, reaching this compressed format was a lot of work :).

Now I’ve attached this zip file containing the contents of what I’ve been talking about, it should be usable out of the box.

There is also there question I guess of securing these files so that they apply to users but users can’t get to them to “help themselves”, but that is another topics for another post perhaps.

As always any feedback is welcomed.

Configure USB device to boot WindowsPE

It’s been a while since my last post but now I found some time to write a complimentary article to my “make your PE boot disk series”. While the make your PE disk series showed you how to make a bootable ISO, it is possible however to write the contents of the ISO to a USB stick and by following this guide to boot Windows PE from USB. The advantage of having a WinPE on USB is great flexibility, with a CD you always have to rebuild the ISO and burn it/mount it whenever you feel like adding new applications/scripts to it. With a flash drive you can just copy the data alongside the booting OS.

Here’s what you need:

  • USB stick of choice (portable USB HDD works aswell)
  • A PC running at least a Windows Vista kernel (Windows 7, 2008 – WinPE versions of these also work)
  • Administrator privileges on the machine.

With the introduction of Vista and later kernels making USB storage bootable for windows became so much easier. Before (win Xp/2003 days there were specialized tools that major hardware vendors had, as far as I know). Why this is was not working in XP/2003?

The reason is that 5.x Versions of Windows did not mark a USB device as hard disk storage device, and you could not use “diskpart” command line utility, to mark partitions as active, what you need to get WinPE to boot.

Diskpart is a pretty powerful disk partitioning utility that comes free with Windows, can be used to manage hard disks when you lack a GUI or are a scripthead like me :). What is great about it is that it’s also included in WindowsPE which can make WinPE a one stop shop for disk management up to a certain point.

The steps we will go through are:

  1. Use Diskpart to list all system disks and select our USB stick
  2. Partition USB stick as desired and mark a specific partition as active
  3. Copy WindowsPE files to the USB stick

Select system drive for WinPE boot

First step is open up your command prompt running it as Administrator. Type diskpart at the prompt and hit enter. After a few seconds you get a command prompt headed by “DISKPART>”.

At the prompt type list disk – this will list all available physical drives. This next step is CRUCIAL. Pay extremely good attention to the information shown. The command will list the disks on your system. Identify which on the disks listed there is your USB stick, use the “Size” parameter to figure it out. If you are still not sure what type of disk you have selected do following:

select disk [enter #] <<enter a disk number from the listing you did>>
detail disk

The output should say your select disk is TYPE:USB. If you get TYPE:ATA, list the disks again and select another number!

DISKPART> detail disk

Disk ID: 2EA32EA2
Type   : USB
Status : Online
Path   : 0
Target : 0
LUN ID : 0
Location Path : UNAVAILABLE
Current Read-only State : No
Read-only  : No
Boot Disk  : No
Pagefile Disk  : No
Hibernation File Disk  : No
Crashdump Disk  : No
Clustered Disk  : No

 Volume ###  Ltr  Label        Fs     Type        Size     Status     Info
 ----------  ---  -----------  -----  ----------  -------  ---------  --------
 Volume 6     G                NTFS   Removable   7679 MB  Healthy

Repeat the “select disk #” and “detail disk” until you find your USB device that you wish to make bootable. To see which disk you selected run:

DISKPART> list disk

 Disk ###  Status         Size     Free     Dyn  Gpt
 --------  -------------  -------  -------  ---  ---
 Disk 0    Online          186 GB      0 B
* Disk 1    Online         7680 MB      0 B

Up to this point we’ve done nothing to the usb device, but I hope you have a backup /don’t care about the data on, because it will be gone in the next step…

Prepare disk and mark as active

With the proper selected disk we will wipe all partitioning data from it, create a single partition, format it as NTFS, give it a drive letter, and mark the partition as active.

!WARNING!: The following will wipe your device, so make sure the selected disk it is the correct one. (use list disk and look for the “*” to see which disk is selected)

create partition primary
format fs=NTFS quick
assign letter=U

All of these commands will echo a response that they ran successfully, once done type exit to leave the diskpart context and let’s copy the WinPE files to disk.

Copy Windows PE Files

Ok, time for a little linking to my previous posts (post1 and post2). In these posts I discussed how to make a Windows PE boot Disk. IF you followed that tutorial (or similar ones on the internet) you will probably be stuck with a folder called ISO in the <PATH>\WinPE_x86\ folder. Also you should left with the ISO file. BOTH of them are good for this next step which is “Copy all the files from either the ISO folder or the ISO IMAGE you built to the root of the USB partition” (make sure you copy all files and folders including hidden ones). Yep, It’s that easy 🙂

Once you are done safely remove the USB device from the PC and attempt to boot from it. It should plain and simple work (provided your bios can boot from USB disk and you configured it to boot from USB disk properly). If your ISO image was working your USB stick should also be working.

I hope this was helpful and if you have feedback it is always welcome.

How to create a Windows PE Disk (part 2)

It is time for part 2 of this guide to making yourself a Windows PE disk. You can read more about the first part here. This post we will cover following: how to integrate drivers, add 3rd party/applications/files to your image, unmount the image and burn it to an ISO file. I also want to say that this is a scripted approach, and all data and scripts are in the E:\PE path in this guide. The scripted approach will come in handy when you are doing tens of rebuilds of the image because a certain driver will not integrate, or a registry file modification does not work.

Integrate Drivers into WinPE Image

First thing on the agenda here is to get the actual drivers you want to integrate into the Image. For most use cases it is enough to integrate Storage and Network drivers, and perhaps Chipset drivers. You also need to take into account the WinPE version you are building, in this guide, we build a x86 WinPE Image so my focus was on x86 drivers for Windows 7/ 2008 /2008 R2. Now go out and grab those CD’s or vendor provided tools (Hyper-V Integration components or VMware Tools).

Some vendors ship other applications along with drivers, you don’t need the extra files most of the time, because WinPE doesn’t know how to use them most of the time. From the drivers in the list WinPE needs *.inf, *.cat and *.sys files corresponding to each driver you want to integrate and ANY other file specified in the *.inf file. Be patient with this process, as it can be sometimes painstaking and will cause you to rebuild your image until you get it right, until you find all the drivers and files you need 🙂

Let’s take the example of VMware Tools for vSphere. If you want your WinPE to boot into vSphere and be able to see your storage adapters and network cards you need to integrate the drivers from VMware Tools.

Step1: On a VM running Windows 2008/ Windows 7 on vSphere start an interactive VMwareTools Install.

Step2: Install your VMware Tools and reboot VM. Now take a look in %programfiles%\vmware\vmware tools\drivers\ – driver heaven! Copy the needed folders from here into a folder called “E:\PE\Drivers\ESX_40” (e:\PE is the location where we run our WinPE imaging process).

For other drivers you may need to take a different approach. I will just share from my experience. Drivers can be in *.cab cabinet files, in *.zip files, inside MSI files, which you kinda have to install to get to (see vmware tools case), even install a driver and then look in device manager where the device driver exists and search for a similarly named *.inf, sys and *.cat file and all the other files referenced in the *.inf file.

When you have all your drivers run this as administrator from a command prompt:

cd \
cd "%PROGRAMFILES%\windows aik\Tools\x86\Servicing"
DISM /image:e:\pe\winpe_x86\mount /Add-Driver /driver:e:\PE\Drivers\ /recurse

Here you run the DISM tool using /add-driver switch, /driver specifying where the drivers are located, and /recurse to make it look in all subfolders in e:\PE\Drivers. This is one of the sweetest things about the DISM, is that it can recursively search for drivers (in WinPE 2.0 you had to have 1 command per folder containing drivers).

The output of the command should look like this:

As you can see DISM searched the folder and found 84 drivers (inf files that he can integrate). I had 85 inf files inside that folder, one failed, and you see DISM threw and error. This is however just a “pre-flight” check, as there can still be errors during the actual integration:

As you can see in this screenshot, DISM could not integrate some of the drivers and pointed to the DISM log file. This file can be found in %WINDIR%\Logs\DISM\dism.log.

For those that just want to test their driver integration skip the next step.

Adding Custom Scripts/Applications to the Image

In an earlier post, I showed how to mount the WinPE Image. The Image was mounted under “E:\PE\winpe_x86\mount”. If you take a look in this folder you will notice a folder structure resembling a windows install…well that is exactly what it is – all Windows PE files unpacked, as they would look like if booted with the image. This means you can add files under %windir%\system32 of the image (in our case Windows\e:\pe\winpe_x86\mount\windows\System32) and you would be able to execute them as %windir%\system32 is in the %path% environment variable of the Windows OS. Note that not all apps run under Windows PE, sometimes it is a matter of trial and error.

So it is just a matter of copying the files you need from a path, let’s say “e:\PE\CustomApps\” to wherever you want in the folder structure “e:\PE\winpe_x86\mount\”. Use a manual copy or do an xcopy like this for example:

xcopy /y /r /F E:\PE\CustomApps E:\PE\winpe_x86\mount\Windows\System32

It is a little known fact about Windows PE that it has a batch file called “startnet.cmd”. This file includes a command “wpeinit”. wpeinit is an executable that is run when WindowsPE boots on your system (more info here). While I don’t care much about wpeinit itself, I do care about startnet.cmd. This file you can modify/overwrite at this point with a custom made startnet.cmd that can start other scripts, check IP connectivity anything you need to do with your WinPE boot disk. Similar to putting custom apps on WinPE you can do this:

xcopy /h /Y /R /F "E:\PE\CustomScripts\startnet.cmd" "E:\PE\winpe_x86\mount\Windows\System32\startnet.cmd"

I am stressing the importance of this file because, you can access it only at boot time and it is “hard-coded” into the WIM file (you cannot change it after you unmount the WIM and build the ISO afterwards). Therefore, since startnet.cmd cannot be altered after building the image, it could make sense to have startnet.cmd point to a file say, autorun.cmd, that you can put on the root of the ISO file for example. And there are many ISO editing tools,so changes to autorun.cmd are easier to make, for editing a WIM things are not so straightforward.

Still following this? Good, because the worst part is over 🙂

Unmount Image and burn to ISO

This last step is fairly easy. DISM has a parameter to unmount the image and commit the changes to the Image. If you remember in the beginning we copied boot.wim to winpe.wim. now we overwrite the existing boot.wim image with our serviced image. The commands below do just that:

cd "%PROGRAMFILES%\windows aik\Tools\x86\Servicing"
::commit changes to image and unmount
Dism.exe /Unmount-Wim /mountdir:E:\PE\winpe_x86\mount /commit
copy E:\PE\winpe_x86\winpe.wim e:\pe\winpe_x86\ISO\sources\boot.wim /Y

In the current state you have 2 options:

1. Copy the contents of the E:\pe\winpe_x86\iso folder to a bootable USB stick or make an iso file out of it. For now let’s focus on making a ISO file.

Microsoft delivered OSCDIMG with the WAIK, a utility that can create the bootable ISO for us.

cd \
cd "%PROGRAMFILES%\windows aik\Tools\x86"
::"-b" MUST BE next to path for
OSCDIMG -bE:\PE\winpe_x86\ -n -o E:\PE\winpe_x86\iso E:\PE\Current_ISO.iso

Please note the comment in the script, “feature” or bug you don’t need a space between -b and the etfsboot,com file.

This should have successfully built the image and you can burn it to a CD/mount it in a VM and enjoy a Microsoft Supported Windows 7 live CD :). Before you go take a mental break from all this reading I just want to point out that Windows PE will crash if you run it on a system with insufficient memory.

Why? The boot disk creates a Ramdisk where he loads Windows PE. If there is not enough RAM memory (typically you have this issue on old hardware or VM’s) it will crash and simply not load. As a rule of thumb the machine using it should have at least 1.8 -2.0 the size of the ISO file as RAM available on the machine.

I hope this was helpful for others looking to use WinPE as boot disk and I appreciate any feedback you may have.

Exchange 2007 Management Shell – Basics, Tips and Tricks

This first post i’d like to talk a little about Exchange 2007’s Management Shell. If you are already working with Exchange 2007, you must know by now that there has been a shift in how administration and management tasks are done. Microsoft introduced the Management Shell of Exchange as a Powershell Extension, and a lot of the GUI tasks are now done from the command line.

Powershell is Microsoft’s new (or maybe not so new, let’s just say latest , it has been with use for some years) extensible command shell interface. It is built on .NET Framework, so it may look more like a shell aimed at the programming savvy, but I think people that have really basic programming skills can handle it after some getting used to.

How to get it? Well assuming you have an Exchange 2007 server in your organization, you have it by default on the Exchange Servers. You can and should use the shell on the Exchange Servers [running scripts closest to the “managed entities” is always best IMO, you avoid adding additional Points of Failure] but you can also download the Exchange Management Tools for Exchange 2007 and install them on your own workstation, or a workstation you designate for management.

Ok, so now you have the tools installed. Unless you already found the link to the Exchange Management Shell on your start menu, you can start the tools by typing this in the run box.

%windir%\system32\windowspowershell\v1.0\powershell.exe -PSConsoleFile "%ProgramFiles%\Microsoft\Exchange Server\bin\exshell.psc1" -noexit -command ". '%ProgramFiles%\Microsoft\Exchange Server\bin\Exchange.ps1'"

You can probably use this in some scripted NT batch files, if you like. You will find some good information on Google about introductions to powershell, I won’t bore you with them. I’m going to assume you have the shell, have done some really light reading on the topic.

Here are some quick fixes for Powershell’s quirks though. You must have stumbled upon this at least once.

Ever ran an extended help command like the one below?

get-help Get-MailBox -full

Lots of lines scrolling, you couldn’t read a thing. It’s like one of those days you wish you were either in The Matrix or Startrek, so you can read the damn command-let help slowly or be an Android…or you could have not skipped the RTFM part of powershell, but if you’re like me, you did.

Worst part about this is that the powershell.exe line buffer is the same as the buffer of cmd.exe, so if the help is big enough, scrolling back up won’t give you a change to read all of the help.

How to Fix it? – Not to worry old NT batch and Powershell have the answer

Tip #1 – Using Powershell – For this I should have done the obvious, meaning taking a closer look at the output of:

get-help get-help (yes you can get-help on get-help)

There’s a little line that says there’s also the option of running, help [command] instead of get-help. You you try:

help get-mailbox -full

You get the equivalent of the /p switch on the NT batch, now that’s help for non Android people 🙂

Tip #2Oldschool, using NT batch you can redirect the output of help to a text file and read it at your leisure.

get-help Get-mailbox-full > c:\
notepad C:\

Which one is better?

Powershell method is quicker because you don’t have to notepad the text file and search for it there. However you cannot use the same method for cmd-let output [or may I have not figured out how, yet], basically reading the output of a cmd-let page by page.

For that you still have to do use the general method, in NT Batch redirect the output to a file and read that later on, like this for example:

get-excommand | select-object Type,Name | ft > c:\
notepad C:\

This should help anyone struggling with learning the Exchange shell syntax for referencing all of the cmd-let switches available.

Happy Scripting, hope this first post was not so bad.