The first question one might ask is, “Really… Why are
you writing about this old news now?” The answer is simple; even with the
release of Window 8 and Server 2012, Pass the Hash (PTH) attacks are still
incredibly simple and effective. While from an academic standpoint
passing the hash is simple to understand, it is a bit more complex from an
attacker or defender’s stand point. The reason for this post is that
having read a huge number of papers and post on pass the hash, none of them
gave me a clear picture.
The reason pass the hash is so powerful is due to NTLM’s
initial design flaw. NTLM was essentially broken from the day it was
released. While UNIX started saving salted hashes in the 1970s, the
designers of NTLM chose to use an unsalted hash. Salting a hash is
probably the most important design criterion when designing an authentication
system.
A hash
is a one way transformation of a variable input to a fixed length output.
A hash function must be deterministic, meaning that the same input will always
generate the same output, no matter what platform it might be run on. Another
key property of a good hash function is that even a small change in the input
creates a significant change in the output. The final vital property of a
hash function is that it must be truly one way. There must be no method
allowing the input to be derived using only the output.
With these properties, and the benefit of hindsight, a hash
is the perfect way to for one party to prove they know a password without the
other party actually knowing it. Storing reversible or god forbid
plaintext passwords introduces a significant number or risks. Only the
ignorant do this.
If the hash can’t be reversed, then you might think there
are no more risks and you can just hash those passwords and be on your merry
way. If we didn’t have a security model to think about, this might make
sense. The reason we bother to hash the passwords and not store
them as plaintext on our authentication servers is that, on the off chance that
the auth server is compromised, we want to minimize the value of the stolen
identities. Assuming you kick out the attacker and restore from backup, it
would be nice to not have to force all of your users to change their
passwords. It would be nice to be sure that the breach wasn’t just a
foothold to a larger attack. Additionally, as users tend to reuse passwords, we
don’t want to put the users’ accounts at risk on other systems or sites.
This brings us to the risk created by just storing the password hash with no
salt. If one has access to the hash and wants to derive the input
(password), all that needs to be done is test passwords until the outputs (hashes)
match. This Brute
force method is always a theoretical option when trying to defeat a
cryptographic function. Trying all possible passwords is time consuming,
which works against the attacker. Unfortunately, with super fast
processors and huge amounts of cheap storage, it is now possible to pre-compute and store huge
numbers of hashes and the corresponding passwords. In the space of less than 1 TB, you can
store tables that cover 96% of 1 to 9 character passwords containing upper
case, lower case, and numbers. By storing just the password hash we make
it completely worth an attacker’s time to create and save the pre-computes
values. Even better, you can just pay when you need to use
someone else’s’ tables.
Simply salting the hash wastes all that work the attacker
did to pre-compute the hashes. Salting a hash is simply adding random or
pseudo-random data to the input before computing the hash. The salt is
saved and later used when verifying the password. When verifying the
password, the salt is looked up, re-applied to the password that is being
tested, and the data hashed. If the result on file and the real-time
computed result match, the password was correct. By applying the random data,
we have completely wasted the attackers’ pre-computation effort. Ideally,
every account uses a different salt, so that even if your user database is
taken, every password must be brute forced separately.
Salted Hash Example
Password Salt SHA-1 Hash
V3ryStrong 1 88 93 EB 7A 28
DA A4 95 89 B1 B5 A1 E0 C6 A0 83 9D 38 A3 39
V3ryStrong 2 59 86 41 B2 62
B7 C3 C7 54 27 78 94 FB D6 59 24 5F 77 74 40
The example is purposely weak to make for easy
understanding. Usually the salt would be 8 – 16 bytes. It shows the
amplification provided by SHA-1. With a single bit change the data is
completely different and we see that there is no way to pre-compute all
passwords, unless we pre-compute all passwords with all possible salt values,
which in not feasible.
While this is fun background data, it really has little to
do with passing the hash, as PTH lets an attacker who has the hash assume the
user’s identity without ever knowing the password. This is because
windows stores the user’s NT hash in Active Directory DIT
or the SAM.
The first step of NTLM and NTLMv2 handshakes is that the system converts the
user’s password to the NT hash, and the handshake does some fun handshake math
that proves the user knew the hash, without the hash ever crossing the
network.
This system makes the hash “password equivalent”. If
an attacker has the user’s hash, they just skip the “convert password to NT
hash” and go straight to using it in the handshake. There are many
tools for doing this, depending on where NTLM is being used. NTLM
authentication occurs in-band with the protocol that is being used to access
data or access a system. NTLM auth occurs inside remote file access via
CIFS/SMB, TDS for accessing SQL server, RPC for all sorts or remote
administration and access, HTTP
for web auth, and I’m sure a few more things.
In order for an attacker to pass the hash, they need four
things:
1.
The valid NT hash (and username)
2.
A channel to pass the hash through
3.
A server hosting a service that utilizes/allows NTLM auth
4.
A client (or tool) that allows the attacker to input the hash rather
than the password
In a world where all four elements are available to an
attacker, there is no stopping PTH. Keeping in mind the four
requirements, defenders can limit, and more importantly, and understand their
level of exposure.
Securing the Hash
The most important thing a defender can do is keep the hash
from falling into the wrong hands. The hash resides on a computer in two
main areas; the SAM (Security Account Manager) db and in RAM, for users that
are logged in. There is a common misconception that the NT hash is also
stored in the registry for cached logon of domain user accounts on domain
joined computers. This is just that, a misconception. Depending on system
settings, data is stored that allows a domain user to logon to a machine when
no domain controller is available; however this data is an MD4 of
the NT hash + username. It might be worth an attackers’ time to
pre-compute the hashes for common user names, such as ‘Administrator’.
Looking at the threat model, one can conclude that the horse
is out of the barn if the hash is stolen. In order to steal the hash, the
attacker had to gain full control of the system. The attacker must either
execute hash stealing code as a member of local administrators, or gain
physical access to the poorly protected computer. While the horse is
indeed out of the barn on that host, the attacker should be able to go no
further. At least that is the defenders hope. This is, of course, not the
case. If the user has the other three required elements, she can act as
the user at will.
Stealing the Hash from RAM
In order for an attacker to steal a user’s NT hash from RAM,
the attacker must run code with administrator rights. As with all the
advice that will be offered, all the controls are fairly standard and map to
basic security concepts.
·
Reduce surface area
o Don’t
leave sessions logged in unnecessarily, as another administrator’s failure can
compromise your account.
o Avoid
logging in with administrator rights. If you screw up and run attackers
code, they can’t steal the hash if you aren’t an admin.
·
Use up to date AV software
Stealing the Hash via Physical Access
We all know that if an attacker has physical access
to a host then they own the host. The last thing we want to do is allow the
attacker to use that host as a foothold to even more systems and data. In
the case of PTH attacks, we probably have good news here. The NT hashes
are stored in the local SAM. If the computers are not domain joined, the
username and password usually don’t cross hosts, unless you took the time to
sync up your usernames and passwords across them all. As I mentioned
earlier, the cached domain credentials DO NOT contain the NT hash. This means
the SAM from one computer is of no value on anther.
The one place where there IS a great deal of risk is in an
enterprise, where standardization probably means that the local admin password
is the same across every domain member. This means that the
compromise of any one server is equivalent to the compromise of every
server. This means that that dev server that you left up running PHP 1.2
can be a great foothold to the rest of your servers and data.
To reduce this risk:
·
Use full disk encryption that requires a token or Password Based Key
Derivation Function
·
Enable syskey
protection > 1.
o This
requires a password or floppy to boot and decrypt the goodies in the SAM.
o This
scales poorly for an enterprise.
·
Make sure all local admin passwords are different.
Stealing the Hash from the Network
The NTLM and NTLMv2 handshakes assure that the NT hash
itself can be verified, without it ever appearing on the network. There
is nothing to see here.
If an attacker were to figure out a way to get the hash from
the network, it would be an impressive feat.
Securing the Channels
If the attacker steals the hash, but has no path to pass it
over, then the hash is of little value. One nice thing about NTLM auth is
that it occurs in band with the protocol utilizing it, so as a defender, you
can better understand and limit your exposure. If you block ports 80,
138,139, and 445, but open 1433, you know that the stolen hash can only be used
to access SQL data but not remote file access or websites.
Controls to consider:
·
Reduce Surface Area. Only open the ports you need. Duh…
·
Authenticate end points with VPN or IPSec.
Stop using NTLM
This one is not so simple. One can “kerberize” all
sorts of servers. That is, allow them to utilize Kerberos authentication
rather than NTLM. Microsoft has done a pretty good job kerberizing
applications, but in almost all cases, if Kerberos fails, the app will allow
fallback to NTLM.
I know of no options for a defender here. This section
is really a call to MS, and others, to allow for more granular options related
to NTLM auth, Kerberos, and fallback options.
I suppose this is an opportunity for firewall vendors as
well. It would be fairly easy to block NTLM auth and allow Kerberos on a
per protocol basis. I suspect an F5 ninja could write a crazy iRule to do it too.
Stop Clients from Allowing the use of the NT Hash
Assuming you have dealt with the firewall rules, most
attackers will have no channel to pass hashes over. The last option would
be to pass from hosts inside your network. This seems plausible, as the
attacker got enough access to steal the hash.
There are two classes of tools that let you work from the
hash rather than the password. The first are tools like WCE,
which run on windows and allow an administrator to inject arbitrary usernames
and hashes into a user’s session. This allows all subsequent uses of any
tool in that session to authenticate as the injected user. This means
that any Windows tool that speaks NTLM will work. The second class are
custom tools that may run on any OS and speak the protocol in question, be it
SMB, TDS/SQL, RPC, or whatever, AND they speak NTLM taking a hash rather than
password.
For a good list of current tools and tons of great info on
PTH, see Still Passing the Hash
15 Years Later.
A good list, granted probably dated, of AV test results for
detection of the tools, can be found here.
Controls to consider:
·
Make sure EVERY host inside your firewall has up to date AV.
o Enforce
this with NAC
or NAP.
o Make
sure hosts with AV match up to your CMDB, such that all hosts are accounted
for.
·
Consider AppLocker
and Software Restriction
Polices.
o Make
sure to block known tools by hash so the attacker can’t just rename at tool
o Make
sure to block known tools by name, in case the attacker makes code changes but
chooses to use the same executable name.
o Consider
white listing known good apps rather than trying to blacklist known bad ones.
·
Minimize the number of local administrators. A local admin can
stop AV or add exclusions prior to copying over and loading up tools.
·
Keep up on the latest version of the tools and test your AV yourself.
Understanding Why Pass the Hash Still Works
The best way to learn this stuff is to go to Eric Glass’s NTLM page
and do the math along with him. I am borrowing heavily here to summarize
for lazy. ;-) Well, there is a lot more great stuff on his page
that you don’t need to know to understand PTH.
There are three different types of NTLM responses:
1.
NTLM
Response
2.
NTLM2
Response, not to be confused with NTLMv2 Response
3.
NTLMv2
Response
NTLM Response
1.
Convert password to Unicode and apply MD4 hash. This is the NT
hash.
2.
Pad the NT hash with 0s to make it 21 bytes.
3.
Break the 21 bytes in to 3 keys of 7 bytes each. This is 56 bits.
4.
Apply odd parity to each key. This makes each key a valid 64 bit
DES key.
5.
Encrypt the NTLM challenge (from the server) with each of the three
keys.
6.
Concatenate the three encrypted values, creating the response.
7.
Send it.
As you can see, the challenge is provided by the server, and
could be substituted by an attacker with network access. This allows an
attacker to create pre-computed responses (rainbow tables) for that
challenge. Obviously this is scary.
NTLM2 Response
Once again, not to be confused with the NTLMv2
Response. This one uses nearly the same math as the NTLM Response, but
let’s the client add a “client challenge” thus negating the value of an
attacker substituting their own challenge. This is used when the
0x00080000- NTLM 2 session security flag is set.
1.
Convert password to Unicode and apply MD4 hash. This is the NT
hash.
2.
Pad the NT hash with 0s to make it 21 bytes.
3.
Break the 21 bytes in to 3 keys of 7 bytes each. This is 56 bits.
4.
Apply odd parity to each key. This makes each key a valid 64 bit
DES key.
5.
The client creates a random 8 byte client challenge.
6.
The server challenge and client challenge are concatenated and MD5 is
applied, creating the challenge data.
7.
Encrypt the challenge (MD5 output) with each of the three keys.
8.
Concatenate the three encrypted values, creating the response.
9.
Send it.
NTLMv2 Response
This response is next level. It is totally different
that the first two and includes a timestamp, the domain the user belongs to, as
well as target information.
1.
Convert password to Unicode and apply MD4 hash. This is the NT
hash.
2.
Concatenate the upper case Unicode username with the Unicode
authentication target.
3.
Perform HMAC-MD5 on the result of step 2, using the NT hash.
4.
Construct blob, containing the Blob signature, 4 bytes of all 0s, the
time in NT time format, the client challenge, another 4 bytes of all 0s, and
the target information from the server Type 2 (challenge) message, and another
4 bytes of all 0s.
5.
The server challenge form the Type 2 message is concatenated to the blob
from step 4.
6.
The blob from step 4 is then HMAC-MD5’d using the result of the HMAC-MD5
in step 3.
7.
The HMAC response from step 6 and the blob from 4 are concatenated and
constitute the response.
8.
Send it.
Conclusion
Pass the hash attacks are alive and well and are not going
away anytime soon. Protect your systems.