Illusive Labs Blog

Technical cybersecurity perspectives focusing on deceptions,
threat trends, incident response, advanced attacks and new technologies

For open source tools published by the Illusive Labs team, visit our GitHub page.

When Everyone's Dog Is Named Fluffy

Posted by Magal Baz and Tom Sela on Jan 22, 2019 2:52:15 PM

How the new Security Questions feature in Windows 10 can be used as a backdoor to establish domain-wide persistence

In April 2018, Microsoft introduced a security questions feature to enable password recovery in Windows 10. This feature allows a user to regain access to a local account by providing “correct” answers to a series of questions—questions of the sort we all know, such as “What was your first pet’s name?” and “What was your childhood nickname?”

Introducing such a feature in 2018 is unusual, so it piqued our curiosity. We decided to explore the way it is implemented and examine its security implications. Most notably, we discovered that it can be used as a unique backdoor which can be remotely distributed, hard to detect and long-lasting. In this blog, which follows our Europe 2018 BlackHat talk on this topic, we will describe this security questions feature, describe its implementation and explain the security risks it presents, focusing on its usability as a backdoor.

Part One - Implementation of Win 10 Security Questions

Security Questions Intended Usage

This feature was introduced in Windows 10 1803 release. Since this version, when you install the OS with a local administrative user, you are required to choose and answer three security questions out of six.

Windows 10 Security Questions

Later on, if you are able to match the original answers you filled in, you are permitted to reset your password. The idea is that if you ever forget your password you won’t lose access to the machine.

Windows 10 Admin View

Local Security Authority (LSA) Secrets - Introduction

First questions that come to mind regarding the feature are: where are the questions and answers stored? and, how are they protected? The answer is that they are stored (and protected) as an LSA Secret. Let’s take a closer look at this mechanism:

LSA Secrets is a system store that safely stores several important pieces of information, such as the password associated with the machine’s account in a domain. The secrets are stored inside the registry, where each secret is represented by a registry key; the name of the LSA Secret is the same as the name of its registry key. The actual data of the LSA Secret is stored in the subkeys of this key. Overall, five subkeys contain the encrypted data, timestamps and a security descriptor, as shown below.

Local Security Authority - Windows10

Access to LSA Secrets via API

LSA Secrets are protected by both encryption and ACLs. However, an administrative user on a machine can use a set of undocumented APIs in order to read and write the secrets:

  • LsaOpenSecret – Retrieves a handle to a secret
  • LsaCreateSecret – Creates a secret and retrieves its handle
  • LsaSetSecret – Changes values of a secret
  • LsaQuerySecret – Queries values of a secret

 

How LSA Secrets Are Encrypted

The binary data of an LSA Secret is stored under the CurrVal and OldVal subkeys (storing the current and previous values of the secret, respectively). It is encrypted by AES256. We describe the scheme in depth in Appendix #1. It is quite complex, but here’s the short version: You collect several pieces of information from the registry and manipulate them (concat, hash, etc.) to derive a key with which you can decrypt an LSA Secret. In other words, if someone has full access to the registry of a machine, he or she can read and write LSA Secrets on that machine.

How LSA Secrets are Encrypted

The Security Questions LSA Secrets

Each local user can have a dedicated LSA Secret that holds his or her security questions and answers, and will be used if the user ever wants to reset their password. Even if the user didn’t set security questions during installation of the OS, this LSA Secret can be written at any time (by the proper name and in the proper format) to enable this feature for the user; no other actions are required to enable it.

The name of the Security Questions LSA Secret of a user looks something like this “L$_SQSA_S-1-5-21-1023112619-1082281760-2285709724-1001”. Let’s break it down:

  • “L$” stands for Local Secret. There are several types of secrets, such as Global Secret and System Secrets. “The type of a secret defines the access and availability boundary for a given secret,” according to MS-LSAD. Local Secret means that it “can be accessed only by a client that is on the same machine as the server.” We’ll see about that.
  • “SQSA” Is the constant string that identifies security questions LSA Secrets. We couldn’t find what it stands for, but it may possibly be “Security Question Security Answers”.
  • “S-1-5-21-1023112619-1082281760-2285709724-1001” is the SID of the user to whom the Secret belongs. Each local user on a machine can have their own set of questions and answers, and the SID in the LSA Secret name identifies the owner.

SID - LSA Secret - ID Owner

The plain text form of the security questions secret is a JSON which holds the questions, answers and a version number. The JSON format is this:

{

  "version":1,

  "questions": [

             {

"question":"What was your first pet’s name?",

       "answer":"Fluffy"

},

{

"question":"What was your childhood nickname",

     "answer":"Bob"

},

{

"question":"What is the first name of your oldest cousin?",

"answer":"Jack"

}

]

}

