Deep Dive into IBM Domino Security Part 1: Password Hashes
Over the past few years we’ve had the opportunity to discuss IBM Domino security at various conferences, as well as exchange views with customers about security in the IBM software space. After all of this, a valid question remains: “Is your environment as secure as possible?” We’ve decided that a blogpost series outlining key aspects of Domino security would be a great way to help you answer that question with a confident “Yes!” And since we’ll be discussing all things security, we’re going to cover securing Domino servers from both the inside and out. This first installment will start with the outside and focus specifically on an important aspect of web security: how hashing relates to HTTP passwords and web authentication.
One of the most widespread security risks We’ve found in customer environments is a Domino Web Server that remains open to the web. In these cases, the OWASP (Open Web Security Access Project) Top 10 list is very handy when setting out to properly review risks and vulnerabilities (among other things).
Regarding the Domino Web Server, Access Control Lists and authentication are both key factors in maintaining a secure environment. But authentication is a vast topic in itself. So, this article will focus on a frequently encountered security misconfiguration that potentially fits three out of 10 on the OWASP list: A2—Broken Authentication and Session Management, A5—Security Misconfiguration, and A6—Sensitive Data Exposure: HTTP Passwords.
HTTP password basics
HTTP Passwords are considered critical assets in an organization, used for Domino web access, Sametime, Quicker, as well as Traveler authentication. They are stored inside each person document, within the organization’s Names and Address Book, in an item called HTTPPassword. Domino has done an amazing job in storing passwords in a hashed format even from the very first days of the Domino Web Server (fig. 1). This is a stark contrast to some of the largest data breaches that have occurred over recent years in which passwords stored in clear text format were directly responsible for the weakness.
A few words on hashing
A hash function is any function that can be used to map data of arbitrary size to data of fixed size. Hashed values are referred to as hash codes, hash digests, hash sums, or simply hashes. It’s important to remember that hashing is one-way encoding: there is no way to decipher the original string from the hash value (as opposed to symmetrical or asymmetrical encryption algorithms). The fixed hash value is simply meant to verify the integrity of the initial clear text using a verification algorithm (see fig. 2).
Hashing in Domino
Although scarcely documented, Domino uses three hashing algorithm versions. And as we’ll see, it is extremely important to ensure that you’ve upgraded to the latest version. Let’s examine the attributes of these algorithms.
Version 1 (V1), (SEC_pwddigest_V1)
Used in Domino versions prior to version 6.
This hashing algorithm has been in use since the Domino web server was first introduced. The hash attributes for version 1 are as follows:
- Character set: 34 characters long, hexadecimal character set (A-F, 0-9), starts and ends in parentheses
- Running the algorithm against the same plain text always results in the same cipher text
- Can be invoked using the formula
@Password("PlainTextValue")
or, in LotusScript,Evaluate("Password(PlainTextValue)")
- Can be verified using the formula
@VerifyPassword(“PlainTextValue”;”CipherTextValue”)
or, in LotusScript,@Password(“PlainTextValue”)=”CipherTextValue”
- Example hash (in this case, the one and only V1 hash of the password “password”):(355E98E7C7B59BD810ED845AD0FD2FC4)
Version 2 (V2), (SEC_pwddigest_V2)
Introduced in Domino version 6, this is significantly more secure than version 1, primarily because it produces a salted hash value. This means that, in the case of V2, an ever-changing, 5-byte-length variant (also known as salt) is used when generating the cipher text (fig. 3).
This means that every time the algorithm is run, the resulting cipher text will be different from the previous one.
The hash attributes for version 2 are as follows:
- Character set: 22 characters long, extended character set (A-Z including upper and lower case, 0-9 plus special characters), starts with “(G” and ends in “)”
- Can be invoked using the formula
@Hashpassword(“PlainTextValue”)
- $SecurePassword item with value of “1” present in documents with upgraded V2 hashes
- Can only be verified using the formula
@VerifyPassword(“PlainTextValue”;”CipherTextValue”)
@Password(“PlainTextValue”)=”CipherTextValue”
will no longer work, since the hash changes every time the algorithm is used.
- Example hash (in this case, one of the many potential hashes for the password “password”):(GdYsi0QObJfHsp4NgUrq)
Version 3 (V3), (SEC_pwddigest_V3)
This is the current, and latest, hashing algorithm that was made available for use as of Domino 8.0. It’s a salted hashing algorithm with a much larger space for hash values due to its increased length; this makes it far less vulnerable to Hash Collision.
What is Hash Collision? Hash collision occurs when a given hash accidentally returns true when verified against two different strings.
Take the Version 1 Domino hash as an example. Due to a relatively limited character set (A-F and 0-9), each character space has 16 possibilities, and thus allows for recurring characters within the hash’s 20-character length (not counting parentheses). Looking at the maximum amount of variations, the total amount of possible character combinations totals 16²º, just a bit over one septillion possibilities.
It won’t necessarily happen after generating exactly that number of hashes, but after exhausting all possibilities, we can be sure that we’d find at least one hash in there that verifies at least two different plain texts.
Read more on Hash Collision here: https://en.wikipedia.org/wiki/Collision_(computer_science)
The hash attributes for version 3 are as follows:
- Character set: 51 characters long, same character set as version 2 (A-Z including upper and lowercase, 0-9 plus special characters) starts with “(H” and ends in “)”
- Can only be invoked using the SECHashPassword3() API call
- $SecurePassword item with value of “2” present in documents with upgraded V3 hashes
- Can only be verified using the formula
@VerifyPassword(“PlainTextValue”;”CipherTextValue”)
@Password(“PlainTextValue”)=”CipherTextValue”
will no longer work, since the hash changes every time the algorithm is used.
- Example hash (in this case, one of the many potential hashes for the password “password”):(H3OkCfpyzvTyfNSdxaneVC30mC30mC3KmC30mCbiAfUHd15MP)
Hash vulnerabilities
As stated earlier, hashed values can’t be decoded directly, but they are vulnerable to dictionary attacks (systematically probing a list of strings or passwords against a given hash). However, the effectiveness of such attacks varies between the 3 different hash versions explained above. Let’s take a closer look at these differences.
Version 1 hashes: Hashed values are designed to be verified against the plain text values using a verification algorithm. This algorithm comes with a built-in “figleaf”, or delay, protection; continuous attempts will be delayed longer and longer, making such attacks extremely inefficient.
Version 1 hashing, however, does not use a salt; running the hashing algorithm on the same plain text will always return the same cipher text. This means that a given version 1 hash can also be verified using the initial algorithm @Password([VerificationWordList])=”CipherTextValue”
which means that using this method, the delay protection can be bypassed, thereby making version 1 hashes extremely vulnerable to dictionary attacks.
Another aspect of this non-salted method is that if two users end up using the same password, their hashes will match. This can easily be recognized by an attacker who has gained access to the organizations Names and Address Book, or a rogue insider user for that matter.
Differences in effort required to crack V1, V2, and V3
As a proof of concept, we built a quick LotusScript solution to demonstrate the significant difference in effort required to crack non-salted vs. salted hash digests. Here are two example scenarios:
Scenario 1
Attempting to crack one V1 hash using a 231 KB text file containing 23300 passwords
For this scenario we used the @Password(“CURRENT_PASSWORDLISTITEM”)=HTTPPassword algorithm to see if we get a match.
The results:
The password was found in 5.511 seconds and during this time 12033 passwords were evaluated against the password hash—quite an efficient crack (see fig. 4).
Scenario 2
Attempting to try ONE password string against 3 different documents with V2 hashing
Since V2 hashes are salted, we can only rely on the official verification algorithm which—as previously stated—comes with a delay protection built in.
The algorithm we used is
@VerifyPassword(“CURRENT_PASSWORDLISTITEM”;HTTPPassword)
The results:
We only tried to check one password against three different V2, salted hash digests. The password was NOT found. What’s more, the three password verification attempts (one per document) took 30.800 seconds (see fig. 5).
Keeping this in mind, V2 clearly offers a vast amount of advantages of V1, not only in it being a salted hash algorithm, but also it’s resistance to brute-force attempts.
Protecting Hashes
To even attempt an attack on HTTPPassword hashes, the would-be attacker would first need to get to the hash value. There are two ways to do this: either by using a protocol like HTTP(S), IMAP, SMTP, or POP3, or by gaining access to the hash itself either through the web (through a names.nsf with and incorrect ACL that allows anonymous users to access person documents) or from the inside.
There are two important security considerations here:
1) Make sure you use the Internet Password Lockout feature. This lets you set a threshold of login attempts and have the user in question locked out once this threshold is met. IBM Domino 8.5.3 FP6 and later supports HTTP(S), LDAP and SMTP; and with IBM Domino 9.0.1 installed, supported protocols also include POP3 and IMAP.
TIP: Once this feature is enabled, a server restart is required.
2) Whichever hash version you’re using (V1, V2, or V3), the default NAB configuration will allow users to see other users’ passwords. Even a user with Editor access could create a local view that would identify hash versions (see fig. 6) and, in the case of V1 hashes, outline users with the same passwords.
There is a great (yet little known) feature in Domino that allows you to specify an additional layer of security on top of ACLs for any database: Extended ACLs or xACLs. This feature lets you restrict users from viewing the HTTPPassword item value for other users—a highly recommended security measure to implement.
Upgrading Hash Versions
Since we’ve established that V2 and V3 are significantly more secure than V1, let’s see how we can go about ensuring our HTTPPasswords are upgraded. This two-step process first requires us to edit the Domino Directory Profile by selecting ‘Yes – Password verification compatible with Notes/Domino release 8.0.1 or greater for version 3′ (see fig. 7).
It’s important to note that once this setting is in place, old hashes will be upgraded to the selected new (V2 or V3) format ONLY when a person document is put into edit mode and then saved. This upgrade is carried out by appending a text-type item called $SecurePassword with value “1” for V2 and “2” for V3. This is the reason why we still see customers with correct Domino Directory Profile settings, but person documents stuck with old hash versions.
Fortunately, there is a quick-and-easy remedy; there is a Domino feature that will let you upgrade all person documents manually. To use this, simply select all documents and select the ‘Upgrade to More Secure Internet Password’ option found in the Actions menu (see fig. 8).
This will not have any adverse impact on your users, and won’t disrupt web or other authentication using HTTPPassword hashes. The combination of these two actions, setting directory profile and upgrading password hashes, will ensure you’re using the latest, salted hashes and make your environment significantly more secure.
Auditing your NAB using scanEZ
After all of this you might be wondering “But what does this have to do with Ytria?” It turns out that we can help with this; we’ve used scanEZ quite a few times to help customers audit their person documents and spot password issues.
The Values function lets us instantly read out item values such as password hashes, using the HTTPPassword and $$SecurePassword items, to get a quick overview of our password situation for all person documents.
Once the information is propagated to the Values window, a single grouping using the HTTPPassword item values will reveal users with old password formats that happen to have the same password (see fig. 9).
The flexYgrid-enabled Values window has an additional function that lets you add custom columns whose cell values are selected using formulas. In this case, we could use a formula to display the hashes and their versions for multiple documents (see fig. 10).
Using this function, we can quickly spot any person documents with older hash versions, isolate them by adding them to a new MySelection folder, and even set new passwords for all the documents in question by using the formula @Hashpassword(“NewPassword”) directly within scanEZ.
Weak HTTPPassword hashes and ACL misconfigurations are tied for first place when it comes to vulnerabilities. But now, with an understanding of how hashing works, what to look for when auditing your environment, and how to upgrade to more secure password storage, you’re well equipped to make your infrastructure much more resilient and secure in the modern online environment.
In our next blogpost, we’ll be discussing strategies to secure your applications and web servers through security documents, ACLs, custom login pages, and more. In the meantime, if you have anything to add, or other angles that you’d like to discuss, we’d love to hear from you!
Great job! Thank you, Ben.
Very informative, thanks Ben.
Danke dir Ben!
Hi Ben,
great job.
One question / hint:
Whats about the problem with Version 3 hashes and jconsole?
As far as I know that isnt solved, yet.
Thomas
Hi Thomas,
If you don’t want to reduce the security of all your NAB’s user (except for the admin’s one…) the workaround is to reduce the hash in the person document ($SecurePassword = 1 ), then re-enter a password and finally delete Data/admindata.xml on your server (it contain the hash)…. don’t forget to remove IPV6, set TCPIP_ControllerTcpIpAddress et ServerController in server’s notes.ini if you want a remote access
Thanks IBM’s support as usual….
Is there a way to generate the V3 password hash outside of Domino?
Background:
We’d like to be able to set the password on another machine
without transmitting the clear password to the Domino server
to get it hashed there. We’d like to submit the hashed value to
a REST web service running on Domino without sending the
clear text version.
These hashed version would be then put into the
httpPassword field to be used by Domino in the Domino Directory.
You will need a Notes client or a Domino server to get a hashed value that will match.
These V3 password functions don’t use standard algorithm, so no public solution will work.
You will need to use another encryption scheme, that will send the info to Domino, which will need to decrypt it and then use the V3 password hash to put in the httpPassword field.