To Scriptblock or Not to Scriptblock, That is the Question

by Ryan 27. March 2014 17:03

I was doing some work with the Active Directory Powershell cmdlets recently.  Well, I work with them almost every day, but they still get me with their idiosyncrasies from time to time.

I needed to check some group memberships on various privileged groups within the directory.  I'll show you an abridged version of the code I started with to get the point across, the idea of which is that I iterate through a collection of groups (a string array) and perform some actions on each of the Active Directory groups in sequence:

Foreach($ADGroupName In [String[]]'Domain Admins',     `
                                  'Enterprise Admins', `
                                  'Administrators',    `
                                  'Account Operators', `
                                  'Backup Operators')
{
    $Group = Get-ADGroup -Filter { Name -EQ $ADGroupName } -Properties Members
    If ($Group -EQ $Null -OR $Group.PropertyNames -NotContains 'Members')
    {
        # This condition only occurs on the first iteration of the Foreach loop!
        Write-Error "$ADGroupName was null or was missing the Members property!"
    }
    Else
    {
        Write-Host "$ADGroupName contains $($Group.Members.Count) members." 
    }
}

Before I continue, I'd just like to mention that I typically do not mind very long lines of code nor do I avoid verbose variable names, mostly because I'm always using a widescreen monitor these days.  Long gone are the days of the 80-character-wide terminal.  And I agree with Don Jones that backticks (the Powershell escape character) are to be avoided on aesthetic grounds, but for sharing code in formats that are less conducive to long lines of code, such as this blog or a StackExchange site with their skinny content columns, I'll throw some backticks in to keep the horizontal scrolling to a minimum. 

Anyway, the above code exhibited the strangest bug. At least I'd call it a bug. (I'll make sure and let Jeffrey Snover know next time I see him. ;P) Only on the first iteration of the Foreach loop, I would get the "error" condition instead of the expected "Domain Admins contains 5 members" output.  The remaining iterations all behaved as expected.  It did not matter in what order I rearranged the list of AD groups; I always got an error on the first element in the array.

For a moment, I settled on working around the "bug" by making a "Dummy Group," including that as the first item in the array, gracefully handling the expected exception because Dummy Group did not exist, and then continuing normally with the rest of the legitimate groups.  This worked fine, but it didn't sit well with me.  Not exactly my idea of production-quality code.  I wanted to find the root cause of this strange behavior.

Stackoverflow has made me lazy.  Apparently I go to Serverfault when I want to answer questions, and Stackoverflow when I want other people to answer questions for me.  Simply changing line 7 above to this:

$Group = Get-ADGroup -Filter "Name -EQ '$ADGroupName'" -Properties Members

