smbclient Security for Windows Printing and File Transfer

by Charles Fisher on March 28, 2017
https://www.linuxjournal.com/content/smbclient-security-windows-printing-and-file-transfer

Microsoft Windows is usually a presence in most computing environments, and UNIX administrators likely will be forced to use resources in Windows networks from time to time. Although many are familiar with the Samba server software, the matching smbclient utility often escapes notice.

The "map network drive" function of Windows relies upon the Server Message Block network protocol that has evolved chiefly within the descendents of NT. The smbclient utility presents an interface reminiscent of FTP that allows file transfer to and from disk directories and printers on an NT server over SMB where sharing is enabled.

In this article, I present connection examples for Windows services, then develop a general script for pushing content to Windows shares. I discuss when the SMB protocols should be used and, more important, when they should not.

Connection Examples

Samba for UNIX is well known for server software that interoperates with clients on Windows networks. However, it also includes the smbclient program that can manipulate any SMB server. The smbclient program will be immediately familiar to those experienced with command-line FTP.

The smbclient program can query SMB servers for a list of visible shares using the -L option:


$ smbclient -L dc.somecompany.com -U nt_username -W nt_domain

Enter nt_username's password:

Domain=[NT_DOMAIN]
OS=[Windows Server 2008 R2 Standard 7601 Service Pack 1]
Server=[Windows Server 2008 R2 Standard 6.1]

     Sharename       Type      Comment
     ---------       ----      -------
     C$              Disk      Default share
     file_stash      Disk
     Fancy_laser     Printer   Really Expensive
     Cheap_laser     Printer   What a deal!

After cataloging the file and printer shares on a server, you can connect to a specific share and manipulate it. Below are examples of several types of transfers:


$ smbclient //dc.somecompany.com/file_stash -U nt_username -W nt_domain

Enter nt_username's password:

Domain=[NT_DOMAIN]
OS=[Windows Server 2008 R2 Standard 7601 Service Pack 1]
Server=[Windows Server 2008 R2 Standard 6.1]

smb: \> mkdir "smbclient test"
smb: \> cd "smbclient test
smb: \smbclient test\> prompt
smb: \smbclient test\> mput samba*
putting file samba.schema.oc.IBM-DS as
  \smbclient test\samba.schema.oc.IBM-DS
  (955.7 kb/s) (average 955.7 kb/s)
putting file samba.schema.at.IBM-DS as
  \smbclient test\samba.schema.at.IBM-DS
  (3590.1 kb/s) (average 2272.9 kb/s)
putting file samba.schema as
  \smbclient test\samba.schema
  (7454.2 kb/s) (average 4000.1 kb/s)
putting file samba.ldif as
  \smbclient test\samba.ldif
  (1615.9 kb/s) (average 2808.0 kb/s)
putting file samba-schema.IBMSecureWay as
  \smbclient test\samba-schema.IBMSecureWay
  (1023.7 kb/s) (average 2553.1 kb/s)
putting file samba-schema-netscapeds5.x.README as
  \smbclient test\samba-schema-netscapeds5.x.README
  (61.0 kb/s) (average 2336.4 kb/s)
putting file samba-schema-FDS.ldif as
  \smbclient test\samba-schema-FDS.ldif
  (5572.1 kb/s) (average 2709.8 kb/s)
putting file samba-nds.schema as
  \smbclient test\samba-nds.schema
  (247.3 kb/s) (average 862.9 kb/s)

smb: \smbclient test\> dir
  .                                   D        0  Fri Mar  3 13:31:24 2017
  ..                                  D        0  Fri Mar  3 13:31:24 2017
  samba-nds.schema                    A    19754  Fri Mar  3 13:31:24 2017
  samba-schema-FDS.ldif               A    17118  Fri Mar  3 13:31:24 2017
  samba-schema-netscapeds5.x.README      A      125  Fri Mar  3 13:31:24 2017
  samba-schema.IBMSecureWay           A     3145  Fri Mar  3 13:31:24 2017
  samba.ldif                          A    14892  Fri Mar  3 13:31:24 2017
  samba.schema                        A    22900  Fri Mar  3 13:31:24 2017
  samba.schema.at.IBM-DS              A    11029  Fri Mar  3 13:31:24 2017
  samba.schema.oc.IBM-DS              A     2936  Fri Mar  3 13:31:24 2017

              708626943 blocks of size 4096\. 95072482 blocks available

