Have You Been Pwned by CVE-2014-6324/MS14-068?

In case you haven't heard, there is a critical [Windows implementation of] Kerberos bug that you need to be updating, right now.

More information on the vulnerability can be found here.

In the "Detection Guidance" section of the above blog post, you will see that you can detect if the vulnerability has been exploited on an unpatched machine by analyzing the Security event logs. Specifically, looking at Event ID 4624 logon events, and taking note that the "Security ID" and "Account Name" fields in that event description match.  If they don't, chances are high that you have been a victim of a privilege escalation attack.

I whipped up a detection script to check all the domain controllers:

#Requires -Module ActiveDirectory
Set-StrictMode -Version Latest
Get-Job | Remove-Job -Force
[String]$DomainName = $(Get-ADDomain).Name
$DCs = $(Get-ADDomain).ReplicaDirectoryServers

:NextDC Foreach ($DC In $DCs)
    Start-Job -ScriptBlock {
        [Int]$PotentialMS14068s = 0
        Write-Output "Fetching Security event log from $DC."
            $Events = Get-EventLog -LogName Security -InstanceId 4624 -ComputerName $DC -ErrorAction Stop
            Write-Error "An error occurred while reading event log from $DC.`r`n$($_.Exception.Message)"

        :NextEvent Foreach ($Event In $Events)
            $MessageLines  = $Event.Message -Split [Environment]::NewLine
            [String]$SecurityID    = [String]::Empty
            [String]$AccountName   = [String]::Empty
            [String]$AccountDomain = [String]::Empty

            # Server 2012 Format
            If ($MessageLines[13].Trim() -Like 'Security ID:*')
                $SecurityID    = ($MessageLines[13].Trim() -Split ':')[1].Trim()
                $AccountName   = ($MessageLines[14].Trim() -Split ':')[1].Trim()
                $AccountDomain = ($MessageLines[15].Trim() -Split ':')[1].Trim() 
            # Server 2008 R2 Format
            If ($MessageLines[11].Trim() -Like 'Security ID:*')
                $SecurityID    = ($MessageLines[11].Trim() -Split ':')[1].Trim()
                $AccountName   = ($MessageLines[12].Trim() -Split ':')[1].Trim()
                $AccountDomain = ($MessageLines[13].Trim() -Split ':')[1].Trim()

            If (($SecurityID -EQ [String]::Empty) -OR ($AccountName -EQ [String]::Empty) -OR ($AccountDomain -EQ [String]::Empty))
                Write-Error "Event log message format unrecognized on $DC!"
                $Event | Format-List
                Break NextEvent

            If ($AccountDomain -Like $DomainName -And $SecurityID -NotLike 'S-1-5-18')
                $SID = New-Object System.Security.Principal.SecurityIdentifier($SecurityID)
                $Username = $SID.Translate([System.Security.Principal.NTAccount])        
                If ($Username -Like '*\*')
                    $Username = ($Username -Split '\\')[-1]
                If ($Username -Like '*@*')
                    $Username = ($Username -Split '@')[0]
                If ($Username -NE $AccountName)
                    $Event | Format-List
        Write-Output "Finished with $DC. $PotentialMS14068s interesting events found."
    } -ArgumentList $DC

While ($(Get-Job -State Running).Count -GT 0)
    Get-Job -State Completed | Receive-Job   
    Start-Sleep -Seconds 10 

The script uses Powershell jobs to achieve some parallelism, because if you have more than one or two domain controllers in your environment, this quickly becomes a Herculean, time-consuming task.  The script will display potential security event log events that may indicate exploits currently being used in your environment.

Windows Server Technical Preview: Soft Reboot

Windows Server Technical Preview Desktop

Microsoft's technical preview of the next version of Windows Server has been out for a month or two now.  (Go download it, what are you waiting for?)  Is it Windows Server 10?  Server 2015?  I suppose they could try to get away from naming it altogether and just call it "Windows Server," to signify that they only plan on evolving the platform incrementally from now on, rather than using the traditional punctuated equilibrium of boxed product releases that we're used to... that's for Microsoft to know and for us to find out.


