Archive for the ‘Security’ Category

h1

Scripted Microsoft Patch Removal

September 19, 2011

Many patch management systems have the ability to uninstall previously deployed patches. This functionality is typically used when a conflict with the patch is discovered after deployment.

Unfortunately, many of the automated removal mechanisms depend on the patch developer supporting and including a patch removal mechanism for each patch. When a patch doesn’t support this functionality, the management platform falls short in supporting this function.

As a workaround, here are a couple of scripts that will provide a semi-automated approach that can be used to remove patches remotely.

First, this script will list the patches installed on a system in the past X days where X is a command line parameter:


#Get list of patched installed in the past X days
param($Argument1,$Argument2)

$ComputerName = $Argument1
$intDays = $Argument2
$bolDaysValid = $true

#Validate second paramter – must be a number between 1 and 1000
If ([Microsoft.VisualBasic.Information]::isnumeric($intDays)) {
    If ($intDays -lt 1 -or $intDays -gt 1000) {$bolDaysvalid = $false }
    else {$bolDaysValid = $true}
}
else {
    $bolDaysValid = $false
}

If ($bolDaysValid -eq $false) {
    write-host "Invalid days parameter. Please use a number between 1 and 1000."
    write-host "Example: .\PatchList.ps1 mycomputer 30"
    write-host "Exiting"
    Exit
}

#Validate first paramter – WMI call to get OS
$OS = Get-WmiObject -Class win32_OperatingSystem -namespace "root\CIMV2" -ComputerName $computerName -ErrorAction silentlycontinue
if ($OS -eq $NULL) {
    write-host "Can’t access computer $ComputerName. Exiting."
Exit
}
#Get list of updates
Get-WmiObject -Computername $ComputerName Win32_QuickFixEngineering | ? {$_.InstalledOn} | where { (Get-date($_.Installedon)) -gt (get-date).adddays(-$intDays) }


Then, once the research is complete and the offending patch is found, the following script can be used to remotely remove the patch.


param($Argument1,$Argument2)
Add-Type -AssemblyName Microsoft.VisualBasic

$computername=$Argument1
$hotfixid=[string]$Argument2

#Second paramter validation – make sure it starts with ‘KB’ followed by a number
If (-not (($hotfixid.substring(0,2) -eq "KB") -and ([Microsoft.VisualBasic.Information]::isnumeric($hotfixid.substring(2))))) {
write-host "Invalid hotfix parameter. Please use ‘KB’ and the article number."
write-host "Example: .\PatchRemove.ps1 mycomputer KB976432"
write-host "Exiting"
Exit
}

#First paramter validation – get OS to be used later. If call fails, bad parameter
$OS = Get-WmiObject -Class win32_OperatingSystem -namespace "root\CIMV2" -ComputerName $computerName -ErrorAction silentlycontinue
if ($OS -eq $NULL) {
write-host "Can’t access computer $ComputerName. Exiting."
Exit
}
#Get hotfix list from target computer
$hotfixes = Get-WmiObject -ComputerName $computername -Class Win32_QuickFixEngineering |select hotfixid           