smb: \smbclient test\> lcd /tmp
smb: \smbclient test\> get samba.schema.oc.IBM-DS
getting file \smbclient test\samba.schema.oc.IBM-DS of size 2936 as
  samba.schema.oc.IBM-DS
  (409.6 KiloBytes/sec) (average 409.6 KiloBytes/sec)

smb: \> help
?              allinfo        altname        archive        backup
blocksize      cancel         case_sensitive cd             chmod
chown          close          del            dir            du
echo           exit           get            getfacl        geteas
hardlink       help           history        iosize         lcd
link           lock           lowercase      ls             l
mask           md             mget           mkdir          more
mput           newer          notify         open           posix
posix_encrypt  posix_open     posix_mkdir    posix_rmdir    posix_unlink
print          prompt         put            pwd            q
queue          quit           readlink       rd             recurse
reget          rename         reput          rm             rmdir
showacls       setea          setmode        scopy          stat
symlink        tar            tarmode        timeout        translate
unlock         volume         vuid           wdel           logon
listconnect    showconnect    tcon           tdis           tid
logoff         ..             !
smb: \> quit

A distinctive property of printer shares is that logging in and issuing any type of put will send the file transfer directly to the attached printer. Most commercial laser printers will accept PostScript output, in addition to text files with DOS-style line endings.

There have been several revisions to the SMB protocol through the years. The version 1 protocol was finalized and offered as an internet standard as the "Common Internet File System" (CIFS) in the late 1990s. Many extensions with new features were developed for CIFS by various parties, but Microsoft accepted none of them into the Windows implementation.

Windows Vista marked the first appearance of SMB2, a complete rework of the protocol, which consolidated the command set and reduced the number of round trips required for data transfers. Protocol support for SMB2 was experimentally introduced with Samba 3.5 server and went production with Samba 3.6. Note that smbclient did not receive SMB2 until the 4.1 release.

Windows 8 (and Server 2012) introduced further important improvements with SMB3, which (finally) introduced encryption and high-availability features. Protocol support for SMB3 was introduced with Samba 4.1, where the Samba server and client achieved protocol version parity.

Below is the Samba project's documentation on the various revisions of SMB:

SMB1: Original DOS/Windows LANMAN protocol, which evolved through several versions.

  • CORE: Earliest version. No concept of user names.

  • COREPLUS: Slight improvements on CORE for efficiency.

  • LANMAN1: First modern version of the protocol. Long filename support.

  • LANMAN2: Updates to Lanman1 protocol.

  • NT1: Current up to date version of the protocol. Used by Windows NT. Known as CIFS.

SMB2: Re-implementation of the SMB protocol. Used by Windows Vista and later versions of Windows. SMB2 has sub protocols available.

  • SMB2_02: The earliest SMB2 version.

  • SMB2_10: Windows 7 SMB2 version.

  • SMB2_22: Early Windows 8 SMB2 version.

  • SMB2_24: Windows 8 beta SMB2 version.

By default SMB2 selects the SMB2_10 variant.

SMB3: The same as SMB2. Used by Windows 8. SMB3 has sub protocols available.

  • SMB3_00: Windows 8 SMB3 version. (Mostly the same as SMB2_24.)

  • SMB3_02: Windows 8.1 SMB3 version.

  • SMB3_10: early Windows 10 technical preview SMB3 version.

  • SMB3_11: Windows 10 technical preview SMB3 version (maybe final).

By default SMB3 selects the SMB3_11 variant.

The smbclient program allows a specific protocol version to be locked to a server as the maximum supported revision:


-m|--max-protocol protocol

This allows the user to select the highest SMB protocol level that smbclient will use to connect to the server. By default this is set to NT1, which is the highest available SMB1 protocol. To connect using the SMB2 or SMB3 protocol, use the strings SMB2 or SMB3, respectively. Note that to connect to a Windows 2012 server with encrypted transport selecting a max-protocol of SMB3 is required.

The commentary presented upon initial login (Domain, OS and Server) can change when different protocol revisions are selected (the previous login identified Server 2008 on the same server):


$ smbclient //dc.somecompany.com/file_stash -U nt_username -W nt_domain -mSMB3

Enter nt_username's password:

Domain=[NT_DOMAIN] OS=[] Server=[]

smb: \>

Printer Script

The script below uses a number of shell features to transmit print jobs. It bundles a mechanism for prompting and setting environment variables, prompting for a password without character echo and using a named pipe (fifo) to transmit both credentials and reformatted text:


#!/bin/sh

function chkv {  # $1:var              $2:default_value    $3:prompt
 [[ -z "$(eval echo \$$1))" ]] && if [[ -z "$2" ]]
                                  then echo -n "$3"; eval read $1
                                  else eval $1=$2; fi;
}
chkv               W_DOM               YOUR_WIN_DOMAIN     ''
chkv               W_SERVER            dc.yourcompany.com  ''
chkv               W_PRINTER           office_laser        ''
chkv               W_USER              ''                  'NT Uname: '

if [[ -z "${W_PASS}" ]]
then echo -n 'NT Pass: '; stty -echo; read W_PASS; stty echo; echo ''; fi

W=$(mktemp -dt W-XXXXXX); mkfifo -m 600 "$W/fifo"

for x
do (echo -e "username=${W_USER}\npassword=${W_PASS}\ndomain=${W_DOM}" > \
    "$W/fifo"; awk 'BEGIN{ORS="\r\n"}; {print}' < "${x}" > "$W/fifo") &

   smbclient "//${W_SERVER}/${W_PRINTER}" -A "$W/fifo" \
             -c "put $W/fifo $(basename ${x}).txt"

done; rm -f "$W/fifo"; rmdir "$W"
Below is an example of a run of the script:

$ export W_USER=$LOGNAME W_SERVER=winserv.foo.com
$ export W_PRINTER=a_laser W_DOM=DFOO

$ ./winprint /etc/passwd /etc/group

NT Pass:

   Domain=[DFOO] OS=[Windows Server 2008 R2 Standard 7601 Service Pack 1]
                             Server=[Windows Server 2008 R2 Standard 6.1]
   putting file /tmp/W-s14793/fifo as \passwd.txt (130.1 kb/s)
                                          (average 130.1 kb/s)...

A few specific observations about the script:

  • The chkv function above allows settings for the credentials, server and printer to arrive from the environment, a script default, or by prompt from the user at runtime.

  • The stty calls above allow the password to be entered from the keyboard into a shell variable without an on-screen echo. It also allows the password to arrive by an environment variable, which may be a security concern for some—the /proc/self/environ file is visible to root, and many children of the parent shell might present a password that is (to them) irrelevant. For optimum security of the Windows password, remove the if/then/fi control structure and force a password prompt for every run to ensure that it never appears in /proc/self/environ. In general, some caution should be exercised in exporting environment variables with sensitive content.

  • A fifo, or "named pipe", is safely created, and this fifo serves two purposes. First, the user name/password/domain are written to it, and the fifo is closed. Next, the text file is written to the same fifo, and a "carriage return" (ASCII code 13) is added to each line as an end-of-line marker. This pair of activities is collectively launched as background processes in a subshell.

    The credentials also may be passed to smbclient on the command line with the -Uuser%password and -W domain options. This is unsafe on some platforms, as these arguments will appear in the process list (ps -ef)—one popular solution for hiding program arguments is Oracle's hide.c, but the script implements a fifo with the -A option to smbclient instead. Note that smbclient under Oracle Linux 7 scrubs the password from what is seen in ps -ef, but Oracle Linux 5 does not. For greater safety on all platforms, the credentials are passed over the fifo.

    The laser printers tested for this script did not return to the left margin when printing UNIX-style text files with only line feeds (ASCII code 10) as the end-of-line marker—a carriage return is also required for normal printing. This can be achieved without the need of a temporary disk file by passing the content over the fifo with the added CR. The awk utility was chosen for this function as it has the best POSIX portability coverage for dealing with carriage returns (this script was tested on HP-UX with minimal changes).

  • This script does not define a formal printer queue (that is, CUPS, lpd or lp), but it will allow any non-privileged user to inject content into Windows network printer queues to which they have access. Formal UNIX printer queues that accept SMB credentials are doing something similar to what is done here.

  • The script uses the default NT1 variant of SMB1—there might be cause to alter this, which is addressed in the next section.

  • Finally, this script can be just as easily used to transfer text files to a disk share with the correct DOS-style line endings (that is, the "ASCII" mode in FTP).

