Ransomware – Better get used to it


The reality is that Ransomware is here to stay. There is simply too much money involved for it to go away in the near term. Antivirus and technology companies do their best to keep up safe but new variants arrive almost everyday.

This means that you need to be extra vigilant. Be careful and don’t open documents from people you don’t know. Be very careful when downloading files when you are not sure who the author is. Keep your operating system, browser, and antivirus up to date on your computer and phone (yes your smartphone too). Don’t turn off UAC or run as an administrator just because it’s a little inconvenient from time to time. Most importantly have a good backup that has version control or one that you keep offline. The first thing Ransomware typically wants to do is delete all your backups.


One of the latest attacks just asks you to turn on macros.  For reference a document will never look like this just because your macros are off.


If you are not sure don’t open it. If you are worried it might be legitimate ask professional first. 

It’s much easier to tell you that it’s OK to open than to recover if it wasn’t. 

A location that is unavailable?? but it’s right there!!

I was asked to look into the error a client was receiving.  The user connected to a domain joined windows 2008 R2 server with an account that had local admin rights. Mapped a drive (M) to a file share browsed to a file and tried to copy it to the local D drive. He got the typical UAC prompts and then the following error message.


“M:\ refers to a location that is unavailable. It could be on a hard drive on this computer, or on a network. Check to make sure that the disk is properly inserted, or that you are connected to the Internet or your network, and then try again. If it still cannot be located, the information might have been moved to a different location.”



Some quick searches picked up lots of strange suggestions more than a few suggesting you just disable UAC and move on.  (Don’t do that) If you want to understand what actually happening read on, if not skip to the end….

When you logon to a system with UAC you get a split token at logon. You may have the option to elevate to admin rights but typically you are working away happily with normal user rights.

The secret here is to think of this split token almost like to separate sessions in this case, and here is the proof.

Logon and map a drive, then open a command prompt and do a “net use” to see the mapped drive.


Now at the same time run a command prompt as an administrator and do the same thing. Note Administrator in the title bar.

No mapped drive….

You start to copy a file using explorer.exe (running in your normal user process) you right-click on a file or folder in the mapped drive and select copy. (so far so good)

Now you go to a UAC protected location like the root of a drive, in this case D:\ and right-click paste. (everything still working just fine)

Now you get a UAC prompt and approve the move to the Administrator token.

The copy now tries to complete moving the file or folder you previously copied (m:\whatever.txt) but of course now that you are under the admin token M:\ doesn’t exist and the copy fails.



1) Create a folder and copy there. If it’s not UNC protected this is not an issue

2) Use a UNC instead of a mapped drive – Because this does not use a drive letter the copy does not fail.

3) Map the drive under your admin token as well and the copy will work.



I have found this issue happens even when logged on via RDP as a local administrator in this instance, but aside from that  this is a good explanation of whats going on. Regardless of the specifics you can use the above technique to see if this is causing your specific problem.

This could be an issue in a number of scenarios wherever you have a combination of UAC  and mapped drives so don’t worry too much about the OS version etc just try the test and see for yourself if you have this kind of error.




Death of a Hotfix – Fun with KB973705

Ever have one of those days when the help desk calls you early and says EVERYTHING IS DOWN!!

We all know that it’s very rarely that bad, but either way you see your day evaporate.  For me yesterday was one of those times.

The Problem: Perhaps 50% of our machines that received MSKB973705 last night can’t run outlook anymore. a quick look shows that the outlook.exe is smaller, does not have a version number anymore and if you run it from the command line you get “Program too big to fit in memory”. Quickly we declined this update in WSUS to prevent the spread and then it’s on to fixing the problem machines.

 The Process: After some research and a call to Microsoft the recommendation is to remove the patch only from affected machines at least until the developers can have a look at it and determine whats really going wrong here. Sounds simple right?

First we need to determine who has the patch, I found the base of the following vbscript from Hey, Scripting Guy (skip to the end for the whole script)