#Search for requested hotfix
if($hotfixes -match $hotfixID) {
    $hotfixNum = $HotfixID.Replace("KB","")
    Write-host "Found the hotfix KB " $HotfixNum
    Write-Host "Uninstalling the hotfix"
    #Windows 2008/R2 use WUSA to uninstall patch
    if ($OS.Version -like "6*") {
        $UninstallString = "cmd.exe /c wusa.exe /uninstall /KB:$hotfixNum /quiet /norestart"
          $strProcess = "wusa"
    }
    #Windows 2003 use spuninst in $NTuninstall folder to uninstall patch
    elseif ($OS.Version -like "5*") {
        $colFiles = Get-WMIObject -ComputerName $computername -Class CIM_DataFile -Filter "Name=`"C:\\Windows\\`$NtUninstall$HotFixID`$\\spuninst\\spuninst.exe`""
        if ($colfiles.FileName -eq $NULL) {
        Write-Host "Could not find removal script, please remove the hotfix manually."
        }
        else {
            $UninstallString = "C:\Windows\`$NtUninstallKB$hotfixNum`$\spuninst\spuninst.exe /quiet /z"
              $strProcess = "spuninst"
        }
    }
    #Send removal command
    ([WMICLASS]"\\$computername\ROOT\CIMV2:win32_process").Create($UninstallString) | out-null           
    #Wait for removal to finish
    while (@(Get-Process $strProcess -computername $computername -ErrorAction SilentlyContinue).Count -ne 0) {
        Start-Sleep 3
        Write-Host "Waiting for update removal to finish …"
    }
    #Test removal by getting hotfix list again
    $afterhotfixes = Get-WmiObject -ComputerName $computername -Class Win32_QuickFixEngineering |select hotfixid           
    if($afterhotfixes -match $hotfixID) {
        write-host "Uninstallation of $hotfixID succeeded"
    }
    else {
        write-host "Uninstallation of $hotfixID failed"
    }
}
else {           
    write-host "Hotfix $hotfixID not found"
return
}           


Note that these scripts are tested on servers running Windows 2003 or later.

h1

Windows VPN Client and local DNS resolution

August 25, 2011

Typically when configuring a remote access VPN, the goal is for DNS requests to be resolved by DNS servers on the remote/server side of the VPN connection.

This is either because the connection is from a less trusted network to a more trusted one – i.e. from home to office, and so split tunnels are not allowed. Even if split tunnels are allowed, the local client network is typically less complex and can use broadcast name resolution while the remote network is complex so using it requires DNS.

Since this is the predominant configuration, this is how most VPN clients are configured and many, including the Windows VPN client, do not offer an option to change this configuration.

In some cases, however, it makes sense for DNS resolution to remain local to the client side of the VPN connection. This is useful when the connection is from a more trusted and complex network to a less trusted and complex network. For example, a connection from the office network to a lab network or to a home network, would benefit from keeping DNS resolution on the client side of the connection.

I ran into this problem trying to configure a connection to my lab that would allow me to keep the connection open while working on the office network.

Unfortunately, this isn’t easy to do this with the VPN client that is included in Windows Vista/7 (The VPN client with Windows XP had an issue that resulted in a side effect with this exact configuration). While Windows does allow configuring the binding order to different interfaces using the ‘Advanced Settings’ menu option in the ‘Network Connections’ control panel, changing the binding order for ‘[Remote Access Connections]’ doesn’t seem to have any impact.

The binding order is stored in the registry in the following location: HKLM\System\CurrentControlSet\Services\Tcpip\Linkage\Bind. The list includes all the device GUIDs for network adapters and active connections in the binding priority order.

When working with the registry key, the following facts emerge:

  • Changing the order of the GUIDs in the registry does impact the binding order, including for VPN connections
  • Any changes to the key take effect immediately
  • When a VPN connection is completed, the GUID for the connection is added to the top of the bind order if it does not already exist
  • When a VPN connection is closed, the GUID entry for the connection is removed
  • If there are multiple GUID entries for the connection, only one is removed when the connection is closed

This mechanism creates the possibility of the following workaround:

  1. Examine the Bind registry key
  2. Connect to your VPN connection
  3. Check the Bind key again and copy the GUID that was added to the top of the list
  4. Paste the GUID entry at the bottom of the list 20 times
  5. Export the key and clean up the exported file to only include the bind key

The result is a key that will support the desired behavior. Every time a VPN connection is established, since the GUID is present, it will not be added. Since the GUID is at the bottom, DNS resolution will be done locally to the client. When the connection is disconnected, one GUID entry will be removed. After 20 VPN connections, the exported registry file can be used to reimport the key.

Of course, you can paste the GUID more times to reduce how often you have to reimport the key.