One of the fun things about public CTP releases is that the thorough documentation always comes last... so we download these tech previews, and we see all these new features, and a lot of them are not well documented, if they're documented at all.  And that makes them great blog fodder.  So let us begin a journey through these poorly-documented features, starting with a new feature called Soft Restart.

The promise of this simple feature is to allow server administrators to restart or reboot the Windows operating system on a physical computer, without having to wait through the long and annoying process of the machine's POST, initializing RAID controllers, out-of-band management devices, network adapters, etc.  On some physical server hardware, this process can take several minutes just to come back from a reboot.

However, on a virtual machine, this feature is not likely to save you much time, however, since the virtualized/synthetic/emulated devices on VMs don't typically have those long initialization procedures anyway.

You can install the Soft Restart feature via the GUI:

Soft Restart via GUI

Or by my preferred method, Powershell:

PS C:\> Install-WindowsFeature Soft-Restart -Restart

Installing the feature requires a reboot.

So, one thing you'll notice in the new Windows Server that we did not have before, is a new parameter - /soft - for the shutdown.exe program:

shutdown.exe soft restart

However, I find it interesting that this new parameter exists, and works, with or without the new Soft Restart feature actually being installed!

There is also a new Powershell equivalent: Restart-Computer -Soft. This also appears to work regardless of whether the Soft Restart feature is actually installed or not... but this may be because I only have the tech preview on virtual machines right now.  It could be a different story if I were playing on physical hardware.

Modifying Permissions on Windows Services Pt I

I'm going to jot down some quick notes on modifying the permissions on Windows services, because I don't think I have written anything about it here before.

Many times, we find ourselves wanting to delegate some administrative activity on a server to another admin or group of admins, but we don't want to give them full administrative control over the entire server.  We need to delegate only specific activity.  For example, we might want to give our delegated users the right to stop, start and restart only a specific Windows service.  Modifying the ACL on a Windows service is a little more involved than modifying the ACL on a file or folder, though.

You can do this with Group Policy if it's a domain-joined machine.

Group Policy System Services

If the computer is not domain joined or if you only want to do this with the local security policy of one or two computers, you can also accomplish this task using Security Templates on the local computer:

Local Security Templates

You can also use the sc.exe utility:

sc sdshow and sc sdset

The sc sdshow servicename command displays the access control list of the Windows service, in SDDL (security descriptor definition language) format.

The SDDL string looks crazy at first, but it’s pretty simple after you analyze it for a second. There is a D: part, and an S: part. The D: part stands for Discretionary ACL. This is what we usually think of when we think of an ACL on a file, etc. The S: part is the system ACL that is used for things like object access auditing, and is not usually modified as much or thought about as much as the DACL.

With the second command, I am setting the new ACL on the service with sc sdset. I have inserted one Access Control Entry into the D: part of the ACL, before the S: part. The SID I specified is of a non-administrative user. I would recommend creating a security group called “IIS Delegated Administrators” or something like that, and using the SID of that security group. I have granted that account the RP, WP, and DT privileges. (Start service, stop service, and pause service.)  The A stands for Allow, as opposed to a Deny ACE.  And different types of objects such as services, files, MSDTC components, etc., all have slightly different rights strings.  In other words, the "RP" right means something different for a Directory Service object than it does for a Windows service.  Here are the rights strings for Windows services:














You can find a lot more here.

NTHashTickler_CUDA v1.0

I've ported my NTHashTickler program to NVIDIA CUDA... poorly.

As before, my motivation for writing this program is not because I really care about finding NT hashes per se, but just teaching myself more about multithreaded programming and in this case, NVIDIA CUDA. If you know anything at all about CUDA, please feel free to criticize my work and tell me what I'm doing wrong. (Source code is on Github.)



So CUDA is basically like standard C, but with a few extensions.  The challenge is that you have "host" code, and you have "device" code comingling, with host code only being able to run on your CPU and access your main memory, while "device" code can only run on your GPU and only access GPU memory.  What this means is that you are totally on your own when you're writing device code to run on your GPU. You can't even use C standard library functions like memcmp or strtol, etc.  And you definitely cannot call something as luxurious as a Windows API function from device code. The sole exception as far as I know is that CUDA does allow you to use printf from within device code for debugging purposes...

