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:
A few things to note:
15.2.1 User Level Security with Plaintext PasswordsUser 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]
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:
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:
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 PasswordsWe 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
|