Set colQuickFixes = objWMIService.ExecQuery _
(“Select * from Win32_QuickFixEngineering where HotFixID = ‘KB973507′”)

This will at least tell us if the patch is installed. If so we need a quick check to see what version is on the outlook as most people appear to have received the patch without issue.

dim filesys, a
    Set filesys = CreateObject(“Scripting.FileSystemObject”)
    a = filesys.GetFileVersion(“C:\Program Files\Microsoft Office\OFFICE11\OUTLOOK.EXE”)

If the patch is installed and the outlook version is bad then we need to uninstall the patch using this script I hoped to just use the .uninstall() method of the Win32_QuickFixEngineering object. Sigh, this is not an option. It is an option for the Win32_Product Class but not the  Win32_QuickFixEngineering Class

After much research, , trolling the registry, google and newsgroups we finally found how a patch like this needs to be uninstalled from the command line. I can’t count the number of times I chased down a solution that looked so easy that I couldn’t believe I missed it earlier, only to find again I was looking at KB973507 and not KB973705 … Dyslexics Of The World Untie

msiexec /package {} /uninstall {} /passive /norestart”

now all we need is the product and package GUIDS, these will of course vary based on the version of Office you have installed and the patch in question).

In order to get the product GUID I found the following script WiLstPrd.vbs that gives us the Product ID, the patch ID I just found by going into Add or Remove Programs, finding the patch and clicking to get the support information.


Finally this give us  the command that actually removes the patch:

“msiexec /package {90110409-6000-11D3-8CFE-0150048383C9} /uninstall {22A15D5A-3165-4970-86BE-A5D5661E77E1} /passive /norestart”

We also find that following the uninstall of this patch some machines pick it up from the WSUS cache even though we have declined it in the console for now, so we add a “wuauclt -detectnow” to force the clients to check in with WSUS before trying to install the same patch again.

 Of course when we start testing we find that we have a number of different states

Users who have installed and patch and rebooted  – Script works

Users who have installed but not rebooted – – patch uninstall appears to work but after a reboot leaves the client in a bad state requiring that outlook be repaired from the control panel. Because of this we added a section to the script to see if the machine has been rebooted today, if not we prompt to reboot and then run the script again.

Users who have not installed the patches – script runs as expected but does not do anything

Users who have attempted to fix it themselves – isn’t it fun when this happens? we will just have to fix any of these by hand as we find them.

A few more updates to the script to do some logging and report via email on it’s usage and we are ready to deploy. We have a discussion about the pros and cons of deploying via SCCM, log-on script, GPO, user run or help desk run. We found some issues with SCCM not wanting to run the script a second time if the initial reboot is required. We decide that with out help desk assistance if required for the initial push and see what happens.

The Solution:

Have the users run the following script: (keep in mind this was a quick and dirty script, but if you see things that could be better let me know)

Download : Script

Download : User Documentation

See the alternate Script from GregP at the bottom of this post.


After seeing the logs for a few hundred users I have made a few change, like requiring that a reboot has happened in the last hour or the script will not run, and notifying the user to call the help desk if they are still having problems and the script things everything is OK.

Hey Microsoft:

Before you start, yes I know about Microsoft Connect, and I use it. I also work with my TAM at our expense to try and argue for product improvements. I suggest everyone does the same.

1) How about some standardization on patch uninstallation? I found 3 different ways for 3 different kinds of patches.

2) How about making the uninstall simple? something like you already do for some things… “C:\WINDOWS\$NtUninstallKB975025$\spuninst”

3) How about adding the Product GUID in the technical details for EVERYTHING that is installed under add remove programs.  And would it kill you if  we could cut and paste from there?

The Script :

‘—– Logging constant : 0 = off, 1 = to screen, 2 = to file, 3 = to screen and file
const conLogType = 2
const conLogPath = “c:\”
const conScriptName = “OutlookFix973705-“
Const conClearLog = 0
Const conDisplayLog = 0
Dim username,intFirstRun
Dim strLogFileName