When using the GUI to set security questions and answers you are limited to a set of six predefined questions. However, this restriction applies to what can be input through the GUI, rather than on the actual strings used as security questions. When you directly edit the JSON there are very few restrictions;  anything goes, including emojis, empty strings and extremely long strings.

Part Two - Security Implications

Security Questions - an Outdated Method

If you look for “security questions” on Wikipedia, you’ll find a nice description of how security questions were used as early as 1906 by bankers to authenticate their clients. A hundred years later, in the early 2000s, security questions became a very popular method for online user authentication and password recovery. In recent years they have largely been abandoned in favor of more advanced methods such as 2FA (two-factor authentication).

Since security questions in Windows 10 allow access to a machine equivalent to the user’s password, it makes sense to compare the two in terms of security.

First, let’s address the inherent security issues of recovery questions (issues beyond the specific implementation of the feature in Windows):

  • In these times of social networks, it’s often easy to glean the answers to security questions from the web, with or without direct interaction with the targeted person.
  • Security questions are far more vulnerable to brute force attacks, as the answers are usually short strings from a limited set of options (such as common surnames or car models).
  • For a specific user, the answer to a specific security question usually remains the same over time and across various platforms that utilize the same information.

Now let’s consider the issues that arise from the specific implementation of this feature in Windows 10:

  • While there are several mechanisms for administration of user passwords in a domain (even local user passwords), we couldn’t find any for security questions1.
  • While there is comprehensive auditing of password operations, we couldn’t find any audit functions for the security questions feature. One exception is the “Reset password” event 4724, which is triggered when you use security questions to reset a password. It is, however, not directly intended for monitoring the security questions feature, and it only pertains to the point of time when the feature is used for password reset; the earlier stage, when security questions are changed, remains unmonitored.

 

Passwords versus Security Question chart - Windows10


Proving that Security Questions Can Be Used as a Backdoor for Domain-Wide Persistence

Windows 10 Security Questions can be used in several malicious scenarios. We decided to create a Proof of Concept for one such scenario that is especially interesting to us: the use of security questions as an easily-propagated backdoor to create stealthy, domain-wide persistence. In this scenario, an attacker could change the security questions and answers for everyone in the domain to whatever they want; they could, for example, make the name of everyone’s first pet “Fluffy”.

Since the issue at question is persistence, this scenario assumes an attacker already has administrative access to a targeted machine. To create domain-wide persistence, an attacker would therefore need domain-wide privileges, such as domain admin access or credentials for a default local admin that has been placed on the machines in the domain.

This is an interesting scenario because in recent years it has become clear that in addition to compromising a network and acquiring domain admin privileges, attackers face another major challenge: to maintain their level of access in the network over long periods of time, even once their presence in the network has been detected. Developing new means of establishing domain persistence has therefore become a major area of innovation for attackers. New ideas are emerging, such as DCShadow and DACL-based methods. The method we are describing presents another effective approach for creating such persistence, exploiting new opportunities offered by the Windows 10 security questions feature.

Roadmap for our Proof-of-Concept

We created a proof-of-concept to show how an attacker with domain-wide access, let’s say domain admin credentials, can effectively distribute security questions within the domain to secure their grip on it. Taking on the role of an attacker to demonstrate our premise, we identified three challenges we would have to overcome:

  • We must be able to plant security questions remotely. Optimally, we would like to manipulate security question data even when no user on the targeted machine has already created security questions, as would commonly be the case in enterprise domain environments. To avoid leaving “tracks,” we would ideally also want to do it without executing our own code on the targeted machine, and would prefer a method that triggers no auditing events (or as few as possible).
  • We must be able to reset passwords remotely using security questions. There’s little point to planting security questions if we can’t use them afterwards to regain access to the machine. Local access to the reset password functionality may be useful for privilege escalation, but to propagate the mechanism, what we’re after is remote access.
  • After resetting the password, we need to be able change it back to the original password. Otherwise, users might notice their passwords no longer work, making the backdoor significantly less stealthy.

Reset Password - Revert Password Back

Challenge #1: Plant Security Questions Remotely

Planting security questions can be done by writing an LSA Secret. How do you remotely write LSA Secret? The API LsaSetSecret lets you do it locally. But as indicated, that’s not optimal for us, so we need to write the secret directly into the registry.

