One of my friends PFE has asked me a question regarding userPassword attribute in directory which was related to some behavior he was observing in customer environment. We had a little chat about it and then I thought that maybe other has such questions as well so … here’s a topic for a blog. 

Behavior my friend was observing was related to a fact, that after some operations performed in environment customer has noticed that on some objects affected by these operations this attribute contained user password in clear text … now I can hear screams of all security guys :) … Yes, clear text and password has some connotations .. in most cases negative once.

(cc) Somewhat Frank

Of course fact that this password was there didn’t mean that it was available for anyone willing to read it … some ACLs still apply in directory … however the fact was that IT WAS THERE.

Matched DNs:
Getting 1 entries:
>> Dn: CN=jan Kowalski,OU=DRLab,DC=w2k,DC=pl
    4> objectClass: top; person; organizationalPerson; user;
    1> cn: jan Kowalski;
    1> sn: Kowalski;
    1> userPassword: P@ssw0rd!;

Whatever You thin at this point this is not a bug and there is no point in calling MSFT 112 number (if such exists at all :) ). It is expected and it is a result of userPassword attribute behavior dualism in AD.

 

 

 

userPassword …

userPassword is an attribute which can act differently when it is being written or read depending on directory configuration. Depending of directory settings it can be treated as:

  • ordinary unicode attribute which can be written and read as any other unicode attribute in directory
  • shortcut to user password in directory which will allow password change operation to be performed over LDAP.

In first case, when domain is below Windows 2003 level or at this level specific value in dsHeuristics, is not set this attribute is just an unicode attribute. We can write it and read it … let’s try:

admod -b "CN=jan Kowalski,OU=DRLab,DC=w2k,DC=pl" userPassword::P@ssword!!1

AdMod V01.10.00cpp Joe Richards (joe@joeware.net) February 2007

DN Count: 1
Using server: w2003r2base.w2k.pl:389
Directory: Windows Server 2003

Modifying specified objects...
   DN: CN=jan Kowalski,OU=DRLab,DC=w2k,DC=pl...

The command completed successfully

So we could modify this attribute … now let try to read it:

adfind -b "CN=jan Kowalski,OU=DRLab,DC=w2k,DC=pl" -s base userPassword

AdFind V01.40.00cpp Joe Richards (joe@joeware.net) February 2009

Using server: w2003r2base.w2k.pl:389
Directory: Windows Server 2003

dn:CN=jan Kowalski,OU=DRLab,DC=w2k,DC=pl
>userPassword: 5040 7373 776F 7264 2121 31

1 Objects returned

Success! So apparently we can write and read this attribute and if you will conduct this test on your own this will not affect user password in any way. We have just altered a text in a directory attribute.

However the game rules changes if we will set 9’th char in dsHeuristics to 1 (in fact according to documentation any character other than 0 or 2 should work) writes to this attribute will behave differently. After this modification userPassword attribute is write-only and we can’t read anymore.  But it will allow us to modify user password. Let see …

First dsHeuristics modification:

admod -b "CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuratio
n,DC=w2k,DC=pl" dsHeuristics::000000001

AdMod V01.10.00cpp Joe Richards (joe@joeware.net) February 2007

DN Count: 1
Using server: w2003r2base.w2k.pl:389
Directory: Windows Server 2003

Modifying specified objects...
   DN: CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,DC=w2k,DC
=pl...

The command completed successfully

Done … now let’s try to do same modification as we did earlier:

admod -b "CN=jan Kowalski,OU=DRLab,DC=w2k,DC=pl" userPassword::P@ssword!!1

AdMod V01.10.00cpp Joe Richards (joe@joeware.net) February 2007

DN Count: 1
Using server: w2003r2base.w2k.pl:389
Directory: Windows Server 2003

Modifying specified objects...
   DN: CN=jan Kowalski,OU=DRLab,DC=w2k,DC=pl...: [w2003r2base.w2k.pl] Error 0x35
(53) - Unwilling To Perform

Wow … Error, ... but why? We’ve just tried to modify user’s password over LDAP protocol and in AD this is only allowed over SSL connection which was not specified in this case. So one more try using LDAPS this time:

admod -b "CN=jan Kowalski,OU=DRLab,DC=w2k,DC=pl" userPassword::P@ssword!!1 -ssl -h w2003r2base.w2k.pl:636

AdMod V01.10.00cpp Joe Richards (joe@joeware.net) February 2007

DN Count: 1
Using server: w2003r2base.w2k.pl:636
Directory: Windows Server 2003

Modifying specified objects...
   DN: CN=jan Kowalski,OU=DRLab,DC=w2k,DC=pl...

The command completed successfully

Now it has succeed, and now read test:

adfind -b "CN=jan Kowalski,OU=DRLab,DC=w2k,DC=pl" -s base userPassword

AdFind V01.40.00cpp Joe Richards (joe@joeware.net) February 2009

Using server: w2003r2base.w2k.pl:389
Directory: Windows Server 2003

dn:CN=jan Kowalski,OU=DRLab,DC=w2k,DC=pl

1 Objects returned

Nothing. This mean that we can use userPassword attribute to modify user password but of course we can’t read it afterwards … which is somehow expected..

problem …

Actual topic which started this conversation was KTPASS tool behavior which was observed in customer environment (KTPASS is a tool which allows keytab files to be created –> keytab are used with Unix boxes to allow authentication with Kerberos against AD … in short words).

So … in cases when KTPASS was used for an account, in which none modification to dsHeuristics was made password set for account with KTPASS was available for read with LDAP from appropriate directory object. Apparently KTPASS is trying to set a password using LDAP which leaves it in this attribute. Quick test shows that this is case. If we will try to generate new keytab for an account and specify a password:

ktpass -princ HOST/ubuntu.w2k.pl@W2K.PL -mapuser ubuntu$@W2K.PL -ptype KRB5_NT_SRV_HST -mapop set -pass P@ssw0rd1 -out ubuntu.keytab

(…)

Reset UBUNTU$'s password [y/n]?  y
Key created.
Output keytab to ubuntu.keytab:
Keytab version: 0x502
keysize 60 HOST/ubuntu.w2k.pl@W2K.PL ptype 3 (KRB5_NT_SRV_HST) vno 2 etype 0x17
(RC4-HMAC) keylength 16 (0xae974876d974abd805a989ebead86846)

 

and then we will use ADFIND:

adfind -b "CN=ubuntu,OU=DRLab,DC=w2k,DC=pl" -s base userPassword

AdFind V01.40.00cpp Joe Richards (joe@joeware.net) February 2009

Using server: w2003r2base.w2k.pl:389
Directory: Windows Server 2003

dn:CN=ubuntu,OU=DRLab,DC=w2k,DC=pl
>userPassword: 5040 7373 7730 7264 31

We will see that userPassword gets populated and if you will check its value it will be password specified with KTPASS. The same will happen with any other tool which will try to use LDAP to change or reset user password in such setup.

If we will modify this behavior with setting value on dsHeuristics it will change directory behavior and userPassword will contain no trace of password data in readable form.

Solution …

I think that there is no need for special solution as we don’t have a problem. Best way is to know how it works and if we are concerned with that just use this knowledge to enforce correct behavior … either by establishing some policy around usage of tools which uses LDAP to modify password or through altering directory settings to allow password change through LDAP and thus stopping userPassword from being holding current user password just “by accident”.

Of course ACLs still applies but one might be in hard position of explaining to some AUDITOR why THE PASSWORD IS THERE. In such case … you can redirect them to my blog or better … to MSDN pages.