Traditionally, you could only transfer data from the host to the device through CUDA API calls such as cudaMalloc, etc., but in CUDA compute capability 3.0 they introduced what I like to call "CUDA Easy-Mode," or essentially, variables that can be seamlessly accessed by both host and device simultaneously, making your code look a lot cleaner and simpler.  These are the __device__ __managed__ variables.  They provide what CUDA calls a "unified" view of memory.  I'm guessing it's probably just the CUDA runtime doing the dirty work for you under the hood that you used to have to do yourself.  You can still cause the same kind of problems reading and writing to the variables from different threads that applies to any multithreaded code, but it's still so much easier to work with than cudaMalloc, cudaFree, etc.

So the idea is that if you have a problem that can be parallelized sufficiently, it can take advantage of your GPU's ability to run thousands of parallel threads, instead of your CPU's mere 4 or 8 simultaneous threads.

In practice though, when I finally got the code working, I get about 750,000 hashes per second of throughput, which is slower than the ~ 5 million hashes/second of throughput by my previous version in C that just ran on the CPU!

So I'm definitely doing something wrong.  I think I should be seeing a billion hashes/sec of throughput or better.  I have a lot more work to do.

Luckily, the CUDA Toolkit comes with some really amazing profiling and tracing tools, and I think that's a good place to start looking for optimization opportunities.

(Source code is on Github.)

Supersymmetry Outlook Add-In v1.1.3.17

You can see the original Supersymmetry 1.0 post here.

The Supersymmetry Outlook Add-In has been upgraded to version  (Similarity to "31337" or "1337" is coincidental!) But this release is significantly cooler than 1.0 anyway.

In case you're not familiar, the purpose of the Supersymmetry Outlook Add-In is to prevent you from accidentally sending email messages in Outlook if they contain an uneven or unmatched pair of quotation marks, parentheses, curly braces or square brackets.  Read more about it and see more early screenshots in the 1.0 post I linked to earlier.

Improvements in this release include:

  • A new text file named ignore.txt should be placed at %USERPROFILE%\Supersymmetry\ignore.txt.  In this text file, the user can put character sequences ("tokens") for Supersymmetry to ignore in a message.  This is very handy for ignoring things like emoticons, because emoticons usually have parentheses in them, and the use of emoticons can make the message as a whole appear as though it contains an uneven number of parentheses, when the message is actually fine if you ignore the emoticons. A sample ignore.txt is included in the download package.
  • A new text file named divider.txt should be placed at %USERPROFILE%\Supersymmetry\divider.txt.  In this text file, the user can put a character or string token that splits or divides an email thread into pieces, and Supersymmetry will only scan up to the first occurrence of that token. The token or divider can be a single character, or a special string.  This is very useful so that Supersymmetry does not include all of the previous messages in the email thread during its scan.  I recommend putting your special delimiter character or string cleverly in your email signature for both new messages and replies, so that Outlook automatically inserts the token into every message you draft.  I'll leave that up to you.  A sample divider.txt is included in the download package.
  • If either of the two aforementioned files does not exist in the right place on the file system, the add-in will still work, but you will really miss those features.  Additionally, you will see some warning notifications pop up when Outlook loads the add-in:

Supersymmetry cannot locate its files

  • Notice that the recommended installation directory has changed from %APPDATA%\Supersymmetry to %USERPROFILE%\Supersymmetry, just because it's a little simpler.  If the add-in is installed correctly, and the configuration files were read successfully, you'll see these popups instead:

Supersymmetry loaded correctly


Download the package here:
Supersymmetry-v1.1.3.17.zip (296.8KB)

Make sure to Uninstall any old version of Supersymmetry first, by going to Programs and Features in your Control Panel and uninstalling Supersymmetry.  Also, make sure you've closed Outlook.  Then, unzip the package into your user profile directory, so that %USERPROFILE%\Supersymmetry exists and contains a file named setup.exe.  Next, run setup.exe.  In theory, that should help you download any required prerequisites such as .NET 4.5, and Visual Studio Tools for Office, and then install the add-in.  It's a "ClickOnce" deployment.  A great idea, when it works.


Simply go to Programs and Features (aka Add/Remove Programs) in Control Panel, find Supersymmetry, and uninstall it.

Have fun!

Supersymmetry in action!