Dougga here. Not a password policy blog post, I am finally off of that issue. But I couldn’t help myself and included something about passwords in this post <grin>.
Users and Computers have and attribute called UserAccountControl that dictates some behaviors and characteristics of these accounts. Active Directory administrators should be aware this attribute and how to interpret it. The value is a bitmask and features are enabled by turning on or off various bits along the mask. There are many articles on this topic (here is one), so I am simply giving you some examples to work through and a homework assignment at the end.
When viewing the UserAccountControl attribute in ADSI edit or LDP, the value is represented in Decimal or Hexidecimal. So, it is important to know how to convert the values. And since it is a bitmask, binary is needed as well. I am going to walk you through two short examples and give you a few to do on your own. I am not going to teach you how to convert the values, so use a calculator as needed.
Further down in this blog is a bitmask table with explanation of the values. I copied the table from protocol specification MS-ADTS. Review the table and you may find some familiar settings that you may have encountered. The table is needed for working the examples and homework to map the one or two letter values.
On with the examples and homework.
Example 1:
The default value for domain controllers: 532480
Convert 532480 to binary and hexidecimal:
Bin: 1000 0010 0000 0000 0000
Hex: 0x82000
Place the binary value on the top row to interpret the bit using the table below. For domain controllers the default value for domain controllers lines up TD and ST.
Note: The second row is a counter for the bit 0 – 31 (32 bits).
1 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
||||||||||||
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
X |
X |
X |
X |
X |
PS |
NA |
TA |
PE |
DR |
DK |
ND |
TD |
SR |
X |
DP |
X |
X |
ST |
WT |
ID |
X |
N |
X |
ET |
CC |
NR |
L |
HR |
X |
D |
X |
The result is:
SERVER_TRUST_ACCOUNT
TRUSTED_FOR_DELEGATION
Example 2:
A common finding on Active Directory Rap as a Service is domain controllers that have Password Not Required set. This can be reproduced by creating a computer account before joining the computer to the domain and promoting the machine to become a domain controller. In addition to the Active Directory Rap as a Service, DCdiag will discover the issue with the following output:
<SNIP FROM DCDIAG>
Starting test: MachineAccount
Checking machine account for DC DC101 on DC DC101.
Warning: Attribute userAccountControl of DC101 is:
0x82020 = ( PASSWD_NOTREQD | SERVER_TRUST_ACCOUNT | TRUSTED_FOR_DELEGATION )
Typical setting for a DC is
0x82000 = ( SERVER_TRUST_ACCOUNT | TRUSTED_FOR_DELEGATION )
DCdiag is good at showing that three bits are set
PASSWD_NOTREQD
SERVER_TRUST_ACCOUNT
TRUSTED_FOR_DELEGATION
<END DCDIAG SNIP>
Using the table again we have the same two bits from the default settings on a domain controller, but also add an additional bit to set “PASSWD_NOTREQD”.
1 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
||||||||||||
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
X |
X |
X |
X |
X |
PS |
NA |
TA |
PE |
DR |
DK |
ND |
TD |
SR |
X |
DP |
X |
X |
ST |
WT |
ID |
X |
N |
X |
ET |
CC |
NR |
L |
HR |
X |
D |
X |
Convert 1000 0010 0000 0010 0000 to decimal and hexadecimal
Dec: 532512
Hex: 0x82020
Note: to fix this issue, use ADSIedit to open the properties of the domain controller and edit the useraccountcontol attribute of the domain controller to set it to 532480.
Homework (answers below):
Use the tables below to determine what these values mean.
1) A typical user decimal value is 512 (dec)
2) A typical workstation or server value is 0x1000 (hex)
Extra Credit:
What value would you expect for an IIS server that has been trusted for delegation?
Table and bit value meanings:
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
X |
X |
X |
X |
X |
PS |
NA |
TA |
PE |
DR |
DK |
ND |
TD |
SR |
X |
DP |
X |
X |
ST |
WT |
ID |
X |
N |
X |
ET |
CC |
NR |
L |
HR |
X |
D |
X |
X |
Unused. Must be zero and ignored. |
D (ADS_UF_ACCOUNT_DISABLE, 0x00000002) |
Specifies that the account is not enabled for authentication. |
HR (ADS_UF_HOMEDIR_REQUIRED, 0x00000008) |
Specifies that the homeDirectory attribute is required. |
L (ADS_UF_LOCKOUT, 0x00000010) |
Specifies that the account is temporarily locked out. |
NR (ADS_UF_PASSWD_NOTREQD, 0x00000020) |
Specifies that the password-length policy, as specified in [MS-SAMR] section 3.1.1.8.1, does not apply to this user. |
CC (ADS_UF_PASSWD_CANT_CHANGE, 0x00000040) |
Specifies that the user cannot change his or her password. |
ET (ADS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED, 0x00000080) |
Specifies that the cleartext password is to be persisted. |
N (ADS_UF_NORMAL_ACCOUNT, 0x00000200) |
Specifies that the account is the default account type that represents a typical user. |
ID (ADS_UF_INTERDOMAIN_TRUST_ACCOUNT, 0x00000800) |
Specifies that the account is for a domain-to-domain trust. |
WT (ADS_UF_WORKSTATION_TRUST_ACCOUNT, 0x00001000) |
Specifies that the account is a computer account for a computer that is a member of this domain. |
ST (ADS_UF_SERVER_TRUST_ACCOUNT, 0x00002000) |
Specifies that the account is a computer account for a DC. |
DP (ADS_UF_DONT_EXPIRE_PASSWD, 0x00010000) |
Specifies that the password does not expire for the account. |
SR (ADS_UF_SMARTCARD_REQUIRED, 0x00040000) |
Specifies that a smart card is required to log in to the account. |
TD (ADS_UF_TRUSTED_FOR_DELEGATION, 0x00080000) |
Used by the Kerberos protocol. This bit indicates that the “OK as Delegate” ticket flag, as described in [RFC4120] section 2.8, MUST be set. |
ND (ADS_UF_NOT_DELEGATED, 0x00100000) |
Used by the Kerberos protocol. This bit indicates that the ticket-granting tickets (TGTs) of this account and the service tickets obtained by this account are not marked as forwardable or proxiable when the forwardable or proxiable ticket flags are requested. For more information, see [RFC4120]. |
DK (ADS_UF_USE_DES_KEY_ONLY, 0x00200000) |
Used by the Kerberos protocol. This bit indicates that only des-cbc-md5 or des-cbc-crc keys, as defined in [RFC3961], are used in the Kerberos protocols for this account. |
DR (ADS_UF_DONT_REQUIRE_PREAUTH, 0x00400000) |
Used by the Kerberos protocol. This bit indicates that the account is not required to present valid preauthentication data, as described in [RFC4120] section 7.5.2. |
PE (ADS_UF_PASSWORD_EXPIRED, 0x00800000) |
Specifies that the password age on the user has exceeded the maximum password age policy. |
TA (ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION, 0x01000000) |
Used by the Kerberos protocol. When set, this bit indicates that the account (when running as a service) obtains an S4U2self service ticket (as specified in [MS-SFU]) with the forwardable flag set. If this bit is cleared, the forwardable flag is not set in the S4U2self service ticket. |
NA (ADS_UF_NO_AUTH_DATA_REQUIRED, 0x02000000) |
Used by the Kerberos protocol. This bit indicates that when the Key Distribution Center (KDC) is issuing a service ticket for this account, the Privilege Attribute Certificate (PAC) MUST NOT be included. For more information, see [RFC4120]. |
PS (ADS_UF_PARTIAL_SECRETS_ACCOUNT, 0x04000000) |
Specifies that the account is a computer account for a read-only domain controller (RODC). If this bit is set, the ADS_UF_WORKSTATION_TRUST_ACCOUNT must also be set. This flag is only interpreted by a DC whose DC functional level is DS_BEHAVIOR_WIN2008 or greater. |
Homework (Answers):
1) A typical user decimal value is 512 (dec)
This converts to 10 0000 0000 Binary
0 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
|||||||||||||||||||||
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
X |
X |
X |
X |
X |
PS |
NA |
TA |
PE |
DR |
DK |
ND |
TD |
SR |
X |
DP |
X |
X |
ST |
WT |
ID |
X |
N |
X |
ET |
CC |
NR |
L |
HR |
X |
D |
X |
This lines up with N for Normal_Account
2) A typical workstation or server value is 0x1000 (hex)
This converts to 1 0000 0000 0000 Binary
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
Nice post Doug, getting deep into the weeds of AD. I’ve been using a spreadsheet Peter Geelen posted years ago
http://blog.identityunderground.be/
http://identityunderground.be/downloads/useraccountcalculator.xls
Makes the calculations much easier.
Thanks
Mike
@Michael, Need more clarification on your question. Are you trying to edit the attribute or are you trying to reset a password with the NR (0x00000020) set on an account?
Thanks for the comment Mike and the spreadsheet link. I have saved the spreadsheet to my computer for future use.
thanks for sharing.
@michael. I tested the NR in my lab and it does indeed override the domain policy (sometimes). The good part of this story, is it is not configurable in the GUI as a check box and you have to set this on purpose with an LDAP browser like ADSIedit.
With some testing, I found it interesting that the user is not permitted to create a blank password, but an admin can reset the password to a blank using ADUC and the user can log in with that blank password. Hence the "sometimes" above.
I didn’t test it further, but my guess (from my testing above) is if the password expires, the user will be forced to create a password. SO while this is definitely NOT a recommended configuration, it should be noted that it can cause issues when the password
expires if the weak "no password" requirement is truly needed. You could also set the password to never expire to avoid that – but I hate even saying that. This would be a bad thing!
I am sure that you are not doing this, but was just asking out of curiosity. So please take this as information and not targeted at you
@mez
I am not a programmer so not too quick on writing a vbscript to repro your issue. However, I did find an interesting discussion on the userAccountControl attribute (actually applies to bitmask attributes). But it appears that a basic LDAP query against the
attribute will not work. And I have used LDIFDE with LDAP queries on this attribute and had to do the same as they suggested – Link:
Post from scripting guys:http://blogs.technet.com/b/heyscriptingguy/archive/2005/05/12/how-can-i-get-a-list-of-all-the-disabled-user-accounts-in-active-directory.aspx
"That works fine for most Active Directory attributes; it doesn’t work so fine – in fact, it doesn’t work at all – for bitmask attributes. Therefore we have to rely on Plan B, and use the LDAP query syntax instead:"
Hi, I have a question about NR (ADS_UF_PASSWD_NOTREQD, 0x00000020). Using your table I found an UAC 544 and tested. Found that a blank or 1 character wasn’t accepted via standard client password reset functionality. What mitigating controls would override that? Or what are the circumstances by which the NR could be exploited?
Trying to reset a password with NR on the account from a user perspective Ctrl alt del reset password but it seems like the group policy takes precedence. Is this NRonly applicable when a privileged user resets the password in AD?
Thanks Doug. I just see this happening with a few clients who have migrated from NT 4 to 2003 then 2008 and somewhere along the line the NR appeared without specifically being set. It is a very specific usecase to compromise and would need the collusion
of someone with access to ADUC.
Hi Doug,
I have a question you might be able to answer. When I check with adsiedit.msc this attribute for a specific user, I get 0x10200 (Normal account and Password does not expire). When I check the same user using dsa.msc, I get the checkbox for the password does
not expire select, as well as user cannot change the password. My understanding is that the UserAccountControl is also covering the user cannot change the password, thus in adsiedit.exe, I shall see that reflected like 0x10240 instead.
I’m willing to use a script to read that value, but as it’s incorrect in AD already, I always can the wrong information.
This is happening using a syntax like GetObject("LDAP://") and then user.get("UserAccountControl"). When I use the old way, like GetObject("WinNT://") and then user.get("UserFlags") then it works fine.
Any hints on what is going on here?
Thanks
Patrick
Thanks Doug. I’ve looked there and while it gives useful information, I still have the same issue using that method. I’ve posted a comment/question there to follow up.