15.2 Plaintext Passwords

This is the easiest SMB authentication mechanism to implement and the least secure. It's roughly equivalent to leaving your keys in the door lock after you've parked the car. Sure, the car is locked, but...

Plaintext passwords may still be sufficient for use in small, isolated networks, such as home networks or small office environments ( assuming no disgruntled employees and a well-configured firewall on the uplink or no Internet connection at all). Plaintext passwords also provide us with a nice opportunity to get our feet wet in the mired pool of authentication. We can look at the packets and clearly see what is happening on the wire. Note, however, that many newer clients are configured to prevent the use of plaintext. Windows clients have registry entries that must be twiddled in order to permit plaintext passwords, and jCIFS did not support them at all until version 0.7.

In order to set up a workable test environment you will need a server that does not expect encrypted passwords, and a client that doesn't mind sending the passwords in the clear. That is not an easy combination to come by. Most contemporary SMB clients and servers disable plaintext by default. It is easy, however, to configure Samba so that it requests unencrypted passwords. Just change the encrypt passwords parameter to no in the smb.conf file, like so:

 ; Disable encrypted passwords. encrypt passwords = no 

Don't forget to signal smbd to reload the configuration file after making this change.

On the client side we will, once again, use the jCIFS Exists utility in our examples. If you would rather use a Windows client for your own tests, you can find a collection of helpful registry settings in the docs/Registry/ subdirectory of the Samba distribution. You will probably need to change the registry settings to permit the Windows client to send plaintext passwords. Another option as a testing tool is Samba's smbclient utility, which does not seem to argue if the server tells it not to encrypt the passwords.

This is what our updated Exists test looks like:

graphics/260fig01.gif

A few things to note:

  • The -DdisablePlainTextPasswords=false command-line option tells jCIFS that it should permit the use of plaintext.

  • The username and password are passed to jCIFS via the SMB URL. The syntax is fairly common for URLs. [2] Basically, it looks like this:

    [2] ... sort of. Support for inclusion of a password within a URL is considered very dangerous. The recommendation from the authors of RFC 2396 is that new applications should not recognize the password field and that the application should instead prompt for both the username and password.

     smb://[[user[:password]@]host[:port]] 

    The username in our example is pat .

  • The password in our example is p@ssw0rd , but the ' @ ' in the password conflicts with the ' @ ' used to separate the userinfo field from the hostport field. [3] To resolve the conflict we encode the ' @ ' in p@ssw0rd using the URL escape sequence " %40 ", which gives us p%40ssw0rd .

    [3] Yet again we seek the wisdom of the RFCs. See Appendix A of RFC 2396 for the full generic syntax of URLs, and RFC 2732 for the IPv6 update.

  • If at all possible, applications should be written to request the password in a more secure fashion, and to hide it once it has been given. The [:password] syntax is not part of the general URL syntax definition, and its use is highly discouraged. Having the password display on the screen is as naughty as sending it across the wire in plaintext.

15.2.1 User Level Security with Plaintext Passwords

User and Share Level security were described back in Section 12.4 on page 209, along with the TID and [V]UID header fields. The SecurityMode field of the NEGOTIATE PROTOCOL RESPONSE SMB will indicate the authentication expectations of the server. For User Level plaintext passwords, the value of the SecurityMode field will be 0x01 .

Below is an example SESSION_SETUP_ANDX.SMB_DATA block such as would be generated by the jCIFS Exists tool. Note, once again, that the discussion is focused on the NT LM 0.12 dialect .

 SMB_DATA  {  ByteCount = 27  Bytes    {    CaseInsensitivePassword = "p@ssw0rd"    CaseSensitivePassword   = <NULL>    Pad                     = <NULL>    AccountName             = "PAT"    PrimaryDomain           = "?"    NativeOS                = "Linux"    NativeLanMan            = "jCIFS"    }  } 

There are always fiddly little details to consider when working with SMB. In this case, we need to talk about upper- and lowercase. (bLeCH.) The example above shows that the AccountName field has been converted to uppercase. This is common practice, but it is not really necessary and some implementations don't bother. It is a holdover from the early days of SMB when lots of things (filenames, passwords, share names, NetBIOS names , bagels, and pop singers) were converted to uppercase as a matter of course. Some older servers (pre-NT LM 0.12) may require uppercase usernames, but newer servers shouldn't care. Converting to uppercase is probably the safest option, just in case...

Although the AccountName in the example is uppercase, the CaseInsensitivePassword is not. Hmmm... Odd, eh? The situation here is that some server operating systems (e.g. most Unixy OSes) use case-sensitive password verification algorithms. If the password is sent all uppercase it probably won't match what the OS expects, resulting in a login failure even though the user entered the correct password. The field may be labeled case-insensitive (and that really is what it is intended to be) but some server OSes prefer to have the original password, case preserved, just as the user entered it.

