Tag Archives: security

Preventing Petya ransomware with Group Policy

This post and this twitter thread describe a mechanism to prevent the latest ransomware cyber attack from running. It involves creating 1 (or 3) files with a specific name(s) and with the Read-only attribute set. Although the instructions on the first post describe copying and renaming notepad.exe, any file, even an empty file, with the correct names and the Read-only attribute will suffice, if I read the twitter thread correctly.

There are numerous ways to accomplish this in a large organization, including an SCCM package that either deploys some files, or that runs a script to create the files. However, I decided to use Group Policy File Preferences to copy a small text file to the three filenames described, including setting the Read-only attribute.

Using Group Policy File Preferences to create the files that will block the Petya (NotPetya) Ransomware.

This should be executed on the affected computers at their next GP refresh, which might be sooner than a reboot for a start-up script.

PowerShell Script: New-RandomString.ps1

I need to automate the setting of passwords on some Active Directory accounts. Since resetting passwords is also a task that I’m asked to perform with some routine, I decided to make a more generic tool script that could be used in a variety of tasks ( I listened to Don Jones‘ advice on building Tools and Controllers).

I also got a head start from Bill Stewart’s useful Windows IT Pro article Generating Random Passwords in PowerShell.  Among the changes I made are source character class handling, and a new SecureString output option. Please let me know if you find the script useful, or if you find any bugs.

Generates one or more randomized strings containing specified
character classes.

The length of the string to be generated.

.PARAMETER CharacterClasses
An array of Character Classes from which to generate the string. The string
will contain at least one character from each specificied class. You may also use the alias 'Classes' for the parameter name

Valid Character classes are:

    Upper    - A..Z
    Lower    - a..z
    Digits   - 0..9
    AlphaNum - shorthand for Upper,Lower,Digits
    Symbols  - !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
    Safe     - #$%+-./:=\_~  (ODBC Safe, Shell Safe if quoted)

If no classes are specified, a string is generated with mixed-case letters,
digits, and symbol characters (i.e., ALL the classes).

.PARAMETER IncludeCharacters
A string of characters to include in the generated string:

.PARAMETER ExcludeCharacters
A string a characters to exclude in the generated string:

The number of strings to be generated.

.PARAMETER AsSecureString
Specifies that the new random string(s) will be returned as Secure String
objects, to make their use as passwords easier.

> New-RandomString.ps1 -CharacterClasses Lower,Digits -Length 14 -Count 5
Generated five strings, each fourteen characters long, comprised of lowercase
letters and digits.

> New-RandomString.ps1 -Classes AlphaNum,Symbols -length 21
> New-RandomString.ps1 -length 21

The previous two commands are equivalent, because the default character classes
used are upper and lowercase letters, digits, and symbol characters.

> New-RandomString.ps1 -Class 'AlphaNum' -Include '#$%^'

The generated string will contain characters from the UpperCase, LowerCase
and Digits classes, as well as at least one character from among the four

> New-RandomString.ps1 -Class 'AlphaNum' -Exclude 'O0l1'

The generated string will contain characters from the UpperCase, LowerCase
and Digits classes, but will not contain the "look-alike' characters.

Author     : Geoff Duke <Geoffrey.Duke@uvm.edu>
Last Edit  : 2014-11-07 

Based on script "Get-RandomString.ps1" for Windows IT Pro:


#Requires -version 3

        $length = 21,

        $count = 1,

        $CharacterClasses = @('Upper','Lower','Digits','Symbols'),

        $IncludeCharacters = '',

        $ExcludeCharacters = '',



Set-StrictMode -version 'Latest'

# Additional parameter wrangling
# --------------------------------------------------------------------
[string[]] $Classes = $CharacterClasses.ToLower()