Made all the difference.  That is, using a string with an expandable variable inside it instead of the script block for a filter.  (Which itself is a little confusing since single quotes (') usually indicate non-expandable variables.  Oh well.  Just syntax to remember when playing with these cmdlets.

Nevertheless, if the code would not work correctly with a script block, I wish the parser would mark it as a syntax error, instead of acting weird.  (Behavior exists in PS 2 and PS 4, though in PS 4 the missing property is just ignored and I get 0 members, which is even worse.)

Tired of the NSA Seeing What Model of Plug and Play Mouse You're Using?

by Ryan 14. January 2014 13:40

Not long ago, the story broke that the NSA was capturing internet traffic generated by Windows crash dumps, driver downloads from Windows Updates, Windows Error Reporting, etc.

As per Microsoft's policy, this information, when it contains sensitive or personally identifiable data, is encrypted.

Encryption: All report data that could include personally identifiable information is encrypted (HTTPS) during transmission. The software "parameters" information, which includes such information as the application name and version, module name and version, and exception code, is not encrypted.

While I'm not saying that SSL/TLS poses an impenetrable obstacle for the likes of the NSA, I am saying that Microsoft is not just sending full memory dumps across the internet in clear text every time something crashes on your machine.  But if you were to, for instance, plug in a new Logitech USB mouse, your computer very well could try to download drivers for it from Windows Update automatically, and when that happens, it sends a few details about your PC and the device you just plugged in, in clear text.

Here is where you can read more about that.

So let's say you're an enterprise administrator, and you want to put an end to all this nonsense for all the computers in your organization, such that your computers no longer attempt to contact Microsoft or send data to them when an application crashes or someone installs a new device.  Aside from setting up your own internal corporate Windows Error Reporting server, (who does that?) you can disable the behavior via Group Policy. There are a surprising number of policy settings that should be disabled so that you're not leaking data all over the web:

  • The system will be configured to prevent automatic forwarding of error information.

Configure the policy value for Computer Configuration -> Administrative Templates -> System -> Internet Communication Management -> Internet Communication settings-> “Turn off Windows Error Reporting” to “Enabled”.

  • An Error Report will not be sent when a generic device driver is installed.

Configure the policy value for Computer Configuration -> Administrative Templates -> System -> Device Installation -> "Do not send a Windows error report when a generic driver is installed on a device" to "Enabled".

  • Additional data requests in response to Error Reporting will be declined.

Configure the policy value for Computer Configuration -> Administrative Templates -> Windows Components -> Windows Error Reporting -> "Do not send additional data" to "Enabled".

  • Errors in handwriting recognition on Tablet PCs will not be reported to Microsoft.

Configure the policy value for Computer Configuration -> Administrative Templates -> System -> Internet Communication Management -> Internet Communications settings “Turn off handwriting recognition error reporting” to “Enabled”.

  • Windows Error Reporting to Microsoft will be disabled.

Configure the policy value for Computer Configuration -> Administrative Templates -> Windows Components -> Windows Error Reporting “Disable Windows Error Reporting” to “Enabled”.

  • Windows will be prevented from sending an error report when a device driver requests additional software during installation.

Configure the policy value for Computer Configuration -> Administrative Templates -> System -> Device Installation -> “Prevent Windows from sending an error report when a device driver requests additional software during installation” to “Enabled”.

  • Microsoft Support Diagnostic Tool (MSDT) interactive communication with Microsoft will be prevented.

Configure the policy value for Computer Configuration -> Administrative Templates -> System -> Troubleshooting and Diagnostics -> Microsoft Support Diagnostic Tool -> “Microsoft Support Diagnostic Tool: Turn on MSDT interactive communication with Support Provider” to “Disabled”.

  • Access to Windows Online Troubleshooting Service (WOTS) will be prevented.

Configure the policy value for Computer Configuration -> Administrative Templates -> System -> Troubleshooting and Diagnostics -> Scripted Diagnostics -> “Troubleshooting: Allow users to access online troubleshooting content on Microsoft servers from the Troubleshooting Control Panel (via Windows Online Troubleshooting Service - WOTS)” to “Disabled”.

  • Responsiveness events will be prevented from being aggregated and sent to Microsoft.

Configure the policy value for Computer Configuration -> Administrative Templates -> System -> Troubleshooting and Diagnostics -> Windows Performance PerfTrack -> “Enable/Disable PerfTrack” to “Disabled”.

  • The Application Compatibility Program Inventory will be prevented from collecting data and sending the information to Microsoft.

Configure the policy value for Computer Configuration -> Administrative Templates -> Windows Components -> Application Compatibility -> “Turn off Program Inventory” to “Enabled”.

  • Device driver searches using Windows Update will be prevented.

Configure the policy value for Computer Configuration -> Administrative Templates -> System -> Device Installation -> “Specify Search Order for device driver source locations” to “Enabled: Do not search Windows Update”.

  • Device metadata retrieval from the Internet will be prevented.

Configure the policy value for Computer Configuration -> Administrative Templates -> System -> Device Installation -> “Prevent device metadata retrieval from internet” to “Enabled”.

  • Windows Update will be prevented from searching for point and print drivers.

Configure the policy value for Computer Configuration -> Administrative Templates -> Printers -> “Extend Point and Print connection to search Windows Update” to “Disabled”.

Let's Deploy EMET 4.1!

by Ryan 26. December 2013 17:22

Howdy!

Let's talk about EMET.  Enhanced Mitigation Experience Toolkit.  Version 4.1 is the latest update, out just last month. It's free. You can find it here. When you download it, make sure you also download the user guide PDF that comes with it, as it's actually pretty good quality documentation for a free tool.

The thing about EMET, is that it is not antivirus. It's not signature-based, the way that traditional AV is. EMET is behavior based.  It monitors the system in real time and watches all running processes for signs of malicious behavior and attempts to prevent them.  It also applies a set of overall system-wide hardening policies that make many types of exploits more difficult or impossible to pull off. The upshot of this approach is that EMET can theoretically thwart 0-days and other malware/exploits that antivirus is oblivious to.  It also allows us to protect legacy applications that may not have been originally written with today's security features in mind.

The world of computer security is all about measure and countermeasure. The attackers come up with a new attack, then the defenders devise a defense against it, then the attackers come up with a way to get around that defense, ad nauseum, forever. But anything you can do to raise the bar for the attackers - to make their jobs harder - should be done.

Here's what the EMET application and system tray icon look like once it's installed:

EMET

From that screenshot, you get an idea of some of the malicious behavior that EMET is trying to guard against.  You can turn on mandatory DEP for all processes, even ones that weren't compiled for it. Data Execution Prevention has been around for a long time, and is basically a mechanism to prevent the execution of code that resides in areas of memory marked as non-executable. (I.e. where only data, not code, should be.)  With DEP on, heaps and stacks will be marked as non-executable and attempts to run code from those areas in memory will fail. Most CPUs these days have the technology baked right into the hardware, so there's no subverting it. (Knock on wood.)

You can turn on mandatory ASLR for all processes on the system, again, even for processes that were not compiled with it.  Address Space Layout Randomization is a technique whereby a process loads modules into "random" memory addresses, whereas in the days before ASLR processes always loaded modules into the same, predictable memory locations. Imagine what an advantage it would be for an attacker to always know exactly where to find modules loaded in any process on any machine.

Then you have your heapspray mitigation. A "heap spray" is an attack technique where the attacker places copies of malicious code in as many locations within the heap as possible, increasing the odds of success that it will be executed once the instruction pointer is manipulated. This is a technique that attackers came up with to aid them against ASLR, since they could no longer rely on predictable memory addresses. By allocating some commonly-used memory pages within processes ahead of time, we can keep the heap sprayer's odds of success low.

Those are only a few of the mitigations that EMET is capable of.  Read that user guide that I mentioned before for much more info.

Oh, and one last thing: Is it possible that EMET could cause certain applications to malfunction? Absolutely! So always test thoroughly before deploying to production. And just like with enterprise-grade antivirus software, EMET also requires a good bit of configuring until you come up with a good policy that suits your environment and gives you the best mix of protection versus application compatibility.

Let's get into how EMET can be deployed across an enterprise and configured via Group Policy. Once you've installed it on one computer, you will notice a Deployment folder in with the program files. In the Deployment folder you will find the Group Policy template files you need to configure EMET across your enterprise via GPO.  First, create your Group Policy Central Store if you haven't already:

Creating Central Store

Copy the EMET.ADMX file into the PolicyDefinitions folder, and EMET.ADML file into the EN-US subfolder.  If all goes well, you will notice a new Administrative Template now when you go to create a new GPO:

EMET GPO

Now you may notice that while I do have the EMET administrative template... all my other admin templates have disappeared! That's because I forgot to copy all of the other admin templates from one of the domain controllers into Sysvol before I took the screen shot. So don't forget to copy over all the other *.admx and *.adml files from one of your DCs before continuing.

Now you can control how EMET is configured in a centralized, consistent, enforceable way on all the computers in your organization.

The next part is deploying the software. The EMET user guide describes using System Center Configuration Manager to deploy the software, and while I agree that SCCM is boss when it comes to deploying software, I don't have it installed here in my lab, so I'm going to just do it via GPO as well.  In fact, I'll do it in the same EMET GPO that defines the application settings too.

Copy the installer to a network share that can be accessed by all the domain members that you intend to deploy the software to:

Copy the MSI

Then create a new GPO with a software package to deploy that MSI from the network location. Make sure the software is assigned to the computer, not the user.  And lastly, you'll likely rip less of your hair out if you turn off asynchronous policy processing like so:

Computer Settings
 + Administrative Templates
    + System
       + Logon
          + Always wait for the network at computer startup and logon: Enabled

And software deployment across an entire organization, that simple. Luckily I didn't even have to apply a transform to that MSI, which is good, because that is something I didn't feel like doing this evening.

Until next time, stay safe, and if you still want to hear more about EMET, watch this cool talk from Neil Sikka about it from Defcon 21!

IPv4Address Attribute In Get-ADComputer

by Ryan 2. December 2013 12:00

Guten Tag, readers!

Administrators who use Microsoft's Active Directory module for Powershell are most likely familiar with the Get-ADComputer cmdlet.  This cmdlet retrieves information from the Active Directory database about a given computer object.  Seems pretty straightforward, but recently I started wondering about something in Get-ADComputer's output:

Get-ADComputer IPv4Address

IPv4Address?  I don't recall that data being stored in Active Directory... well, not as an attribute of the computer objects themselves, anyway.  If you take a look at a computer object with ADSI Edit, the closest thing you'll find is an ipHostNumber attribute, but it appears to not be used:

ADSI Edit Computer Properties

Hmm... well, by this point, if you're anything like me, you're probably thinking that a DNS query is about the only other way that the cmdlet could be getting this data.  But I wasn't satisfied with just saying "it's DNS, dummy," and forgetting about it.  I wanted to know exactly what was going on under the hood.

So I started by disassembling the entire Microsoft.ActiveDirectory.Management assembly.  (How did I know which assembly to look for?)

After searching the resulting source code for ipv4, it started to become quite clear.  From Microsoft.ActiveDirectory.Management.Commands.ADComputerFactory<T>:

internal static void ToExtendedIPv4(string extendedAttribute, string[] directoryAttributes, ADEntity userObj, ADEntity directoryObj, CmdletSessionInfo cmdletSessionInfo)
{
  if (directoryObj.Contains(directoryAttributes[0]))
  {
    string dnsHostName = directoryObj[directoryAttributes[0]].Value as string;
    userObj.Add(extendedAttribute, (object) IPUtil.GetIPAddress(dnsHostName, IPUtil.IPVersion.IPv4));
  }
  else
    userObj.Add(extendedAttribute, new ADPropertyValueCollection());
}

Alright, so now we know that Get-ADComputer is using another class named IPUtil to get the IP address of a computer as it runs. Let's go look at IPUtil:

internal static string GetIPAddress(string dnsHostName, IPUtil.IPVersion ipVersion)
{
  if (string.IsNullOrEmpty(dnsHostName))
    return (string) null;
  try
  {
    foreach (IPAddress ipAddress in Dns.GetHostEntry(dnsHostName).AddressList)
    {
      if (ipAddress.AddressFamily == (AddressFamily) ipVersion && (ipVersion != IPUtil.IPVersion.IPv6 || !ipAddress.IsIPv6LinkLocal && !ipAddress.IsIPv6SiteLocal))
        return ipAddress.ToString();
    }
    return (string) null;
  }
  catch (SocketException ex)
  {
    return (string) null;
  }
}

Ahh, there it is.  The ole' trusty, tried and true System.Net.Dns.GetHostEntry() method.  The cmdlet is running that code every time you look up a computer object.  Also notice that the method returns on the first valid IP address that it finds, so we know that this cmdlet isn't going to work very well for computers with multiple IP addresses.  It would have been trivial to make the cmdlet return an array of all valid IP addresses instead, but alas, the Powershell developers did not think that was necessary.  And of course if the DNS query fails for any reason, you simply end up with a null for the IPv4Address field.

I've noticed that Microsoft's Active Directory cmdlets have many little "value-added" attributes baked into their cmdlets, but sometimes they can cause confusion, because you aren't sure where the data is coming from, or the "friendly" name that Powershell ascribes to an attribute doesn't match the attribute's name in Active Directory, etc.

More Windows and AD Cryptography Mumbo-Jumbo

by Ryan 6. November 2013 09:41

I've still had my head pretty deep into cryptography and hashing as far as Windows and Active Directory is concerned, and I figured it was worth putting here in case you're interested.  We're going to talk about things like NTLM and how Windows stores hashes, and more.

The term NTLM is a loaded one, as the acronym is often used to refer to several different things.  It not only refers to Microsoft’s implementation of another standard algorithm for creating hashes, but it also refers to a network protocol.  The NTLM used for storing password hashes on disk (aka NT hash) is a totally different thing than the NTLM used to transmit authentication data across a TCP/IP network.  There’s the original LAN Manager protocol, which is worse than NT LAN Manager (NTLM or NTLMv1,) which is worse than NTLMv2, which is worse than NTLMv2 with Session Security and so on…  but an NT hash is an NT hash is an NT hash.  When we refer to either NTLMv1 or NTLMv2 specifically, we’re not talking about how the password gets stored on disk, we’re talking about network protocols.

Also, this information refers to Vista/2008+ era stuff.  I don’t want to delve into the ancient history Windows NT 4 or 2000, so let’s not even discuss LAN Manager/LM.  LM hashes are never stored or transmitted, ever, in an environment that consists of Vista/2008+ stuff.  It’s extinct.

Unless some bonehead admin purposely turned it back on.  In which case, fire him/her.

Moving on…

LOCAL MACHINE STUFF

So here we talk about what goes on in a regular Windows machine with no network connection.  No domain.  All local stuff. No network.

"SO REALLY, WTF IS AN NT HASH!?"

You might ask.  An NT hash is simply the MD4 hash of the little endian UTF-16 encoded plaintext input.  So really it’s MD4.

"So the Windows Security Accounts Manager (SAM) stores MD4 hashes of passwords to disk, then?"

Well no, not directly.  The NT hashes, before being stored, are encrypted with RC4 using the machine’s "boot key," which is both hard to get at as well as being unique to each OS install.  By "hard to get at," I mean that the boot key is scattered across several areas of the registry that require system level access and you have to know how to read data out of the registry that cannot be seen in Regedit, even if you run it as Local System. And it must be de-obfuscated on top of that.  After hashing the boot key and other bits of data with MD5, you then create another RC4 key from the MD5 hash of the hashed bootkey, plus some more information such as the specific user's security identifier.

So the final answer is that Windows stores local SAM passwords to disk in the registry as RC4-encrypted MD4 hashes using a key that is unique to every machine and is difficult to extract and descramble, unless you happen to be using one of the dozen or so tools that people have written to automate the process.

Active Directory is a different matter altogether.  Active Directory does not store domain user passwords in a local SAM database the same way that a standalone Windows machine stores local user passwords.  Active Directory stores those password hashes in a file on disk named NTDS.dit.  The only password hash that should be stored in the local SAM of a domain controller is the Directory Services Restore Mode password.  The algorithms used to save passwords in NTDS.dit are much different than the algorithms used by standalone Windows machines to store local passwords.  Before I tell you what those algorithms are, I want to mention that the algorithms AD uses to store domain password hashes on disk should not be in scope to auditors, because NTDS.dit is not accessible by unauthorized users.  The operating system maintains an exclusive lock on it and you cannot access it as long as the operating system is running.  Because of that,  the online Directory Services Engine and NTDS.dit together should be treated as one self-contained ‘cryptographic module’ and as such falls under the FIPS 140-2 clause:

"Cryptographic keys stored within a cryptographic module shall be stored either in plaintext form or encrypted form.  Plaintext secret and private keys shall not be accessible from outside the cryptographic module to unauthorized operators…"

So even plaintext secrets are acceptable to FIPS 140, as long as they stay within the cryptographic module and cannot be accessed by or sent to outsiders.

Active Directory stores not only the hashed password of domain users, but also their password history.  This is useful for that “Remember the last 24 passwords” Group Policy setting.  So there are encrypted NT hashes stored in NTDS.dit.  Let’s just assume we have an offline NTDS.dit – again, this should not be of any concern to auditors – this is Microsoft proprietary information and was obtained through reverse engineering.  It’s only internal to AD.  FIPS should not be concerned with this because this all takes place "within the cryptographic module."  Access to offline copies of NTDS.dit should be governed by how you protect your backups.

To decrypt a hash in NTDS.dit, first you need to decrypt the Password Encryption Key (PEK) which is itself encrypted and stored in NTDS.dit.  The PEK is the same across all domain controllers, but it is encrypted using the boot key (yes the same one discussed earlier) which is unique on every domain controller.  So once you have recovered the bootkey of a domain controller (which probably means you have already completely owned that domain controller and thus the entire domain so I'm not sure why you'd even be doing this) you can decrypt the PEK contained inside of an offline copy of NTDS.dit that came from that same domain controller.  To do that, you hash the bootkey 1000 times with MD5 and then use that result as the key to the RC4 cipher.  The only point to a thousand rounds of hashing is to make a brute force attack more time consuming.

OK, so now you’ve decrypted the PEK.  So use that decrypted PEK, plus 16 bytes of the encrypted hash itself as key material for another round of RC4.  Finally, use the SID of the user whose hash you are trying to decrypt as the key to a final round of DES to uncover, at last, the NT (MD4) hash for that user.

Now you need to brute-force attack that hash.  Using the program ighashgpu.exe, which uses CUDA to enable all 1344 processing cores on my GeForce GTX 670 graphics card to make brute force attempts on one hash in parallel, I can perform over 4 billion attempts per second to eventually arrive at the original plaintext password of the user.  It doesn’t take long to crack an NT hash any more.

As a side-note, so-called "cached credentials" are actually nothing more than password verifiers.  They’re essentially a hash of a hash, and there is no reversible information contained in a "cached credential" or any information that is of any interest to an attacker.  "Cached credentials" pose no security concern, yet most security firms, out of ignorance, still insist that they be disabled.

So there you have it.  You might notice that nowhere in Windows local password storage or Active Directory password storage was the acronym SHA ever used.  There is no SHA usage anywhere in the above processes, at all. 

 

NETWORK STUFF

Now passing authentication material across the network is an entirely different situation!

I’ll start with the bad news.  Remember earlier when I talked about brute-forcing the decrypted NT hash of another user?  Well that last step is often not even necessary.  NT hashes are password-equivalent, meaning that if I give Windows your hash, it’s as good as giving Windows your password in certain scenarios.  I don’t even need to know what your actual password is.  This is the pass-the-hash attack that you might have heard of.  But it’s not as bad as it sounds.

The good news is that neither Windows nor Active Directory ever sends your bare NT hash over the wire during network transmission.  And you cannot begin a pass-the-hash attack until you’ve already taken over administrative control of some domain joined machine.  That means there is no such thing as using pass-the-hash to own an entire networked AD environment just from an anonymous observer sniffing network packets.  That’s not how it works.  (Fun video on PtH)

Now that we know what an NT hash is, it’s a good time to draw the distinction that whenever we talk about specifically NTLMv1 and NTLMv2, we’re not actually talking about NT hashes anymore.  We’re talking about network communication protocols.  The whole mess is often just called NTLM as a blanket term because it’s all implemented by Microsoft products and it’s all interrelated.

Both NTLMv1 and NTLMv2 are challenge-response protocols, where Client and Server challenge and respond with each other such that Server can prove that Client knows what his/her password is, without ever actually sending the password or its hash directly over the network.  This is because Server already knows Client’s password (hash), either because it’s stored in the local SAM in the case of local Windows accounts, or because Server can forward Client’s data to a domain controller, and the domain controller can verify and respond to Server with “Yep, that’s his password, alright.”

With NTLMv1, you’ll see some usage of DES during network communication. 

With NTLMv2, you’ll see some usage of HMAC-MD5.

There’s also NTLM2 Session, aka NTLMv2 With Session Security, but it uses the same encryption and hashing algorithms as NTLMv2.

It is possible to completely remove the usage of NTLM network protocols from an Active Directory domain and go pure Kerberos, but it will break many applications.  Here is a fantastic article written by one of my favorite Microsoft employees about doing just that.

So let’s assume that hypothetically we blocked all usage of NTLM network protocols and went pure Kerberos. Kerberos in AD supports only the following encryption:

DES_CBC_CRC    (Disabled by default as of Win7/2008R2)[Source]
DES_CBC_MD5    (Disabled by default as of Win7/2008R2)
RC4_HMAC_MD5   (Disabled by default as of Win7/2008R2)
AES256-CTS-HMAC-SHA1-96
AES128-CTS-HMAC-SHA1-96
RC4-HMAC
Future encryption types

 

Of course, there are plenty of other Windows applications that pass authentication traffic over the network besides just AD.  Remote Desktop is a great example.  Remote Desktop traditionally uses RC4, but modern versions of Remote Desktop will negotiate a Transport Layer Security (TLS) connection wherever possible.  (Also known as Network Level Authentication (NLA).)   This is great news because this TLS connection uses the computer’s digital certificate, and that certificate can be automatically created and assigned to the computer by an Enterprise Certificate Authority, and that certificate can be capable of SHA256, SHA384, etc.  However the Certificate Authority administrator defines it.

If you turn on FIPS mode, Remote Desktop can only use TLS 1.0 (as opposed to SSL) when NLA is negotiated, and it can only use 3DES_CBC instead of RC4 when TLS is not negotiated.

Other ciphers that are turned off when FIPS mode is turned on include:

-          TLS_RSA_WITH_RC4_128_SHA

-          TLS_RSA_WITH_RC4_128_MD5

-          SSL_CK_RC4_128_WITH_MD5

-          SSL_CK_DES_192_EDE3_CBC_WITH_MD5

-          TLS_RSA_WITH_NULL_MD5

-          TLS_RSA_WITH_NULL_SHA

 

That will apply to all applications running on Windows that rely upon Schannel.dll.  The application will crash if it calls upon one of the above ciphers when FIPS mode is enabled.

So anyway, that’s about all I got right now.  If you made it to the bottom of  this post I should probably buy you a drink!

 

FIPS 140

by Ryan 29. October 2013 21:23

FIPS 140-2 Logo

Oh yeah, I have a blog! I almost forgot.  I've been busy working.  Let's talk about an extraordinarily fascinating topic: Federal compliance!

FIPS (Federal Information Processing Standard) has many different standards.  FIPS holds sway mainly in the U.S. and Canada.  Within each standard, there are multiple revisions and multiple levels of classification.  FIPS 140 is about encryption and hashing algorithms.  It’s about accrediting cryptographic modules.  Here’s an example of a certificate.  The FIPS 140-2 revision is the current standard, and FIPS 140-3 is under development with no announced release date yet.  It does not matter if your homebrew cryptography is technically “better” than anything else ever.  If your cryptographic module has not gone through the code submission and certification process, then it is not FIPS-approved.  You have to submit your source code/device/module to the government, in order to gain FIPS approval.  Even if you have the most amazing cryptography the world has ever seen, it is still not FIPS approved or compliant until it goes through the process.  In fact, the government is free to certify weaker algorithms in favor of stronger ones just because the weaker algorithms have undergone the certification process when the stronger ones have not, and they have historically done so.  (Triple-DES being the prime example.)

There is even a welcome kit, with stickers.  You need to put these tamper-proof stickers on your stuff for certain levels of FIPS compliance.

So if you are ever writing any software of your own, please do not try to roll your own cryptography. Use the approved libraries that have already gone through certification. Your custom crypto has about a 100% chance of being worse than AES/SHA (NSA backdoors notwithstanding,) and it will never be certifiable for use in a secure Federal environment anyway.  Also avoid things like re-hashing your hash with another hashing algorithm in attempt to be ‘clever’ – doing so can ironically make your hash weaker.

And the Feds are picky.  For instance, if programming for Windows in .NET, the use of System.Security.Cryptography.SHA1 classes may be acceptable while the use of System.Security.Cryptography.SHA1Managed classes are not acceptable.  It doesn’t mean the methods in the SHA1Managed classes are any worse, it simply means Microsoft has not submitted them for approval. 

Many major vendors such as Microsoft and Cisco go through this process for every new version of product that they release.  It costs money and time to get your product FIPS-certified.  Maybe it’s a Cisco ASA appliance, or maybe it’s a simple Windows DLL. 

The most recent publication of FIPS 140-2 Annex A lists approved security functions (algorithms.)  It lists AES and SHA-1 as acceptable, among others. So if your application uses only approved implementations of AES and SHA-1 algorithms, then that application should be acceptable according to FIPS 140-2.  If your application uses an MD5 hashing algorithm during communication, that product is NOT acceptable for use in an environment where FIPS compliance must be maintained. 

However, there is also this contradictory quote from NIST:

“The U.S. National Institute of Standards and Technology says, "Federal agencies should stop using SHA-1 for...applications that require collision resistance as soon as practical, and must use the SHA-2 family of hash functions for these applications after 2010" [22]”

So it seems to me that there are contradictory government statements regarding the usage of security functions.  The most recent draft of FIPS 140-2 Annex A clearly lists SHA-1 as an acceptable hashing algorithm, yet, the quote from NIST says that government agencies must use only SHA-2 after 2010.  Not sure what the answer is to that. 

These algorithms can be broken up into two categories: encryption algorithms and hashing algorithms.  An example of a FIPS encryption algorithm is AES (which consists of three members of the Rijndael family of ciphers, adopted in 2001, and has a much cooler name.)  Encryption algorithms can be reversed/decrypted, that is, converted back into their original form from before they were encrypted.

Hashing algorithms on the other hand, are also known as one-way functions.  They are mathematically one-way and cannot be reversed.  Once you hash something, you cannot “un-hash” it, no matter how much computing power you have.  Hashing algorithms take any amount of data, of an arbitrary size, and mathematically map it to a “hash” of fixed length.  For instance, the SHA-256 algorithm will map any chunk of data, whether it be 10 bytes or 2 gigabytes, into a 256 bit hash.  Always 256 bit output, no matter the size of the input.

This is why the hash of a password is generally considered decently secure, because there is NO way to reverse the hash, so you can pass that hash to someone else via insecure means (e.g. over a network connection,) and if the other person knows what your password should be, then they can know that the hash you gave them proves that you know the actual password.  That's a bit of a simplification, but it gets the point across.

If you were trying to attack a hash, all you can do, if you know what hash algorithm was used, is to keep feeding that same hash algorithm new inputs, maybe millions or billions of new inputs a second, and hope that maybe you can reproduce the same hash.  If you can reproduce the same hash, then you know your input was the same as the original ‘plaintext’ that you were trying to figure out.  Maybe it was somebody’s password.  This is the essence of a ‘brute-force’ attack against a password hash.

Logically, if all inputs regardless of size, are mapped to a fixed size, then it stands to reason that there must be multiple sets of data that, when hashed, result in the same hash.  These are known as hash collisions.  They are very rare, but they are very bad, and collisions are the reason we needed to migrate away from the MD5 hashing algorithm, and we will eventually need to migrate away from the SHA-1 hashing algorithm.  (No collisions have been found in SHA-1 yet that I know of.)  Imagine if I could create a fake SSL certificate that, when I creatively flipped a few bits here and there, resulted in the same hash as a popular globally trusted certificate!  That would be very bad.

Also worth noting is that SHA-2 is an umbrella term, that includes SHA256, SHA384, SHA512, etc.

FIPS 140 is only concerned with algorithms used for external communication.  Any communication outside of the application or module, whether that be network communication, or communication to another application on the same system, etc.  FIPS 140 is not concerned with algorithms used to handle data within the application itself, within its own private memory, that never leaves the application and cannot be accessed by unauthorized users.  Here is an excerpt from the 140-2 standard to back up my claim:

“Cryptographic keys stored within a cryptographic module shall be stored either in plaintext form or encrypted form. Plaintext secret and private keys shall not be accessible from outside the cryptographic module to unauthorized operators…”

Let’s use Active Directory as an example.  This is why, when someone gets concerned about what algorithms AD uses internally, you should refer them to the above paragraph and tell them not to worry about it.  Even if it were plaintext (it’s not, but even if hypothetically it were,) it isn’t in scope for FIPS because it is internal only to the application.  When Active Directory and its domain members are operated in FIPS mode, connections made via Schannel.dll, Remote Desktop, etc., will only use FIPS compliant algorithms. If you had applications before that make calls to non-FIPS crypto libraries, those applications will now crash.

Another loophole that has appeared to satisfy FIPS requirements in the past, is wrapping a weaker algorithm inside of a stronger one.  For instance, a classic implementation of the RADIUS protocol utilizes the MD5 hashing algorithm during network communications.  MD5 is a big no-no.  However, see this excerpt from Cisco:

“RADIUS keywrap support is an extension of the RADIUS protocol. It provides a FIPS-certifiable means for the Cisco Access Control Server (ACS) to authenticate RADIUS messages and distribute session keys.”

So by simply wrapping weaker RADIUS keys inside of AES, it becomes FIPS-certifiable once again.  It would seem to follow that this logic also applies when using TLS and IPsec, as they are able to use very strong algorithms (such as SHA-2) that most applications do not natively support.

So with all that said, if you need the highest levels of network security, you need 802.1x and IPsec if you need to protect all those applications that can't protect themselves.

Bare Minimum Required to Promote a Domain Controller Into a Domain

by Ryan 13. October 2013 13:17

Hiya,

This is something I meant to blog about months ago, but for some reason I let it slip my mind. It just came up again in a conversation I had yesterday, and I couldn't believe I forgot to post it here. (It also may or may not be similar to a test question that someone might encounter if he or she were taking some Microsoft-centric certification tests.)

It started when someone on ServerFault asked the question, "Do you need a GC online to DCPROMO?"

Well the short answer to that question is that no, you don't need a global catalog online (or reachable) from the computer you are trying to simply promote into a domain controller. But that got me thinking, I'd like to go a step farther and see for myself what the bare minimum requirements for promoting a computer to a domain controller in an existing domain, especially concerning the accessibility of certain FSMO roles from the new DC. I don't care about anything else right now (such as how useful this DC might be after it's promoted) except for just successfully completing the DCPromo process.

On one hand, this might seem like just a silly theoretical exercise, but on the other hand, you just might want to have this knowledge if you ever work in a large enterprise environment where your network is not fully routed, and all DCs are not fully meshed. You might need to create a domain controller in a segment of the network where it has network connectivity to some other DCs, but not all of them.

Well I have a fine lab handy, so let's get this show on the road.

  1. Create three computers.
  2. Make two of them DCs for the same single-domain forest (of the 2008+ variety.)
  3. Make only one of them a global catalog.
  4. Leave all FSMOs on the first domain controller, for now.

So when you promote a writable domain controller, you need two things: another writable domain controller online from which to replicate the directory, and your first RID pool allocation directly from the RID pool FSMO role holder. When you promote an RODC, you don't even need the RIDs, since RODCs don't create objects or outbound replicate.  If the computer cannot reach the RID pool master, as in direct RPC connectivity, DCPROMO will give you this message:

You will not be able to install a writable replica domain controller at this time because the RID master DC1.domain.com is offline.

But you can still create an RODC, as long as the domain controller with whom you can communicate is not also an RODC - it has to be a RWDC.

So the final steps to prove this theory are:

  1. Transfer only the RID master to the second domain controller.
  2. Power down the first domain controller.

At this point, only the RID pool master is online, and no global catalog is online. Now run DCPromo on your third computer. Can you successfully promote the new domain controller as a RWDC?

Yes you can.

Now, you'll encounter some other problems down the road, such as the new DC not being able to process password changes because it cannot contact the PDCe, but you've successfully added a new domain controller to the domain nonetheless.

Locating Active Directory Site Options with Powershell

by Ryan 2. October 2013 16:30

So as you may know, I hang out on ServerFault a lot.  And last night, one of my favorite ServerFault members, Mark Marra, asked an interesting question there that sent me on a long journey of research in order to answer it.

(Mark's got his own IT blog by the way which you should totally check out. He's a world class Active Directory guy, the kind of guy that doesn't usually ask easy questions, so I'm proud of myself whenever I'm able to answer one of his questions.)

The link to the actual question and answer on ServerFault is here, most of which I am about to repeat in this post, but I'll see if I can embellish a little here on this blog.

Question:

How can I use PowerShell to find AD site options like +IS_INTER_SITE_AUTO_TOPOLOGY_DISABLED in PowerShell? I've been playing around with the following command, but can't get it to spit out anything useful.

Get-ADObject -Filter 'objectClass -eq "site"' `
-Searchbase (Get-ADRootDSE).ConfigurationNamingContext `
-Properties options

Answer:

The above command is very close, but off by just a hair. The short and simple answer is that the above command is searching for the options attribute of the Site object itself, when we actually need to be looking at the NTDS Site Settings object belonging to that site. And furthermore, there is no Powershell-Friendly way of getting this data as of yet, i.e., there is no simple Get-ADSiteOptions Cmdlet... but we may just have the cure for that if you can get through the rest of this blog post. We just need to figure out where exactly to find the data, and then we can use Powershell to grab it, wherever it may be hiding.

Take the following two commands: 

repadmin commands

Repadmin /options <DC> gives us the DSA options that are specific to the domain controller being queried, such as whether the domain controller is a global catalog or not, and the Repadmin /siteoptions <DC> command gives us the options applied to the Active Directory Site to which the domain controller being queried belongs (or you can specify that you want to know the settings for another site with the /site:California parameter. Full repadmin syntax here, or just use the /experthelp parameter.)

Note that these settings are relatively advanced settings in AD, so you may not work with them on a regular basis. Sites by default have no options defined, so if you find yourself working with these options, chances are you have a more complex AD replication structure on your hands than the average Joe. If all you have are a few sites that are fully bridged/meshed, all with plenty of bandwidth, then you probably have no need to modify these settings. More importantly, if you modify any of these settings, it's very important that you document your changes, so that future administrators will know what you've done to the domain.

So where does repadmin.exe get this information?

The settings for individual domain controllers come from here: 

ADSI Edit 1

That is, the options attribute of the NTDS Settings object for each domain controller.

The site options come from the NTDS Site Settings object for each site. (Not the site object itself: ) 

Site Options

Here is the basic MSDN documentation on the Options attribute:

A bitfield, where the meaning of the bits varies from objectClass to objectClass. Can occur on Inter-Site-Transport, NTDS-Connection, NTDS-DSA, NTDS-Site-Settings, and Site-Link objects.

Now we know exactly which bits repadmin.exe works on when we issue a command such as repadmin /options DC01 +IS_GC or repadmin /siteoptions DC01 /site:Arlington +IS_INTER_SITE_AUTO_TOPOLOGY_DISABLED. Fortunately, repadmin.exe as well as the ADSI Edit MMC snap-in both have bitmask translators in their code, so that they can show us the friendly names of the value of the options attribute, instead of just a 32-bit hexadecimal code.

If we want to roll our own Get-ADSiteOptions Cmdlet, we'll have to build our own bitmask translator too.

Fortunately the bitfields for both the DC settings and the Site settings are documented, here and here. Here is an excerpt for the Site options bitmask: 

Site Options Bitmask

So now we have enough information to start working on our Get-ADSiteOptions Cmdlet. Let's start with this basic snippet of Powershell:

ForEach($Site In (Get-ADObject -Filter 'objectClass -eq "site"' -Searchbase (Get-ADRootDSE).ConfigurationNamingContext)) 
{ 
    Get-ADObject "CN=NTDS Site Settings,$($Site.DistinguishedName)" -Properties Options 
}

What that does is get the DistinguishedName of every Site in the forest, iterate through them and get the attributes of each Site's NTDS Site Settings object. If the options attribute has not been set for a Site (which remember, is the default,) then it will not be shown. Only Sites with modified options will show as having an options attribute at all. Furthermore, in Powershell, it will come out looking like this:

Powershell site options

It's in decimal. 16 in decimal is 0x10 in hex, which we now know means IS_INTER_SITE_AUTO_TOPOLOGY_DISABLED.

So, without further ado, let's see if we can build our own Get-ADSiteOptions Cmdlet:

#Require -Version 3
#Require -Module ActiveDirectory
Function Get-ADSiteOptions
{
<#
.SYNOPSIS
    This Cmdlet gets Active Directory Site Options.
.DESCRIPTION
    This Cmdlet gets Active Directory Site Options.
    We can fill out the rest of this comment-based help later.
.LINK
    http://myotherpcisacloud.com
.NOTES
    Written by Ryan Ries, October 2013. ryanries09@gmail.com.
#>
    [CmdletBinding()]
    Param()
    BEGIN
    {
        Set-StrictMode -Version Latest

        # This enum comes from NtDsAPI.h in the Windows SDK.
        # Also thanks to Jason Scott for pointing it out to me. http://serverfault.com/users/23067/jscott
        Add-Type -TypeDefinition @" 
                                   [System.Flags]
                                   public enum nTDSSiteSettingsFlags {
                                   NTDSSETTINGS_OPT_IS_AUTO_TOPOLOGY_DISABLED            = 0x00000001,
                                   NTDSSETTINGS_OPT_IS_TOPL_CLEANUP_DISABLED             = 0x00000002,
                                   NTDSSETTINGS_OPT_IS_TOPL_MIN_HOPS_DISABLED            = 0x00000004,
                                   NTDSSETTINGS_OPT_IS_TOPL_DETECT_STALE_DISABLED        = 0x00000008,
                                   NTDSSETTINGS_OPT_IS_INTER_SITE_AUTO_TOPOLOGY_DISABLED = 0x00000010,
                                   NTDSSETTINGS_OPT_IS_GROUP_CACHING_ENABLED             = 0x00000020,
                                   NTDSSETTINGS_OPT_FORCE_KCC_WHISTLER_BEHAVIOR          = 0x00000040,
                                   NTDSSETTINGS_OPT_FORCE_KCC_W2K_ELECTION               = 0x00000080,
                                   NTDSSETTINGS_OPT_IS_RAND_BH_SELECTION_DISABLED        = 0x00000100,
                                   NTDSSETTINGS_OPT_IS_SCHEDULE_HASHING_ENABLED          = 0x00000200,
                                   NTDSSETTINGS_OPT_IS_REDUNDANT_SERVER_TOPOLOGY_ENABLED = 0x00000400  }
"@
        ForEach($Site In (Get-ADObject -Filter 'objectClass -eq "site"' -Searchbase (Get-ADRootDSE).ConfigurationNamingContext)) 
        {            
            $SiteSettings = Get-ADObject "CN=NTDS Site Settings,$($Site.DistinguishedName)" -Properties Options
            If(!$SiteSettings.PSObject.Properties.Match('Options').Count -OR $SiteSettings.Options -EQ 0)
            {
                # I went with '(none)' here to give it a more classic repadmin.exe feel.
                # You could also go with $Null, or omit the property altogether for a more modern, Powershell feel.
                [PSCustomObject]@{SiteName=$Site.Name; DistinguishedName=$Site.DistinguishedName; SiteOptions='(none)'} 
            }
            Else
            {
                [PSCustomObject]@{SiteName=$Site.Name; DistinguishedName=$Site.DistinguishedName; SiteOptions=[Enum]::Parse('nTDSSiteSettingsFlags', $SiteSettings.Options)}
            }
        }
    }
}

And finally, a screenshot of the fruits of our labor - what we set out to do, which was to view AD Site options in Powershell:

SRV Record for NTP? In *MY* Active Directory?

by Ryan 12. August 2013 15:00

Howdy fellow IT goons. I am probably not going to talk about Powershell today... but no promises.

Good ole' RFC 2782, the great fireside reading that it is, spells out the concept behind DNS SRV records and using them to locate services within a domain. The Microsoft article "How DNS Support for Active Directory Works", which is also more than just a heart-warming story but is also required reading if you're a Windows admin, mentions that Active Directory is pretty much, more or less, compliant with the aforementioned RFC:

"When a domain controller is added to a forest, a DNS zone hosted on a DNS server is updated with the Locator DNS resource records for that domain controller. For this reason, the DNS zone must allow dynamic updates (RFC 2136), and the DNS server hosting that zone must support the SRV resource records (RFC 2782) to advertise the Active Directory directory service."

It goes _<service>._<protocol>.domain.com, so if I wanted to locate LDAP services in a domain I'd issue a DNS query for _ldap._tcp.domain.com, or if I wanted to find Kerberos service I'd do _kerberos._tcp.domain.com.

But no one ever said that Active Directory uses every type of SRV there is by default. Not even close. Take NTP, Network Time Protocol, as an example.  Given the above logic I might issue a DNS query for _ntp._udp.domain.com, searching for NTP time service in that domain. Assuming I'm in a Microsoft Active Directory domain, odds are that I will not find it.

An SRV record is not created by default for the NTP service.  This is because Windows clients connecting to an AD domain already know to use domain controllers for time service in an AD domain, and the domain controllers already have their own SRV records, so separate NTP records would be redundant and unnecessary.

In fact, the only Microsoft-centric scenario I know of where the SRV record _ntp._udp.domain.com comes in to play is smart phones and devices using Microsoft Office Communicator or Lync - and even then it's optional since they'll fail back to time.windows.com if the SRV record is not found. You can find those examples here and here. If you know of any other situations where Windows-based applications use such an SRV record, please let me know.

But maybe you have a heterogeneous IT environment and you may want to add these records for yourself in order to support Unix/Linux clients and their applications that are making such DNS queries.  It's very easy:

  • Open the DNS Manager console/MMC snap-in.
  • Drill down into your Forward Lookup Zones.
  • Locate the _udp subdomain, since the NTP service operates over the UDP protocol.
  • You should see a list of _kerberos and _kpasswd SRV records there already, that represent the domain controllers currently in your domain.
  • Right-click in that white space and choose "Other New Records..."
  • Select "Service Location (SRV)" from the list.
  • Configure your new record like this screenshot:

SRV record

Mind the underscores, and notice the trailing period at the end of your domain name. You will probably want to add one of these for each domain controller you have, and you can play around with the weights and priorities however you like. NTP uses port 123 of course. There will be some options in the drop down list that they give you as examples. Don't confuse it with _nntp, unless you host the News Network Transfer service in your domain too.

Tell Me Which Active Directory Security Groups Are Not Applying Inheritable Permissions

by Ryan 22. July 2013 14:05

I encounter many Active Directory forests that were built and maintained for years by other organizations, and then through mergers or acquisitions or business reorgs, I need to help bring them into the fold with the rest of my portfolio of AD forests.

AD permissions can be a deep rabbit hole, especially when sitting down to a new directory sight unseen. Administrators make subtle changes to AD objects over the years and a lot of entropy happens.  Entropy that's not always easy to see or keep track of.

In this particular instance, we had an issue where a delegation of control was not working correctly and/or consistently.  It was the common IT task of delegating the ability to reset passwords and unlock accounts (but nothing else) to a special "help desk" sort of security group. It was allowing members of the "help desk" group to reset the passwords of certain users, but not others.  None of them were administrative users, or members of the Domain Admins group, the Account Operators group, etc. etc.

Turns out, the problem was that some security groups were not including inheritable permissions from the domain root object, so users who were members of these certain groups were immune to the effects of the delegation. 

Advanced Permissions

At first I actually thought to go and click on every single security group in the domain, checking on whether they were applying inheritable permissions or not.  Then a few seconds I realized, "Don't be an idiot Ryan. The GUI is not your friend! Don't succumb to its siren song!"

After glancing at this excellent SDDL reference here for about 5 minutes, I whipped this up:

Foreach($_ In Get-ADGroup -Filter *)
{
	[bool]$Inherits = $($(Get-ADGroup $_ -Properties *).nTSecurityDescriptor.Sddl.Contains('OI'))
	If($Inherits -EQ $False)
	{
		$_
	}
}

 And presto - a list of all security groups in the domain that are not applying inheritable permission from their parents.

PS - I admit, I still have to use a cheat sheet when reading SDDL.  :P

About Me

Name: Ryan Ries
Location: Texas, USA
Occupation: Systems Engineer 

I am a Windows engineer and Microsoft advocate, but I can run with pretty much any system that uses electricity.  I'm all about getting closer to the cutting edge of technology while using the right tool for the job.

This blog is about exploring IT and documenting the journey.


Blog Posts (or Vids) You Must Read (or See):

Pushing the Limits of Windows by Mark Russinovich
Mysteries of Windows Memory Management by Mark Russinovich
Accelerating Your IT Career by Ned Pyle
Post-Graduate AD Studies by Ned Pyle
MCM: Active Directory Series by PFE Platforms Team
Encodings And Character Sets by David C. Zentgraf
Active Directory Maximum Limits by Microsoft
How Kerberos Works in AD by Microsoft
How Active Directory Replication Topology Works by Microsoft
Hardcore Debugging by Andrew Richards
The NIST Definition of Cloud by NIST


MCITP: Enterprise Administrator

VCP5-DCV

Profile for Ryan Ries at Server Fault, Q&A for system administrators

LOPSA

GitHub: github.com/ryanries

 

I do not discuss my employers on this blog and all opinions expressed are mine and do not reflect the opinions of my employers.