Another way of checking whether a reboot is pending

posted Jan 5, 2016, 7:04 PM by Bryan Lockwood   [ updated Jan 6, 2016, 9:21 AM ]

While working on PSWU, I discovered that this PowerShell method of checking for a pending reboot will not work remotely:

$sb = {
    $NeedsReboot = $false
    $SystemInfo= New-Object -ComObject "Microsoft.Update.SystemInfo"
    if ($SystemInfo.RebootRequired) {$NeedsReboot = $true}
Invoke-Command -ComputerName REMOTEPC -ScriptBlock $sb

The code above will return a subtly deceptive error:  Exception from HRESULT: 0x80070005 (E_ACCESSDENIED).  For awhile I assumed this was equivalent to an 0xC0000008 "Access Denied" error, as is typically returned when filesystem or registry permissions do not allow access to an object. But in this case the "E_ACCESSDENIED" error means that whatever your access privs (even SYSTEM), you cannot access the COM object method or property from a remote system. See the result codes shown here for example. And this is indeed documented, though easily missed. 

So I needed another way of checking whether Windows Update (WU)  had left the PC in a 'pending reboot' state. With a hint from this MSDN blog, and some investigation using Process Monitor and RegEdit, I was able to discover a couple of registry keys to check for:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired

In my limited testing on a Windows 8.1 system, both keys existed when WU was calling for a reboot, and neither key existed when it was not. That means the following PowerShell code can remotely check for a reboot pending due to Windows Updates:

$sb = {
    $NeedsReboot = $false
    $WURegKey = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired"
    $CBSRegkey = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending"
    if (test-path $WURegKey) {$NeedsReboot = $true}
    if (test-path $CBSRegkey) {$NeedsReboot = $true}
Invoke-Command -ComputerName REMOTEPC -ScriptBlock $sb

If the remote PC is pending reboot due to WU, this will return True. If not, False.


Auditing Your Root Certificates

posted Feb 24, 2015, 4:33 PM by Bryan Lockwood   [ updated Mar 20, 2015, 9:24 PM ]

If you're paying attention to recent security events, you've probably heard about the SuperFish incidentSynopsis: a large PC maker (Lenovo) were selling PCs with pre-installed bundleware called Superfish VisualDiscovery. That software installs a self-signed root HTTPS certificate. Together with a builtin web proxy, this allows the Superfish software to act as a man in the middle for some or all secure HTTP communications the PC is involved in. Further, the self-signed certificate was improperly secured, making it possible for third parties to hijack secure HTTP communications. And finally, the Superfish software broke the PC's ability to validate certificates on visited websites.

Synopsis of the synopsis: if you bought a PC with Superfish installed on it, any hacker within wireless range of your PC could hijack your online banking transactions. 

Some certs on my PC
Bad stuff all around. I hope this forces PC builders everywhere to re-think their bundleware policies, and maybe even stop the practice altogether. Paul Thurrott thinks this stuff "
destroys the Windows experience" and I gotta say, it's a very strong point. But I will leave the editorializing to others, and get to my point.

This incident made me wonder: how can we verify that our computers are using trustworthy certificates? When I open the Certificates Console (certlm) on my PC, I find 59 "Trusted Root Certification Authorities", and another 50 "Third Party Root Certification Authorities". Root certs are the keys to the kingdom; they're the ones used to validate all other more specific certs in use. 

So I should probably have an idea of how trustworthy all these root certs are. But with 109 of them to work through ... where should I start? 

This post at Ars Technica called my attention to Jason Fossen's work at SANS. Jason suggests starting with the root certs that Microsoft trusts enough to distribute with Windows. Microsoft are careful with their trust, granting it only to root CAs who submit to yearly audits of their practices. Included in Jason's article is a script for checking which of the root certs installed on your Windows PC are trusted by Microsoft.  Jason's script needs a list of root certificate thumbprints. Microsoft provides their list of Windows Root CA Members on this web page - but the list is in PDF format, and Jason's script can't read PDF.

So I have extracted all 443 thumbprints from the document. I've also refactored Jason's script to be a bit more readable.
  • Sept2014-WindowsRootCAList.txt (the list of 443 root certs Windows will trust)
  • Audit-TrustedRootCAv2.ps1  (my refactored version of Jason's script)
  • Both of the above files are now on GitHub. Feel free to help me improve them!
Download them both to a directory and run the script. If it finds root certs that aren't on Microsoft's trust list, it will notify you.  

Keys get lost
I found four such certs on my system. Three of them were named BryanPC, which happens to be the name of my computer.   They didn't contain any other clues about their purpose. One was named "localhost" but also identified itself with a Friendly Name: "Skype Click to Call". 

So here's the problem. Since these are root certificates, and they're not on Microsoft's list, I have no way to verify anything about them. The one identifying itself with Skype may or may not actually come from Skype. With nothing else to check, I have four choices:
  1. Leave the certificate in place, and hope it's never used for evil.
  2. Delete the certificate and hope that this doesn't cause me problems later on.
  3. Export the certificate to a file, then delete it. This way, if a problem occurs later, I can re-import the certificate and (hopefully!) solve the problem.
  4. Leave the certificate in the store, but disable it. If a problem occurs, I can quickly re-enable the certificate.
I tried exporting and then re-importing a couple of certificates, but I notice that in doing so, I lose the keys associated with them, as shown in screenshot at right. So I decided that the safest and easiest thing to do is disable the certificates I can't clearly identify.

Here's how I did that:
  1. Invoke the Start Menu (or Start Screen) and type "certlm.msc". Click to run it.
  2. In the CertLM console, navigate to the suspect certificate. It will be under "Trusted Root Certification Authorities" or "Third-Party Root Certification Authorities."
  3. Double-click the suspect certificate, then click on the Details tab. Then click the Edit Properties button.
    Getting ready to disable a certificate

  4. In the resulting dialog box, change the radio button to "Disable all purposes for this certificate"
    Disabling the cert

  5. Click OK to enact your change. You can click OK to exit the other dialog box as well.

PSWU - PowerShell Windows Updater

posted Feb 23, 2015, 3:05 PM by Bryan Lockwood   [ updated Feb 23, 2015, 3:15 PM ]

Installing a new copy of Windows from scratch is a drag. The OS itself installs in less than a half hour. But then you start slogging through updates. It goes like this:

  1. Start Windows Update
  2. Click "check for updates" and wait a minute or two
  3. Select everything, click the "Install Updates" button. 
  4. Wait 1-100 minutes (depending on your internet connection and the size & number of updates)
  5.  Answer any dialogs that pop up. 
  6. Reboot if prompted to. 
  7. Repeat this process until no more updates are available. 
This update process can take hours to complete, and you have to babysit the whole thing. It should be automated! And now it is, because I've written a PowerShell script called PSWU to babysit the process.

With PSWU, the update process can still take hours - I haven't found any way to substantially speed up the download and installation of updates. But you don't have to babysit; you just start the script and walk away. PSWU handles the drudgery.

Using PSWU
  1. Download PSWU.ps1 (you don't need anything else), saving it wherever you like.
    • For this guide, I'll put it in my Documents folder: c:\users\bryan\documents\pswu.ps1
  2. Start an elevated PowerShell console or ISE.
  3. Unblock the script with the command:
    • unblock-file c:\users\bryan\documents\pswu.ps1
    • (Substitute your own path, of course.)
  4. If you haven't already done so, set your Powershell execution policy to allow running scripts:
    • Set-ExecutionPolicy Unrestricted
  5. Run PSWU:
    • c:\users\bryan\documents\pswu.ps1
    • If you have any unsaved work on the PC, save and close it. PSWU will reboot the system as necessary.
  6. PSWU will start checking for and downloading updates.
    • This process may take minutes or hours, depending on your bandwidth and the number of updates the system needs.
    • All actions will be logged to the file PSWU.log which is placed on the desktop.
    • PSWU may reboot the system multiple times.
    • When done, PSWU will place a file named DONE UPDATING on the desktop. 
I welcome your feedback.

Reputation Pie

posted Feb 10, 2015, 1:10 AM by Bryan Lockwood   [ updated Feb 10, 2015, 1:15 AM ]

A couple of days ago, I wrote this article, which had its problems, but I'm still highly interested this whole code-signing phenomenon. Developers pay good money for code-signing certificates, and they expend effort to sign the applications they distribute. From the end-user's point of view, that developer effort boils down to what you see when UAC pops up:
UAC dialog for unsigned executable. Note the yellow top.
UAC dialog for signed executable. Note the blue top.
An unsigned executable produces a yellow topped UAC dialog. A signed executable produces a blue topped UAC dialog.

While some people may notice the difference, I suspect that the great majority have no idea what the difference means. So they probably treat both UAC dialogs the same way: as a button that must be clicked in order to get on with life. Hopefully some people consider this a time to think, if only for a second, about whether they trust the maker of whatever program they just invoked. And if you don't know who made your software, how can you trust it?

Still, my point is this: developers spend money, time, and effort on code-signing, and it seems that we should be able to get more benefit out of their outlay. We should be able to audit our computers (and all of their installed applications) using code-signing to answer questions like:
  • How many executables on my PC come from unknown sources?
  • Who made each of the executables on my PC?
    • Are they still in business?
    • Are they well known?
    • Do I trust them?
  • How many of the executables on my PC have been modified, so they aren't the same ones their maker distributes?
  • How many of the executables on my PC require elevation to run?
  • Knowing all of the above, how much can I really trust my PC?
What if we could have a tool that would audit our PCs, taking these factors into account, and returning something like the 'reputation pie' I mocked up here? Suppose then you could click on each slice and get the names or makers of all files in that slice, and from here, take actions (like removing unsigned programs) that make your computer more verifiably trustworthy?

Get-AuthenticodeSignature ... doesn't

posted Feb 9, 2015, 11:46 PM by Bryan Lockwood   [ updated Feb 10, 2015, 1:27 AM ]

When I wrote the original version of my article Code signing is important, I was pretty hot and bothered. At the time I thought that about half of the executable files found in a new installation of Windows had no code-signing certificates, and thus could  be easily tampered with. 

I have since learned that there two ways to add Authenticode signatures to a file or group of files. The first is to embed the Authenticode signature directly into a file. It works with:
  • "Portable Executable" (PE) files (.exe, .dll, .sys, and .ocx). 
  • Cabinet files (.cab).
  • Windows Installer (.msi and .msp). 
These are known as embedded signatures. This method is documented here, and discussed in detail by Eric Lawrence here. Get-AuthenticodeSignature works great with embedded signatures.

But there are many filetypes which don't have provisions for embedded signatures, so here is another way to use Authenticode: catalog files. One or more files are hashed, and the hashes collected into a catalog (.cat) file. The catalog is then cryptographically signed with an Authenticode certificate. What little I know about catalog signing comes from Microsoft's 2007 Code Signing Best Practices document. 

The Get-AuthenticodeSignature cmdlet seems to be entirely unaware of catalog signing. It has absolutely no provision for detecting catalog-signed files. So it treats a catalog file as though it has no signature at all. Have a look at this screenshot:

Get-AuthenticodeSignature and SignTool, checking the same file.

Here I check the powershell.exe file with Get-AuthenticodeSignature which returns a status of NotSigned. Then I check it again with signtool.exe from the Windows SDK. SignTool detects the catalog signature and successfully verifies it. I then run signtool again, with its /v switch, to show more details. The verbose output is quite detailed, so I have truncated it here. 

So that explains why I thought half of the executables delivered with Windows were unsigned. I was naively assuming that the Get-AuthenticodeSignature cmdlet, introduced in PowerShell version 3, would detect all Authenticode signatures. That's just not true. Since well over half of Authenticode-signed files use catalogs rather than embedded signatures, this makes the output of Get-AuthenticodeSignature about as useful as flipping a coin. You can trust a "Valid" response. But a "NotSigned" response is very likely to be wrong.

I've reported this behavior to Microsoft as a bug. If you also think it's a bug worthy of fixing, go to my report and upvote it. 

Powershell Compatibility Matrix

posted Jan 14, 2015, 7:37 PM by Bryan Lockwood   [ updated Jan 14, 2015, 7:41 PM ]

For a project I'm working on, I needed to construct this Powershell compatibility matrix. Couldn't find one on the web, so I'm dropping a copy here.

PS v2 PS v3 PS v4 PS v5
Distributed in KB968930 WMF 3.0 WMF 4.0 WMF 5 Preview
XP SP3 Installable NA NA NA
Vista Default NA NA NA
Windows 7 SP1 Default Installable Installable NA
Windows Server 2008 SP2 Installable Installable NA NA
Windows Server 2008 R2 SP1 Default Installable Installable NA
Windows 8 ~ Default NA (upgrade to 8.1) NA
Windows 8.1 ~ ~ Default Installable
Windows Server 2012 ~ Default Installable Installable
Windows Server 2012R2 ~ ~ Default Installable
Windows 10 ~ ~ ~ Default


posted Dec 31, 2014, 4:15 PM by Bryan Lockwood   [ updated Jan 15, 2015, 10:12 AM ]

You've heard of PowerShell, right?

Me too. I remember seeing Jeff Snover's first Channel 9 demo of Monad, way back in 2004, and being highly impressed. I became a PowerShell cheerleader then and there. Then PowerShell v1 released in 2006 ... it could be manually installed on XP and Windows Server 2003. Later, it came preinstalled on Vista and Windows Server 2008. And I was still cheerleading for it. I've never stopped, really.

But I have to admit, I didn't really go all-in on PowerShell until just a few months ago. Out of habit and inertia, the bad old cmd console remained as my go-to CLI environment. I could write out a bunch of excuses for that, but let's not waste time. Instead, I'm just going to share the two main resources I used to finally pull myself over the hump:
These are both broken out into shorter sessions, so you can nibble off a little bit each day. Actually, I think they've taken a lot of their material and structure from these books:
Speaking of books - often I want/need more than a YaBinGle search delivers. I like to learn not just how to work a thing, but all the little details of how that thing works. That's why I've added these three books to my library:
These helped a lot. But really, I needed to just grit my teeth and commit to the change. So I resolved to close my ever-present cmd console, and instead keep the PowerShell ISE always open. And to spend at least 60 seconds trying to do each CLI task the PowerShell way, rather than the cmd way. After a week of that, I really took the plunge - I resolved to write a script to automate all those Windows Updates one has to do after installing a new copy of Windows. You'll be hearing more about that in the near future.

I'm really glad I (finally!) pushed myself over the hump on this. If you haven't done it yet ... well. 2015 starts tomorrow. 

Bug in Disk Space Fan?

posted Oct 15, 2014, 2:06 AM by Bryan Lockwood   [ updated Oct 15, 2014, 2:41 AM ]

For a very long time, I recommended Steffen Gerlach's Scanner as a quick and easy way to visualize disk contents, and find large space hogging files and directories. Personally I like these radial layouts far better than what you get with the far more popular WinDirStat. Somehow, radial/pie charts just line up better with the way my mind works. And Scanner was and is blazing fast!

Somewhere along the line, I got a little worried about Scanner - I never saw any evidence of it being updated, and I never saw any changes in Mr. Gerlach's site. I guess I just got worried that it was getting stale. So, I began using and recommending the free edition of Disk Space Fan instead.

Until today, that is. If you take a close look at the screenshot in this article, you can see that both Scanner and Disk Space Fan are analyzing the same disk (a USB-attached Zalman VE-300 enclosure, carrying a WD Scorpio 500GB drive). But they give drastically different results. Disk Space Fan (on the left) shows the drive using 173GB; Scanner shows the drive using 368GB (on the right).  

Scanner gives the correct results; Disk Space Fan (DSF) is oblivious to 195GB of files on the disk. That's a HUGE error on DSF's part, and I do not know what causes it. It seems to be randomly ignoring some files, which are not marked hidden, have no special permissions. Two directories I examined more closely were full of .iso files; DSF saw some of them, ignored others. File size didn't seem to matter; it missed both big files and smaller files.

So, I'm back to using and recommending Gerlach's Scanner. Sorry I ever doubted you, Steffen!

Rebooting the site

posted Oct 15, 2014, 1:38 AM by Bryan Lockwood   [ updated Oct 15, 2014, 2:40 AM ]

I've left this site lying fallow for, ohmigosh, 3+ years now. It's way past time I got back to work on it. 

Won't bore you with promises or a list of changes I've made or am planning to make. 

Let's just see what happens!

1-9 of 9