Set objFSO = CreateObject(“Scripting.FileSystemObject”)

logmsg “*************** OutlookFix973705 Started. *****************”

Set WshNetwork = WScript.CreateObject(“WScript.Network”)
logmsg “on Computer Name = ” & WshNetwork.ComputerName
strComputer = “.”
Set objWMIService = GetObject(“winmgmts:” _
& “{impersonationLevel=impersonate}!\\” & strComputer & “\root\cimv2”)

Set colOperatingSystems = objWMIService.ExecQuery (“Select * from Win32_OperatingSystem”)
For Each objOS in colOperatingSystems
    dtmBootup = objOS.LastBootUpTime
    dtmLastBootupTime = WMIDateStringToDate(dtmBootup)
    dtmSystemUptime = DateDiff(“h”, dtmLastBootUpTime, Now)
    logmsg “Last boot time: ” & dtmLastBootupTime
    logmsg “bootup: ” &dtmBootup
    logmsg “Uptime: “& dtmSystemUptime
Function WMIDateStringToDate(dtmBootup)
    WMIDateStringToDate = CDate(Mid(dtmBootup, 5, 2) & “/” & Mid(dtmBootup, 7, 2) & “/” & Left(dtmBootup, 4) & ” ” & Mid (dtmBootup, 9, 2) & “:” & Mid(dtmBootup, 11, 2) & “:” & Mid(dtmBootup, 13, 2))
end function
If dtmLastBootupTime < “14/10/2009” then
 logmsg “reboot required before script runs”
 msgbox “Please reboot and run the script again”
end if

Set colQuickFixes = objWMIService.ExecQuery _
(“Select * from Win32_QuickFixEngineering where HotFixID = ‘KB973507′”)

logmsg “WMI Query Complete”

For Each objQuickFix in colQuickFixes
  if objQuickFix.HotFixID = “KB973507” then
    dim filesys, a
    Set filesys = CreateObject(“Scripting.FileSystemObject”)
    a = filesys.GetFileVersion(“C:\Program Files\Microsoft Office\OFFICE11\OUTLOOK.EXE”)
   if a<>”” then
  logmsg “outlook version appears to be good, patch not removed”
   end if
   if a=”” then
      logmsg “uninstall started”
      set objShell = wscript.createObject(“wscript.shell”)
      objShell.Run “msiexec /package {90110409-6000-11D3-8CFE-0150048383C9} /uninstall {22A15D5A-3165-4970-86BE-A5D5661E77E1} /passive /norestart”
      Set objNet = Nothing     �
    end if
 end if
      set objShell = wscript.createObject(“wscript.shell”)
      objShell.Run “wuauclt -detectnow”
      Set objNet = Nothing     �
logmsg “wuaudetect now started”
logmsg “script end”

‘ Procedure  : LogMsg

Sub LogMsg (strMsg)

dim objWshShell, objFileSystem
dim intLogFile
dim strTemp

 Select Case conLogType
  Case 0
  Case 1
   Set objWshShell = WScript.CreateObject(“WScript.Shell”)
   wscript.echo Now & ” – ” & strMsg
      Set objWshShell = NOTHING
  Case 2
   Set objFileSystem = CreateObject(“Scripting.FileSystemObject”)
   strTemp = Now()
   strTemp = Day(strTemp) & Month(strTemp) & Year(strTemp)
   strLogFileName = conLogPath & conScriptName & strTemp & UserName & “.log”
   If conClearLog = 1 and intFirstRun = 1 Then
    If objFileSystem.FileExists(strLogFileName) then
    End If
    intFirstRun = 0
   End if  �
   Set intLogFile = objFileSystem.OpenTextFile(strLogFileName,8,true)
   intLogFile.WriteLine(Now & ” – ” & strMsg)
   set intLogFile = NOTHING
   set objFileSystem = NOTHING
  Case 3
   Set objFileSystem = CreateObject(“Scripting.FileSystemObject”)
   strTemp = Now()
   strTemp = Day(strTemp) & Month(strTemp) & Right(Year(strTemp),2)
   strLogFileName = conLogPath & conScriptName & strTemp & username & “.log”
   If conClearLog = 1 and intFirstRun = 1 Then
    If objFileSystem.FileExists(strLogFileName) then
    End If
    intFirstRun = 0
   End if
   Set intLogFile = objFileSystem.OpenTextFile(strLogFileName,8,true)
   intLogFile.WriteLine(Now & ” – ” & strMsg)
   wscript.echo   Now & ” – ” & strMsg
   set intLogFile = NOTHING
   set objFileSystem = NOTHING
 end Select