It would be possible to improve the efficiency of the script by launching smbclient as a "coprocess", authenticating only once, then issuing multiple puts without exiting the client. The Korn shell's long-known coprocess syntax was disregarded in the newly introduced Bash coprocesses, so such a pursuit of efficiency would require differing syntax depending upon the branch of the Bourne shell tree.

SMB Protocol Security

The unfortunate synopsis for SMB security is that, for the most part, there is none.

While the credentials establishing a login are encrypted, the network payload (that is, a print job or file transfer) is transmitted in clear text in Microsoft's SMB1 and SMB2 protocols, and there is no capability for native encryption. Microsoft introduced encryption options for SMB3, but they are not enabled by default due to performance. Sensitive content should not be transmitted over any version of SMB unless the server mandates encrypted transfers, and this is confirmed by a client attempting a clear-text login.

Samba for UNIX implemented encryption extensions for SMB1/NT1 starting with the 3.2 release in 2008. Microsoft ignored these improvements, and Windows users were forced to wait until 2012 for SMB3 encryption. Microsoft's improvements to SMB2 during this time focused foolishly on throughput, as if performance was somehow more important than security (even after total market victory, they were still struggling to beat Novell IPX/SPX technically).

Windows 7 and Server 2008 lack SMB3, and SMB transfers on these platforms with the native clients and servers are wide open. Do not transmit sensitive data using any SMB cleartext protocol over networks that you do not absolutely trust. Unfortunately, Windows 7 remains the most popular release in the field (due to the aesthetic challenges of Windows 8 and the Stalinesque oversight of Windows 10).

Windows 7 is the desktop OS leader as of February 2017 with 48.41% of the market. As Windows XP still holds 8.45%, one can say that the majority of the Windows market has chosen clear-text SMB over encryption. The Windows 7 community's refusal to upgrade has the unfortunate side effect of flooding their networks with clear-text transfers.

A workaround exists that uses third-party tools to wrap SMB in TLS encryption. The stunnel utility can cloak any version of SMB as demonstrated in a NetBSD tutorial. Unfortunately, the \localhost share is used on UNIX clients, allowing only a single encrypted connection—if you need to access two sensitive servers, you have to decide which one you love more. For Windows clients, an elaborate invocation of "localhost" interfaces configured with entirely fictitious addresses are required (abandon all sanity all who enter here)—this effectively means that "map network drive" will be far too complex for general users (and require elevated rights that they should not possess). Such drive mappings will require a knowledgeable administrator.

Note also that, when enabling Microsoft's SMB3 encryption, SMB1 must be completely disabled (Samba for UNIX does not have this problem). Microsoft has disabled SMB1 by default with Windows 10 for obvious reasons and is evangelizing the removal on older systems. The user community might prefer that Microsoft simply replace its SMB stack with Samba (one can dream). A more realistic alternative is the installation of Microsoft's native port of SSH for the secure transfer of files and print jobs, if Windows administrators finally have the will to forego the flaws of SMB (the sshfs filesystem might be of particular interest).