We’ve already shown, assuming you have access to the registry, how you can generate the AES key with which you can decrypt LSA secrets. Since AES is symmetric, the same key can be used to encrypt LSA Secret and write them to the registry. However, for that, we would need remote access to the registry and, more specifically, to the HKLM\SECURITY key. Remote access to registry can be done with MS-RRP (Windows Remote Registry Protocol) with RPC commands such as BaseRegQueryValue and BaseRegQueryValue.

There is, however, a question of ACLs. By default, only SYSTEM accounts can read\write to HKLM\SECURITY. Administrators do have special privileges to change ACLs, which is convenient for us. Using the RPC BaseRegSetKeySecurity, our remote administrator can give themself read\write privilege to this registry key and its subkeys, so we can overcome this problem.

This is how we accomplished remote writing of security questions:

  1. We created our own JSON with answers we planned to remember or keep somewhere safe
  2. We used BaseRegSetKeySecurity to give our administrative user read\write access to HKLM\SECURITY within the remote machine’s registry
  3. We used BaseRegQueryValue several times to get the pieces of data needed to create the key with which LSA Secrets can be encrypted and decrypted
  4. We used this key to encrypt our JSON
  5. We wrote the encrypted data to the target registry with BaseRegSetValue.

Following these steps an attacker could write security questions to a local user on a remote machine, even if the user didn’t have them enabled.

Remote Machin Access Screen

Windows 10 Security Answers

Challenge #2: Remotely Reset Passwords

Now that we have changed the target’s security questions and answers to something we know, let’s see how we can use them to remotely gain access to the machine. The reset question feature can be accessed through Winlogon. Before Vista, RDP would by default provide access to the login screen of the remote machine. However, in 2007 Network Level Authentication (NLA) was introduced to RDP and set as the default RDP authentication mechanism.

With NLA, the client is prompted to provide credentials in advance through CredSSP, and the RDP sessions is fully established only after the authentication completes. This is a great security feature with many benefits; in our case, its effect is that we can’t access the reset password screen remotely.

There is, however, a way out of this mess: When the RDP session establishment begins, the client notifies the server of the authentication methods it supports. The server then chooses one of them, or rejects the connection. In this negotiation phase, the client can specify that they don’t support CredSSP, and request that the RDP session establishment be done without NLA. If the server accepts, the session is done the “old” way, and the client is presented with the login screen, through which they can use security questions to reset the user’s password.

Other user Windows 10 Login

The easiest way to initiate an RDP session without NLA is to create an RDP connection file, and set the parameter enablecredsspsupport to “False”. Using this RDP file will create a connection with the older method of authentication, which occurs through the login screen, and which allows us to reset the password remotely.

Remote password reset - Windows 10

On the server, NLA can be marked as mandatory, in which case this connection would fail. This is an obstacle that can be addressed in the phase of the attack where we plant the persistence. When we acquire access to the remote registry to plant security questions, we should also make sure that Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp\User Authentication is set to 0, meaning NLA is not mandated on the machine. GPO can potentially be used to enforce NLA, which would therefore thwart this attack, but this is not enabled in default settings.

Challenge #3: Undo the Password Reset Operation

The necessity to change the user’s password in this process is potentially the least stealthy part of this operation. A user unable to access the machine using their previous password could certainly cause suspicion that an attacker is present. So from the attacker’s perspective, it will is a very good practice to revert to the user’s original password.

Thankfully, the password we have just overwritten is not lost; Windows stores NTLM hashes of previous passwords—by default, the last 24. The reason, according to Microsoft, is that, “If users are required to change their password, but they can reuse an old password, the effectiveness of a good password policy is greatly reduced.” When a user tries to reset a password, the new password is checked against the historic NTLM hashes to see if it matches any of them. In our case, it enables attackers to better cover their tracks.

The historic NTLM hashes are stored in the SAM key. They are protected by AES128 with a key based on the SysKey, and can be extracted with administrative access to the machine—which we have at this point in our attack scenario. By extracting the previous hash, e.g the one we just overwrote, and then reinstating it as the active NTLM hash, we can “undo” the password change operation. Setting a hash as the active one can be done with the undocumented API SamSetInformationUser.

The two steps of this procedure are implemented in Mimikatz and can be achieved using these two commands:

  • Lsadump::sam -  to retrieve the list of historic hashes
  • Lsadump:setntlm - to set the previous hash as the active hash for the user

The Implications

The method described here could be used by an attacker who seeks to create domain-wide persistence. It has several major perks in that respect:

  • It can be spread remotely without executing code on a targeted machine
  • It has no expiration date; by design, security questions are not meant to be changed
  • It is almost entirely unaudited, the only exception being the reset password event, which takes place during the later phase when persistence is being used, rather than during the earlier one when persistence is being deployed
  • It manipulates an attribute—the security questions—which is unmanaged and therefore conveniently (for the attacker) under the radar

 