Also important to remember to redo this procedure if there are any changes to network adapters.

h1

Publishing Exchange 2010 with TMG

August 15, 2011

Part III: Redirection (virtual directory and SSL)

Typically when users want to access Outlook Web App (OWA), they are unlikely to type the correct URL: https://webmail.domain.com/owa or /exchange. In order to accommodate common URL combinations that users may enter, commonly using HTTP instead of HTTPS and omitting the virtual directory name, we can employ redirection.

To this end, there are two types of redirection:

The first redirects HTTP traffic to HTTPS and is very easy to accomplish in a TMG environment. If you refer to the previous post, you will see a configuration step for the web listener that accomplishes this function. In the ‘Connections’ tab for the listener, HTTP connections are allowed and redirected to HTTPS. Nice and easy.

The second form of redirection help redirect URLs that reference the root of the web site, i.e. https://webmail.domain.com , to the correct virtual directory. In an Exchange 2007/2010 environment, the destination should be https://webmail.domain.com/owa. If coexistence with legacy versions  (Exchange 2003) is needed, the destination will be https://webmail.domain.com/exchange.

In either case, we will use the ‘HTTP redirection’ feature of IIS 7.5 to configure the required setting using the following process on each CAS server:

  1. Open IIS Manager and navigate to the Default Web Site
  2. Open the HTTP Redirect feature and configure the following options:
  • Redirect all requests to this destination: https://webmail.domain.com/owa
  • Redirect all requests to exact destination: unchecked
  • Only redirect requests to content in this directory: checked
  • Status code: Found (302)

While those are the required settings for the web site, settings these configuration options will automatically set the same options on any sub folders and virtual directories that do not currently have redirection configured. Since we only want the redirection on the web site, we need to remove the redirection from all sub folders.

This process results in a problem: there are three directories that do need to be redirected and those are ‘/Exchange’, ‘/Exchweb’ and ‘/Public’. These three virtual directories must be redirected to ‘/owa’ in order for the OWA service to function correctly.

The problem is evident right after turning off redirection on the ‘/owa’ virtual directory using the UI – this change also disables redirection on the three folders listed above. If you re-enable redirection on any of the three, it will also re-enable redirection on ‘/owa’. This confusing and frustrating loop creates a series of unusable configurations that aren’t simple to correct.

The problem occurs because once the settings are configured using the UI, they are stored in the web.config file for the virtual directory and the four directories discussed all share a single web.config file. If the settings are configured using appcmd.exe the information is stored elsewhere (presumably in the metabase) and the problem is resolved.

The process to correct the issue is as follows:

  1. Remove the HttpRedirect section from the web.config file for /owa.
  2. Use the following commands to configure the correct settings for all folders:

cd %windir%\system32\inetsrv
appcmd set config “Default Web Site/Exchange” /section:httpredirect /enabled:true -commit:apphost
appcmd set config “Default Web Site/Exchweb” /section:httpredirect /enabled:true -commit:apphost
appcmd set config “Default Web Site/Public” /section:httpredirect /enabled:true -commit:apphost

appcmd set config “Default Web Site/owa” /section:httpredirect /enabled:false -commit:apphost

Finally, while you are configuring virtual directories on each CAS server, confirm that the authentication settings are set to Basic Authentication for all of the virtual directories – OWA, ECP, ActiveSync, and Outlook anywhere (configured on the properties of the CAS server). I recommend viewing and making changes to these settings through the Exchange Management Console or Shell.

That should be all that’s needed. The results of following the instructions in all 3 posts of this series are an Exchange 2010 system published with TMG using a single public IP address and a seamless user experience.

A big thanks and credit for various aspects of this post go to a couple of colleagues at Convergent Computing for helping discover, test and document this information. Thank you Yasu SabaLin and Aman Ayaz.

Hope this is helpful and as always please post any comments or questions

Follow

Get every new post delivered to your Inbox.