if ( $Classes.Contains('safe') -and $Classes.Contains('symbols') ) {
    write-warning 'You specified both "Symbols" and "Safe" character classes; this is the same as just specifying "Symbols".'
    $Classes = $Classes | where { $_ -ne 'safe' }

# Replace alphanum with the upper,lower, and digits classes
if ( $Classes.Contains('alphanum') ) {
    $Classes = $Classes | where { $_ -ne 'alphanum' }
    $Classes += 'upper','lower','digits'

# remove any duplicated classes
$Classes = $Classes | select -unique

# Setup source characters
# -------------------------------------------------------------------- 

# Character classes - functionally, a strongly-typed hash of string arrays
#       (addresses issue of singleton arrays turning into simple strings)
$chars = New-Object 'Collections.Generic.Dictionary[string,char[]]'

$chars['lower']    =  97..122 | foreach-object { [Char] $_ }
$chars['upper']    =  65..90  | foreach-object { [Char] $_ }
$chars['digits']   =  48..57  | foreach-object { [Char] $_ }
$chars['symbols']  = (33..47+58..64+91..96+123..126) | foreach-object { [Char] $_ }
$chars['safe']     = '#$%+-./:=\_~'.ToCharArray()

write-verbose $( 'String must include a character from each of ' +
              $( $Classes -join ',' ) +
              $( if ( $IncludeCharacters ) { " plus [$IncludeCharacters] " } ) +
              $( if ( $ExcludeCharacters ) {
                  "but must not include any of [$ExcludeCharacters]" } ) )

if ( $IncludeCharacters ) {
    $Classes += 'include'
    $chars['include'] = $IncludeCharacters.ToCharArray()

[char[]] $char_source  = $chars[ $Classes ] | % { $_ } | select -unique

if ( $ExcludeCharacters ) {
    $char_source = $char_source | Where { $_ -NotIn $ExcludeCharacters.ToCharArray() }

write-verbose "Source chars: $(-join $char_source)"

# Generating the random string(s)
# --------------------------------------------------------------------
$string_count = 0
:NewString while ( $string_count -lt $Count )  {

    $output = ''
    for ( $i=0; $i -lt $length; $i++) {
        $output += get-random @($char_source)
    write-debug "NewString: generated string is -> $output"

    # Ensure that the requested character classes are present
    :CharClass foreach ($class in $Classes) {
        foreach ( $char in $output.ToCharArray() ) {
            if ( $chars[$class] -Ccontains $char ) {
                write-debug "CharClass: '$char' is in $class"
                continue CharClass # check the next character class
        } # end foreach $char, didn't match the current character class
        write-debug "CharClass: No character from $class! Start again"
        continue NewString # Need to generate a new string
    } # end foreach #class

    # string matches required character classes"

    if ( $AsSecureString ) {
        ConvertTo-SecureString $output -AsPlainText -Force
    else {
} # end while

It was while I was writing this script that I ran into the Loop Label documentation error. In PowerShell, as in Perl, Loop Labels do not include the colon when used with a break or continue statement.

Remote Desktop Gateway

In order to connect to the Remote Desktop service on centrally managed servers from off campus, as well as some more sensitive servers from on campus, you need to use the Remote Desktop Gateway feature.

For the current Remote Desktop Client on Windows, you can configure this option by going to the Advanced Options tab, and then click the Settings button.

Remote Desktop Gateway settings

On the RD Gateway Server Settings window that open, select the second option, Use these RD Gateway server settings. The server name is rdgateway.uvm.edu, and chose the Ask for password option.

Click OK, and you should be able to connect using the RD Gateway service. For more information about RD Gateway, see What is a Remote Desktop Gateway server?



Renewing Tomcat SSL certificates

Following Greg’s advice, as well as the Tomcat docs here are the steps I’ve performed to update the SSL certificates used by two Tomcat instances:

  1. Backup the existing keystore file, just in case..
  2. Generate a new certificate, with new alias
    E:\Tomcat\conf> %java_home%\bin\keytool -genkey -keystore mytomcatserver.keystore -storepass ############ -alias tomcat2013 -keyalg RSA -keysize 2048  -dname "CN=mytomcatserver.uvm.edu, OU=Enterprise Technology Services, O=University of Vermont, L=Burlington, ST=VT, C=US" -validity 730
  3. Create a certificate signing request for that cert
    E:\Tomcat\conf> %java_home%\bin\keytool -certreq -keystore mytomcatserver.keystore -storepass ############ -keyalg RSA -alias tomcat2013 -file mytomcatserver.csr
  4. process the CSR with our CA

Now, there are two options for importing the certificate, and I’m not sure if there are implications for the difference:

  1. Import the rootCA cert first, then the intermediate CA, then the actual server
  2. Import the three certificates together as a chained cert. The order of the certificates in the certificate file appears significant; our signing authority provides the chained cert with the RootCA first, which hides the other certs from the Windows cert viewer, among other things.

To import the chained cert (ordered with the host cert, interm. cert, then rootCA cert):

E:\Tomcat\conf> %java_home%\bin\keytool -import -keystore mytomcatserver.keystore -storepass ############ -alias tomcat2013 -file mytomcatserver_uvm_edu.cer -trustcacerts

Now, we need to update the tomcat server.xml so that the keyalias attribute references our new certificate’s alias. Then, when the tomcat process is cycled, it should use the new cert.

Scripting printer permissions

I will probably need to refer to this myself, but maybe someone else will find this useful.

Still working through some print queue management tasks, I needed to change permissions on a collection of printers. Yesterday, I broke down and did a bunch of repetitive work in the GUI, and noticed there were some inconsistencies in the permissions applied to a clients print queues. Today, I decided that I would fix them, but I didn’t want to use the GUI.

Although the Server 2012 Printer Management Set-Printer cmdlet can change the permissions through its -PermissionSDDL parameter, I haven’t found a workable (even if you call SDDL workable) way to do so on a Server 2008 system.

So I fell back to using PowerShell with Helge Klein’s SetACL command-line tool. I could also have used his COM version if I wanted to be really efficient. I use an array of arguments to the external command. See this Scripting Guy post for more info on calling external commands.

Here’s what I did:

# Retrieve a list of target printers
PS C:> $rlprinters = gwmi Win32_Printer -filter "Name like 'RL -%' OR Name like 'RL-%' "

# Construct a list of printer names in \\[hostname]\[sharename] format
PS C:> $printers = $rlprinters | % { '\\' + $_.SystemName + '\' + $_.ShareName }

# Create some variables to make the command construction simpler
PS C:> $setacl = 'C:\local\bin\SetACL.exe'
PS C:> $group = 'DOMAIN\RL-PrinterGroup'

# Iterate through the list of printers, calling SetACL for each
PS C:> foreach ( $p in $printers ) {
>> & $setacl '-on', $p , '-ot', 'prn', '-actn', 'ace','-ace',"n:$group;p:full"

It worked like a champ.

Note that I needed to run an elevated PowerShell session (run as Administrator) to be able to make the changes. Also, I tested this on a single printer before attempting to make bulk changes. I also have a nightly dump of my printer configuration. You get the idea.

You can include multiple actions for each invocation of SetACL, and there are a number of ways to collect output in case you need to follow-up on problems when applying changes to large collections of printers. Hopefully, this is enough to get you started,

HoW PGP Whole Disk Encryption Works

In my discussion and demo at the IT-Discuss Live – Security event in May, I used a short slide deck to describe—in broad terms—how PGP Whole Disk Encryption works. This laid the foundation for working through some common-ish support scenarios.


Having received several requests for a copy of the slides, here they are, in both PowerPoint (.pptx) and PDF formats.

How to catch a phish

I’ve received several phishing attempts, recently, this time masquerading as mail from Twitter. I thought I’d share how I recognized this as an attack. Many list members already know this stuff, but I thought I’d share since we still see folks responding to these kinds of attacks.


1. Unexpected

Before I even looked at the content of the message, I was suspicious because I don’t have any twitter stuff associated with my UVM email. I could have deleted the message then and, if I was using twitter, logged into my twitter account directly to see if something was going on.

But I wondered how the message was crafted, so I opened it with awareness.


2. False link

A false link is shows a web address in the message, but the link that is attached to it is different. Below, my mail program shows that the link will actually send me to pachitanglangbarcelona.com.


Continue reading

NetApp and Microsoft Security Updates

When the recent SMB 2.0 vulnerability was announced, there was some discussion on the Toasters mailing list about whether Data ONTAP was affected. Val Bercovici from NetApp responded that Data ONTAP was not affected by this issue.

Today, I discovered that to enable the filer snapshots to be visible within the Previous Versions facility within Windows 7 (or Server 2008 R2), I needed to enable SMB 2.0. I spent some time search on NetApp’s support site for some assurance that the SMB issue didn’t affect ONTAP, but didn’t find anything.

So I sent Mr. Bercovici an email asking if there was a more official statement about ONTAP and SMB 2.0, and he very kindly looked sent me a link to the Windows File Services (CIFS) Compatibility Matrix – Microsoft Security Update Test Report. [requires NOW account]

This document rocks. It lists the Microsoft Security updates, by month, and the result of NetApp’s testing. Exactly what I was looking for. Thanks, Val.