Contact

Subscribe via Email

Subscribe via RSS

Categories

Recent Posts

Creative Commons Attribution 4.0 International License
© Rakhesh Sasidharan

Windows Services – Fix unquoted path vulnerabilities using PowerShell

At work as part of some security certification we are running Nessus scans on all our systems and it came up with the following vulnerability – link. Read that link, it’s good info.

Basically if one of your Windows Service entries point to (say) “C:\Windows\Microsoft.NET\Framework64\v3.0\Windows Communication Foundation\SMSvcHost.exe” without the double quotes then one could potentially create a malicious file called Windows.exe at “C:\Windows\Microsoft.NET\Framework64\v3.0\Windows” and Windows will execute that file instead of parsing the full path and treating it as part of a folder name. That’s because Windows uses space as a delimiter between a command and its switches & arguments and so it could treat the entry as “C:\Windows\Microsoft.NET\Framework64\v3.0\Windows.exe” with arguments “Communication Foundation\SMSvcHost.exe“.

The solution for this is to find all such entries that contain a space, and if the path is not in double quotes then make it so. You have to do this in the registry, so you could either do it manually or make a script and do it en masse. I went the latter route so here’s something I created.

I am being lazy and not really offering input etc as I just expect a list of servers to be scanned in a file called “ServerNames.txt”. I have the above saved to a .ps1 file and I simply run it as .\Registry.ps1. Feel free to adapt to your needs.

What it does is that it connects to the server specified (provided they are online), tries to open the “services” key under HKLM (assuming it has access), and then enumerates all the subkeys that contain the service names and checks if the path has a space. It only matches against paths containing a .exe so it could miss out some stuff. Once it finds a match it extracts the bit up to the .exe, splits it along any spaces, and if there are more than one results (which means the path did have spaces) it encloses it in double quotes and replaces the original entry.

The code is smart enough to know it must correctly double quote something like "D:\Program Files (x86)\BigHand\BigHand Workflow Server 4.6\BHServer.exe /V:4.6" as "D:\Program Files (x86)\BigHand\BigHand Workflow Server 4.6\BHServer.exe" /V:4.6 and not "D:\Program Files (x86)\BigHand\BigHand Workflow Server 4.6\BHServer.exe /V:4.6".

By default it only displays results. An optional parameter -FixIt will also make the changes.

Example output:

Hope it helps!

PowerShell – List of machines with CPU and disk info

Had to come up with a list of machines and their CPU, disk info etc. Thought it better to make a small script for it.

Hope it helps someone.

Use PowerShell to get a list of GPOs without Authenticated Users in the delegation

Must have seen this recent Windows update that broke GPOs which were missing the Read permission for the “Authenticated Users” group. Solution is to get a list of these GPOs and add the “Authenticated Users” group to them. Here’s a one liner that gets you such a list –

This puts it into a file called GPOs.txt in the current directory. Remove/ Modify that last re-direct as needed.

Get a list of services and “Log On As” accounts

Wanted to find what account our NetBackup service is running under on a bunch of servers –

You have to use WMI for this coz Get-Service doesn’t show the Log On As user.

Wheee!! Had a tweet from Jeffrey Snover for this post.

 

 

Following on that tweet I noticed something odd.

The following command works –

Or this –

In the second one I am explicitly casting the arguments as an array.

But this variant doesn’t work –

That generates the following error –

Get-WmiObject : The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)
At line:1 char:1
+ Get-WmiObject Win32_Service -cn $Servers -Filter ‘Name= “NetBackup Client Service …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Get-WmiObject], COMException
    + FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

Get-WmiObject : The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)
At line:1 char:1
+ Get-WmiObject Win32_Service -cn $Servers  -Filter ‘Name= “NetBackup Client Service …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Get-WmiObject], COMException
    + FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

The error is generated for each entry in the array.

It looks like when I pass the list of servers as an array variable PowerShell uses a different way to connect to each server (PowerShell remoting/ WinRM) while if I specify the list in-line it behaves differently. I didn’t search much on this but found this Reddit thread with the same issue. Something to keep in mind …

 

Configure NTP for multiple ESXi hosts

Following on my previous post I wanted to set NTP servers for my ESX servers and also start the service & allow firewall exceptions. Here’s what I did –

 

PowerShell Remoting Security links

Just some links I found on PowerShell remoting security –

Create multiple DNS records using PowerShell

I had to create multiple A DNS records of the format below –