In any case, you can force smbclient to insist on encryption of some kind (either Samba's NT1 or SMB3 varieties) with the -e flag—it will abort when encryption is unavailable (note that you may need to set the server signing = auto configuration option on Samba for UNIX). Below is an example of a connection to an encrypted SMB1/NT1 server:


$ smbclient -e //badsmb-cleartext.somecompany.com/public -U ntid -W w_dom
Enter ntid's password:
smb_signing_good: BAD SIG: seq 1
session setup failed: NT_STATUS_ACCESS_DENIED

$ smbclient -e //samba-secure.somecompany.com/public -U ntid -W w_dom
Enter ntid's password:
Domain=[W_DOM] OS=[Unix] Server=[Samba 3.6.23-13.0.1.el5_11]
smb: \> quit;
It will be necessary to enable SMB3 to successfully connect with forced encryption
where it is supported on Windows. If you attempt forced encryption without
enabling SMB3, you might see an error similar to the following:

$ smbclient -e //smb3enc.somecompany.com/shush -U nt_username -W dom

Enter DOM\NT_USERNAME's password:

 Domain=[DOM]
 OS=[Windows Server 2012 R2 Standard 9600]
 Server=[Windows Server 2012 R2 Standard 6.3]

Encryption required and server that doesn't support UNIX extensions - failing
connect

Notice above that the OS and Server entries are populated, and there is a mention of the (NT1) UNIX extensions—this is a hint that the connection was made over SMB1. Recall that SMB3 transfers blanked out these entries.

Be especially aware that only Samba version 4.1 enabled SMB2 and SMB3 in the smbclient utility. Even though Samba 3.6 fully supported SMB2 in the server software, the client could not use it until the 4.1 release:


Jeremy Allison 2013-08-20 18:19:11 UTC

One more thing in support of this patchset for 4.1.0...

I really want to enable -e encryption for SMB3 connections from [our] client
tools. In the current climate the only rational response is [to] encrypt
everything. Let's make that possible for our users!

Jeremy.

Boosting the allowed protocol within a capable smbclient enables this behavior. With smbclient, the Windows server can even run SMB1 concurrently with the encrypted SMB3 session (a feature that is beyond the capabilities of any existing Windows client):


$ smbclient -e //smb3enc.somecompany.com/shush -U nt_username -W dom -mSMB3

Enter DOM\NT_USERNAME's password:
Domain=[DOM] OS=[] Server=[]
smb: \> quit

If smbclient -e refuses to connect to a server holding sensitive data despite a thorough exercise of available protocols, then castigate the administrator until the protocols are secured. This is particularly important if the transfers involve the public internet.

Conclusion

Some might assert that NFS under UNIX is also a clear-text protocol with the same security weaknesses as SMB. While this is very true, NFS is usually enabled by knowledgeable administrators between servers in a data center, and similarly to SMB, there are procedures to wrap it in TLS. However, SMB is used by non-administrators outside data centers over (corporate) networks that are not as physically well defended. The users who access SMB likely also have far less technical understanding of the risk to their data. The lack of any data security discussion or warnings in the Microsoft tools puts users at needless risk.

What is particularly aggravating is that Samba solved this problem in 2008 with its encryption extensions to NT1, which should have appeared in XP. Their absence is easily explained as an example of "not invented here", which is unreasonable behavior from an operating system vendor.

There are more powerful tools to manipulate SMB—the Linux kernel especially can mount a Windows share as a native network filesystem with the historic "smbmount" utility, and new implementations can be found in SMBNetFS and FuseSMB. However, as the protocol is controlled by a corporation that does not accept feedback or contributions from the user community, the more basic question is should SMB be encouraged to proliferate?

Perhaps more user-friendly SMB tools should be greeted with minimal enthusiasm for these reasons.

Disclaimer: the opinions expressed here are those of the author and do not necessarily reflect the position of Linux Journal.

2018/6/1 posted in  Network