End Sub
Function GetUserName

dim objWshShell, objWshSysEnv

 Set objWshShell = CreateObject(“WScript.Shell”)
 Set objWshSysEnv = objWshShell.Environment(“PROCESS”)

 GetUserName = objWshSysEnv(“USERNAME”)
 ‘logmsg “Username: ” &Getusername
 Set objWshShell = Nothing
 Set objWshSysEnv = Nothing

End Function

Sub SendMail
Set objMessage = CreateObject(“CDO.Message”)
objMessage.Subject = “Outlook Fix run for: ” & username & ” ” & now() & ” on ” & WshNetwork.ComputerName
objMessage.From = “outlookfix@WHATEVER.COM
objMessage.TextBody = “”
strTemp = Day(strTemp) & Month(strTemp) & Right(Year(strTemp),2)
strLogFileName = conLogPath & conScriptName & strTemp & UserName & “.log”
logmsg strlogfilename
objMessage.AddAttachment strlogfilename

‘==This section provides the configuration information for the remote SMTP server.
‘==Normally you will only change the server name or IP.
objMessage.Configuration.Fields.Item _
(“http://schemas.microsoft.com/cdo/configuration/sendusing“) = 2

‘Name or IP of Remote SMTP Server
objMessage.Configuration.Fields.Item _
(“http://schemas.microsoft.com/cdo/configuration/smtpserver“) = “YOUR MAIL SERVER IP HERE “

‘Server port (typically 25)
objMessage.Configuration.Fields.Item _
(“http://schemas.microsoft.com/cdo/configuration/smtpserverport“) = 25


‘==End remote SMTP server configuration section==

end sub

 Alternate Script:

GregP commented with this option, no VBS. I have not tried it but I like the concept. Thanks Greg for the details.

REM Get patch date.
for /f “skip=4 tokens=1,2,3,4″ %%A in (‘reg query HKLM\Software\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\9040110900063D11C8EF10054038389C\Patches\A5D51A225613079468EB5A5D66E1771E /v Installed’) do set PatchDate=%%C

if “%PatchDate%”==”” exitREM Get last boot date.

net statistics workstation > %Temp%\NetStats.txt
for /f “tokens=1,2,3,4,5 delims=/ ” %%A in (%Temp%\NetStats.txt) do if /i “%%A”==”Statistics” (if %%C LSS 10 (set BootM=0%%C) else (set BootM=%%C))
for /f “tokens=1,2,3,4,5 delims=/ ” %%A in (%Temp%\NetStats.txt) do if /i “%%A”==”Statistics” (if %%D LSS 10 (set BootD=0%%D) else (set BootD=%%D))
for /f “tokens=1,2,3,4,5 delims=/ ” %%A in (%Temp%\NetStats.txt) do if /i “%%A”==”Statistics” set BootY=%%E
set BootDate=%BootY%%BootM%%BootD%

REM UnPatch or No UnPatch?
if %PatchDate% LSS %BootDate% msiexec /package {90110409-6000-11D3-8CFE-0150048383C9} /uninstall {22A15D5A-3165-4970-86BE-A5D5661E77E1} /quiet /norestart

REM Cleanup.
for %%V in (PatchDate BootM BootD BootY BootDate) do set %%V=
del %Temp%\NetStats.txt