Just 9 records, I could create them manually, but I thought let’s try and create en-mass using PowerShell. If you are on Windows Server 2012 and above, you have PowerShell cmdlets for DNS.

So I did the following –

To confirm they are created, the following helps –

Nice!

Find out which DCs in your domain have the DHCP service enabled

Use PowerShell –

Result is a table of DC names and the status of the “DHCP Server” service. If the service isn’t installed (i.e. the feature isn’t enabled) you get a blank.

Quickly get the last boot up time of a remote Windows machine

PowerShell:

Command Prompt/ WMI:

Double quotes are important for the WMI method.

PowerShell regexp match with lines above and below

Wasn’t aware of this until today when I needed to do this. The Select-String cmdlet in PowerShell can select strings based on a regexp (similar to findstr in regular command prompt) with the added benefit that it can also return context. Which is to say you can return the line that matches your pattern and also lines above or below it. Pretty cool!

In my case I needed to scan the output of portqry.exe and also get the UUIDs of the lines that match. These UUIDs are shown on the line above so I did something like this:

The -Context 1,0 switch is the key here. The first number tells the cmdlet how many lines before to show, the second number how many lines after.

Get a list of OUs with inheritance blocked & GPOs not applied

To get a list of OUs and the status of GPO inheritance:

To get a list of OUs that have GPO inheritance blocked:

To get a list of OUs that have GPO inheritance blocked and a don’t have a particular GPO applied to them directly:

There’s probably a better way to do this, but this is the best I could come up with …

User PowerShell/ PowerCLI to get VM space usage

Wanted to get the space used by all VMs across a bunch of our newer hosts –

There’s probably a way to show the total too but I used a separate pipeline for that –

 

Get a list of users in an OU along with last logged on date

Trivial stuff. Wanted to note it down someplace for future reference –

 

Start-BitsTransfer does nothing

I had to copy some VMware templates from our head office to the branch offices. Thought I’d copy them out of the datastores manually, then do a BITS transfer to the remote offices. This way I can do the transfer during normal hours but with minimal user impact.

Since PowerShell 2.0 you had the Start-BitsTransfer cmdlet to do BITS transfers.

Oddly however, the command would just exit without any error for me. And it didn’t seem to be doing anything. Then I realized I was pointing the cmdlet to my source folder and that’s why it was failing! Start-BitsTransfer only takes files. You can specify wildcards to select multiple files but you can’t point it to a folder.

So the following doesn’t work:

But this works:

Since Start-BitsTransfer supports wildcards it’s mostly fine unless your folder contains sub-folders and you want to copy these and/ or preserve the structure. Fortunately this is PowerShell so it’s just a matter of creating some wrappers around the cmdlet to support folders too. Like this one for instance. Or use CSV files like in this MSDN article.

One thing to keep in mind – by default Start-BitsTransfer has a default priority (specified via the -Priority switch) of Foreground. This competes with other applications so is probably not what you want. You alternatives are High, Normal, or Low – each of which does the transfer in the background and uses the idle bandwidth of the client for transfer (the priority determines which transfer job gets priority over the other similar BITS transfers).

Another thing to keep in mind is that BITS only really looks at the bandwidth availability of the client (when I say “client” I am not sure if it’s the sender or receiver – I didn’t read much into this). In a LAN environment it could be the case that the WAN side is saturated but the particular client you are targeting is idle – in this case BITS will use the full client bandwidth available to it even though the network itself doesn’t have any spare bandwidth (this was the case prior to BITS 2.0 but since then BITS can use an Internet Gateway Device to try and assess the bandwidth availability on the WAN side – this requires an IGD be find-able via UPnP and also that the Internet Gateway Device support such reporting, so I am not sure how well it works in practice). You can also use GPOs to control BITS bandwidth usage.

Anyhoo, this is not a BITS intro so I’ll leave it at that. :)

Once you start a BITS transfer you can also pause it via Suspend-BitsTransfer or cancel it via Remove-BitsTransfer. The latter will also delete any files that are already transferred, so if you just want to cancel but leave the transferred files as it is use Complete-BitsTransfer instead.

That’s all for now!

p.s. Almost forgot. You can also use BITS to download HTTP files. Like in this post for instance.

PowerCLI – List all VMs in a cluster along with number of snapshots and space usage

More as a note to myself than anyone else, here’s a quick and dirty way to list all the VMs in a cluster with the number of snapshots, the used space, and the provisioned space. Yes you could get this information from the GUI but I like PowerShell and am trying to spend more time with PowerCLI.