Part Three - Mitigation and Remediation

There are several steps we believe Microsoft and security teams could take to minimize risk associated with security questions:

Microsoft

  • Allow auditing of security questions. We believe it would be beneficial if changes to security questions could be audited.
  • Implement a GPO that would allow security questions to be disabled inside a domain. It has been recently announced that this feature will be added to Windows 10 in the first half of 2019 (it is currently available in Insider Preview Build 18237),  and we believe this is an important move.
  • Remove the security questions feature in the Enterprise versions of Windows 10. This feature makes sense for a home consumer, but likely poses unacceptable risk in an enterprise environment.
  • Allow custom security questions. We believe offering only six questions is a weak point in the implementation of the feature. Someone wanting to use this feature may determine that answers for these specific questions are too easily guessable, and that other questions could be more effective.

Security Teams

  • Minimize prevalence of local administrators. Even before the introduction of security questions, local administors have been a security soft spot in domain environments. Because they are hard to monitor and easy to exploit, their use should be kept to a minimum in network environments.
  • Monitor local password reset events and ACL changes on HKLM\Security. This could help detect suspicious activity such as attempts to access LSA Secrets or assemble the encryption keys required to decrypt them.
  • Set GPO to enforce NLA on RDP sessions. This GPO is available, and could effectively prevent security questions from being used for remote access. In general, NLA is a great feature and enforcing it is highly recommended. The GPO is at “Computer Configuration\Administrative Templates\Windows Components\Remote Desktop Session Host\Security\Require user authentication for remote connections by using network level authentication”
  • Since there’s currently no tool for disabling or controlling the security questions feature, we’ve written one in Powershell, and you can find it on our Github page.   

Conclusion

We believe Microsoft introduces great usability features in Windows 10, but usability often comes at the expense of security. The Security Questions feature is a great example; It can be used by cyberattackers to establish a stealthy backdoor and domain-wide persistence, and raises other concerns as well. Both Microsoft and enterprise security teams should take steps to minimize the risk it presents.

 

Appendix: Psuedo Code for the Decryption Flow of LSA Secrets

The decryption flow is fully implemented in the Mimikatz and Impacket projects. Below is a pseudo-code summary of it, using the structures from Mimikatz:

  1. At HKLM\SYSTEM\CurrentControlSet\Control\Lsacontrol\LSA\ access 4 values - JD, Skew1, GBG, Data - and retrieve a DWORD from each by querying their classes.

  2. Make a 16 byte array from the 4 DWORDs (in the order in which they are listed above)

  3. Permutate the array according to this permutation array - {11, 6, 7, 1, 8, 10, 14, 0, 3, 5, 2, 15, 13, 9, 12, 4} -> the result is called SysKey.

  4. At HKLM\SECURITY\Policy\PolEkList, read default value as NT6_HARD_SECRET:

     

    typedef struct _NT6_HARD_SECRET {
    DWORD version;
    GUID KeyId;
    DWORD algorithm;
    DWORD flag;
    BYTE lazyiv[LAZY_NT6_IV_SIZE];
    union {

    NT6_CLEAR_SECRET clearSecret;

    BYTE encryptedSecret[ANYSIZE_ARRAY];

    };

    } NT6_HARD_SECRET, *PNT6_HARD_SECRET;

     

  5. Hash (SHA256) the SysKey 1000 times with laziv from PolEKList -> we’ll name the result KeyAES1

  6. Use KeyAES1 to decrypt PolEKList encryptedSecret  -> we’ll name the result LSAKey.

  7. Access a secret at HKLM\SECURITY\Policy\Secrets\<secret name>\CurrVal and read default value as NT6_HARD_SECRET.

  8. Hash (SHA256)  LSAKey 1000 times with the secret’s laziv -> we’ll name the result SecretAesKey.

  9. Use SecretAesKey to decrypt encryptedSecret from CurrVal and get the decrypted secret as NT6_CLEAR_SECRET.

    typedef struct _NT6_CLEAR_SECRET {

     

    DWORD SecretSize;
    DWORD unk0;
    DWORD unk1;
    DWORD unk2;
    BYTE  Secret[ANYSIZE_ARRAY];
    } NT6_CLEAR_SECRET, *PNT6_CLEAR_SECRET;

 

Sources:

1) It has been recently announced that such a feature is planned for release in 2019, as we will elaborate in Part Three of this article.

 

Topics: APT, Cybersecurity, Targeted Attacks, Illusive Networks, Password protection, Network Security, BlackHat, advanced persistent attacker, attack surface

Stay up to date!