This is a sticky problem, though, because some clients insist on converting passwords to uppercase before sending them to the server. Windows 95 and '98 may do this, for example. As you might have come to expect by now, the reason for this odd behavior is backward compatibility. There are older (pre-NT LM 0.12) servers still running that will reject passwords that are not all uppercase. Windows 9x systems solve the problem by forcing all passwords to uppercase even when the NT LM 0.12 dialect has been selected. Samba's smbd server, which generally runs on case-sensitive platforms, must go through a variety of contortions to get uppercase plaintext passwords to be accepted. [4]

[4] See the discussion of the password level parameter in Samba's smb.conf(5) documentation for more information about these problems.

Another annoyance is that Windows 98 will pad the plaintext password string to 24 bytes, filling the empty space with semi-random garbage. This behavior was noted in testing, but there wasn't time to investigate the problem in-depth so it may or may not be wide-spread. Still, it's the odd case that will break things. Server implementors should be careful to both check the field length and look for the first terminating nul byte when reading the plaintext password.

In short, client-side handling of the plaintext CaseInsensitivePassword is inconsistent and problematic and the server has to compensate. That's why you need piles of SMB packet captures and lots of different clients to test against when writing a server implementation. It can be done, but it takes a bit of perseverance . When writing a new client, ensure that the client sends the password as the user intended. If that fails, and the dialect is pre-NT LM 0.12, then convert to uppercase and try again. Believe it or not, the use of challenge/response authentication bypasses much of this trouble.

...but that's only half the story. In addition to the Case In sensitivePassword field there is also a Case Sensitive Password field in the data block, and we haven't even touched on that yet. This latter field is only used if Unicode has been negotiated, and it is rare that both Unicode and plaintext will be used simultaneously . It can happen, though. As mentioned earlier, Samba can be easily configured to provide support for Unicode plaintext passwords. [5] In theory, this should be a simple switch from ASCII to Unicode. In practice, no client really supports it yet and weird things have been seen on the wire. For example:

[5] I don't know whether a Windows server can be configured to support Unicode plaintext passwords. To test against Samba, however, you need to use Samba version 3.0 or above. On the client side, Microsoft has a Knowledge Base article and a patch that addresses some of the message formatting problems in Windows 2000 (see Microsoft Knowledge Base Article #257292 ). Thanks to Nir Soffer for finding this article.

  • Clients disagree on the length of the Unicode password string in CaseSensitivePassword . Some count the pair of nul bytes that terminate the string, others do not. (For comparison, the length of the ASCII Case In sensitivePassword string does include the terminating nul, so it seems there is precedent.)

  • In testing, more than one client stored the length of the Unicode password in the Case In sensitivePassword Length field... but that's where the ASCII password length is supposed to go. The Unicode password length should be in the Case Sensitive Password Length field. How should the server interpret the password in this situation as ASCII or Unicode?

  • One client added a nul byte at the beginning of the Unicode password string, probably intended as a padding byte to force word alignment. The extra nul byte was being read as the first byte of the CaseSensitivePassword , thus misaligning the Unicode string. Another client went further and counted the extra byte in the total length of the Unicode password string. As a result, the password length was given as an odd number of bytes (which should never happen).

Empirically, it would seem that Unicode plaintext passwords were never meant to be.

An interesting fact-ette that can be gleaned from this discussion is that there is a linkage between the password fields and the negotiation of Unicode. Simply put:

ASCII (OEM character set) <==> CaseInsensitivePassword

Unicode <==> CaseSensitivePassword

That is, ASCII plaintext passwords are stored in the Case In sensitivePassword field, and Unicode plaintext passwords should be placed into the Case Sensitive Password field. Indeed, Ethereal names these two fields, respectively, "ANSI Password" and "Unicode Password" instead of using the longer names shown above. This relationship carries over to the challenge/response passwords as well, as we shall soon see.

15.2.2 Share Level Security with Plaintext Passwords

We won't spend too much time on this. It is easy to see by looking at packet captures. Basically, in Share Level security mode the plaintext password is passed to the server in the TREE CONNECT ANDX request instead of the SESSION SETUP ANDX . In the NT LM 0.12 dialect, however, a valid username should also be placed into the SESSION SETUP AccountName field if at all possible. Doing so allows the server to map Share Level security to its own user-based authentication system.

Interesting Implementation Alert

graphics/alert.gif

Samba does not completely implement Share Level security. Though all of the required SMBs are supported, Samba does not provide any way to assign a password to a share.

Many SMB clients will provide a username (if one is available) in the SESSION SETUP ANDX SMB even though it is not (technically) required at Share Level. If there is no username available, however, Samba will attempt (through various methods some of which might be considered kludgey) to guess an appropriate username for the connection. Read through the smb.conf(5) manual page if you are interested in the details.




Implementing CIFS. The Common Internet File System
Implementing CIFS: The Common Internet File System
ISBN: 013047116X
EAN: 2147483647
Year: 2002
Pages: 210

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net