Home page logo
/
Intro Reference Guide Book Install Guide
Download Changelog Zenmap GUI Docs
Bug Reports OS Detection Propaganda Related Projects
In the Movies In the News

Library smb

Implements functionality related to Server Message Block (SMB, also known as CIFS) traffic, which is a Windows protocol.

SMB traffic is normally sent to/from ports 139 or 445 of Windows systems. Other systems implement SMB as well, including Samba and a lot of embedded devices. Some of them implement it properly and many of them not. Although the protocol has been documented decently well by Samba and others, many 3rd party implementations are broken or make assumptions. Even Samba's and Windows' implementations aren't completely compatiable. As a result, creating an implementation that accepts everything is a bit of a minefield.

Where possible, this implementation, since it's intended for scanning, will attempt to accept any invalid implementations it can, and fail gracefully if it can't. This has been tested against a great number of weird implementations, and it now works against all of them.

The intention of this library is to eventually handle all aspects of the SMB protocol. That being said, I'm only implementing the pieces that I (Ron Bowes) need. If you require something more, let me know and I'll put it on my todo list.

A programmer using this library should already have some knowledge of the SMB protocol, although a lot isn't necessary. You can pick up a lot by looking at the code. The basic login/logoff is this:

[connect]
C->S SMB_COM_NEGOTIATE
S->C SMB_COM_NEGOTIATE
C->S SMB_COM_SESSION_SETUP_ANDX
S->C SMB_COM_SESSION_SETUP_ANDX
C->S SMB_COM_TREE_CONNECT_ANDX
S->C SMB_COM_TREE_CONNECT_ANDX
...
C->S SMB_COM_TREE_DISCONNECT
S->C SMB_COM_TREE_DISCONNECT
C->S SMB_COM_LOGOFF_ANDX
S->C SMB_COM_LOGOFF_ANDX
[disconnect]

In terms of functions here, the protocol is:

status, smbstate = smb.start(host)
status, err      = smb.negotiate_protocol(smbstate, {})
status, err      = smb.start_session(smbstate, {})
status, err      = smb.tree_connect(smbstate, path, {})
...
status, err      = smb.tree_disconnect(smbstate)
status, err      = smb.logoff(smbstate)
status, err      = smb.stop(smbstate)

The stop function will automatically call tree_disconnect and logoff, cleaning up the session, if it hasn't been done already.

To initially begin the connection, there are two options:

1) Attempt to start a raw session over 445, if it's open.

2) Attempt to start a NetBIOS session over 139. Although the protocol's the same, it requires a session request packet. That packet requires the computer's name, which is requested using a NBSTAT probe over UDP port 137.

Once it's connected, a SMB_COM_NEGOTIATE packet is sent, requesting the protocol "NT LM 0.12", which is the most commonly supported one. Among other things, the server's response contains the host's security level, the system time, and the computer/domain name. Some systems will refuse to use that protocol and return "-1" or "1" instead of 0. If that's detected, we kill the connection (because the protocol following won't work).

If that's successful, SMB_COM_SESSION_SETUP_ANDX is sent. It is essentially the logon packet, where the username, domain, and password are sent to the server for verification. The username and password are generally picked up from the program parameters, which are set when running a script, or from the registry where it can be set by other scripts (for example, smb-brute.nse). However, they can also be passed as parameters to the function, which will override any other username/password set.

If a username and password are set, they are used for the first login attempt. If a login fails, or they weren't set, a connection as the 'GUEST' account with a blank password is attempted. If that fails, then a NULL session is established, which should always work. The username/password will give the highest access level, GUEST will give lower access, and NULL will give the lowest (often, NULL will give no access).

The actual login protocol used by SMB_COM_SESSION_SETUP_ANDX is explained in detail in smbauth.lua.

Thanks go to Christopher R. Hertel and his book Implementing CIFS, which taught me everything I know about Microsoft's protocols. Additionally, I used Samba's list of error codes for my constants. Although I don't believe they would be covered by GPL, since they're public now anyways, but I'm not a lawyer and, if somebody feels differently, let me know and we can sort this out.

Scripts that use this module can use the script arguments listed below example of using these script arguments:

nmap --script=smb-<script>.nse --script-args=smbuser=ron,smbpass=iagotest2k3,smbbasic=1,smbsign=force <host>

Author:
Ron Bowes <ron@skullsecurity.net>

Copyright© Same as Nmap--See http://nmap.org/book/man-legal.html

Source: http://nmap.org/svn/nselib/smb.lua

Script Arguments

smbbasic

Forces the authentication to use basic security, as opposed to "extended security". Against most modern systems, extended security should work, but there may be cases where you want to force basic. There's a chance that you'll get better results for enumerating users if you turn on basic authentication.

smbsign

Controls whether or not server signatures are checked in SMB packets. By default, on Windows, server signatures aren't enabled or required. By default, this library will always sign packets if it knows how, and will check signatures if the server says to. Possible values are:

  • force: Always check server signatures, even if server says it doesn't support them (will
probably fail, but is technically more secure).
  • negotiate: [default] Use signatures if server supports them.
  • ignore: Never check server signatures. Not recommended.
  • disable: Don't send signatures, at all, and don't check the server's. not recommended.
More information on signatures can be found in smbauth.lua.

randomseed

Set to a value to change the filenames/service names that are randomly generated.

smbport

Override the default port choice. If smbport is open, it's used. It's assumed to be the same protocol as port 445, not port 139. Since it probably isn't possible to change Windows' ports normally, this is mostly useful if you're bouncing through a relay or something.

Functions

add_account (host, username, domain, password, password_hash, hash_type, is_admin)

Wrapper around smbauth.add_account.

close_file (smb, overrides)

This sends a SMB request to close a file (or a pipe).

create_file (smb, path, overrides)

This sends a SMB request to open or create a file. Most of the parameters I pass here are used directly from a packetlog, especially the various permissions fields and flags. I might make this more adjustable in the future, but this has been working for me.

delete_file (smb, path, overrides)

This sends a SMB request to delete a file (or a pipe).

disable_extended (smb)

Turn off extended security negotiations for this connection. There are a few reasons you might want to do that, the main ones being that extended security is going to be marginally slower and it's not going to give the same level of information in some cases (namely, it doesn't present the server's name).

file_delete (host, share, remotefile)

Delete a file from the remote machine

file_read (host, share, remotefile, use_anonymous, overrides)

Write given data to the remote machine on the given share. This is similar to file_upload, except the data is given as a string, not a file.

file_upload (host, localfile, share, remotefile, overrides, encoded)

Upload a file from the local machine to the remote machine, on the given share.

file_write (host, data, share, remotefile, use_anonymous)

Write given data to the remote machine on the given share. This is similar to file_upload, except the data is given as a string, not a file.

files_exist (host, share, files, overrides)

Check how many files, in a given list, exist on the given share.

get_account (host)

Wrapper around smbauth.get_account.

get_mutex (smbstate)

Returns the mutex that should be used by the current connection. This mutex attempts to use the name, first, then falls back to the IP if no name was returned.

get_os (host)

Retrieve information about the host's operating system. This should always be possible to call, as long as there isn't already a SMB session established.

get_overrides (username, domain, password, password_hash, hash_type, overrides)

Create an 'overrides' table

get_overrides_anonymous (overrides)

Get an 'overrides' table for the anonymous user

get_port (host)

Determines whether or not SMB checks are possible on this host, and, if they are, which port is best to use. This is how it decides:

get_socket_info (host)

Basically a wrapper around socket:get_info, except that it also makes a SMB connection before calling the get_info function. Returns the mac address as well, for convenience.

get_status_name (status)

Convert a status number from the SMB header into a status name, returning an error message (not nil) if it wasn't found.

get_subnames (name)

This function will take a string like "a.b.c.d" and return "a", "a.b", "a.b.c", and "a.b.c.d". This is used for discovering NetBIOS names. If a NetBIOS name is unknown, the substrings of the DNS name can be used in this way.

get_uniqueish_name (host, extension, seed)

Generate a string that's somewhat unique, but is based on factors that won't change on a host. At the moment, this is a very simple hash based on the IP address. This hash is *very* likely to have collisions, and that's by design -- while it should be somewhat unique, I don't want it to be trivial to uniquely determine who it originated from.

get_windows_version (os)

Converts numbered Windows version strings ("Windows 5.0", "Windows 5.1") to names ("Windows 2000", "Windows XP").

is_admin (host, username, domain, password, password_hash, hash_type)

Determines, as accurately as possible, whether or not an account is an administrator. If there is an error, 'false' is simply returned.

lock_mutex (smbstate, func)

Locks the mutex being used by this host. Doesn't return until it successfully obtains a lock.

logoff (smb, overrides)

Logs off the current user. Strictly speaking this isn't necessary, but it's the polite thing to do.

message_check_signature (smb, body)

Check the signature of the message. This is the opposite of message_sign, and works the same way (replaces the signature with the sequence number, calculates hash, checks)

message_sign (smb, body)

Sign the message, if possible. This is done by replacing the signature with the sequence number, creating a hash, then putting that hash in the signature location.

negotiate_protocol (smb, overrides)

Sends out SMB_COM_NEGOTIATE, which is typically the first SMB packet sent out. Sends the following:

  • List of known protocols

read_file (smb, offset, count, overrides)

This sends a SMB request to read from a file (or a pipe).

send_transaction_named_pipe (smb, function_parameters, function_data, pipe, no_setup, overrides)

This is the core of making MSRPC calls. It sends out a MSRPC packet with the given parameters and data. Don't confuse these parameters and data with SMB's concepts of parameters and data -- they are completely different. In fact, these parameters and data are both sent in the SMB packet's 'data' section.

share_anonymous_can_read (host, share)

Check whether or not a share is accessible by the anonymous user. Assumes that share_host_returns_proper_error has been called and returns true.

share_anonymous_can_write (host, share)

Determine whether or not the anonymous user has write access on the share. This is done by creating then deleting a file.

share_find_writable (host)

Find a share that the current user can write to. Return it, along with its path. If no share could be found, an error is returned. If the path cannot be determined, the returned path is nil.

share_get_details (host, share)

Get all the details we can about the share. These details are stored in a table and returned.

share_get_list (host)

Retrieve a list of fileshares, along with any details that could be pulled. This is the core of smb-enum-shares.nse, but can also be used by any script that needs to find an open share.

share_host_returns_proper_error (host)

Determine whether or not a host will accept any share name (I've seen this on certain systems; it's bad, because it means we cannot tell whether or not a share exists).

share_user_can_read (host, share)

Check whether or not a share is accessible by the current user. Assumes that share_host_returns_proper_error has been called and returns true.

share_user_can_write (host, share)

Determine whether or not the current user has read or read/write access on the share. This is done by creating then deleting a file.

smb_encode_data (data, overrides)

Converts a string containing the data section into the encoded data string. The encoding is simple:

  • (2 bytes) The number of bytes in the data section
  • (variable) The data section
This is automatically done by smb_send.

smb_encode_header (smb, command, overrides)

Creates a string containing a SMB packet header. The header looks like this:

smb_encode_parameters (parameters, overrides)

Converts a string containing the parameters section into the encoded parameters string. The encoding is simple:

  • (1 byte) The number of 2-byte values in the parameters section
  • (variable) The parameter section
This is automatically done by smb_send.

smb_read (smb, read_data)

Reads the next packet from the socket, and parses it into the header, parameters, and data.

smb_send (smb, header, parameters, data, overrides)

Prepends the NetBIOS header to the packet, which is essentially the length, encoded in 4 bytes of big endian, and sends it out. The length field is actually 17 or 24 bits wide, depending on whether or not we're using raw, but that shouldn't matter.

start (host)

Begins a SMB session, automatically determining the best way to connect. Also starts a mutex with mutex_id. This prevents multiple threads from making queries at the same time (which breaks SMB).

start_ex (host, negotiate_protocol, start_session, tree_connect, create_file, disable_extended, overrides)

Initiates a SMB connection over whichever port it can, then optionally sends the common initialization packets. Note that each packet depends on the previous one, so if you want to go all the way up to create_file, you have to set all parameters.

start_netbios (host, port, name)

Begins a SMB session over NetBIOS. This requires a NetBIOS Session Start message to be sent first, which in turn requires the NetBIOS name. The name can be provided as a parameter, or it can be automatically determined.

start_raw (host, port)

Begins a raw SMB session, likely over port 445. Since nothing extra is required, this function simply makes a connection and returns the socket.

start_session (smb, overrides, log_errors)

Sends out SMB_COM_SESSION_SETUP_ANDX, which attempts to log a user in. Sends the following:

  • Negotiated parameters (multiplexed connections, virtual circuit, capabilities)
  • Passwords (plaintext, unicode, lanman, ntlm, lmv2, ntlmv2, etc)
  • Account name
  • OS (I just send "Nmap")
  • Native LAN Manager (no clue what that is, but it seems to be ignored)

stop (smb)

Kills the SMB connection, closes the socket, and releases the mutex. Because of the mutex being released, a script HAS to call stop before it exits, no matter why it's exiting!

tree_connect (smb, path, overrides)

Sends out SMB_COM_SESSION_TREE_CONNECT_ANDX, which attempts to connect to a share. Sends the following:

  • Password (for share-level security, which we don't support)
  • Share name
  • Share type (or "?????" if it's unknown, that's what we do)

tree_disconnect (smb, overrides)

Disconnects a tree session. Should be called before logging off and disconnecting.

unlock_mutex (smbstate, func)

Unlocks the mutex being used by this host.

write_file (smb, write_data, offset, overrides)

This sends a SMB request to write to a file (or a pipe).



Functions

add_account (host, username, domain, password, password_hash, hash_type, is_admin)

Wrapper around smbauth.add_account.

Parameters

  • host:
  • username:
  • domain:
  • password:
  • password_hash:
  • hash_type:
  • is_admin:
close_file (smb, overrides)

This sends a SMB request to close a file (or a pipe).

Parameters

  • smb: The SMB object associated with the connection
  • overrides: The overrides table

Return value:

(status, result) If status is false, result is an error message. Otherwise, result is undefined.
create_file (smb, path, overrides)

This sends a SMB request to open or create a file. Most of the parameters I pass here are used directly from a packetlog, especially the various permissions fields and flags. I might make this more adjustable in the future, but this has been working for me.

Parameters

  • smb: The SMB object associated with the connection
  • path: The path of the file or pipe to open
  • overrides: [optional] Overrides for various fields

Return value:

(status, result) If status is false, result is an error message. Otherwise, result is a table containing a lot of different elements, the most important one being 'fid', the handle to the opened file.
delete_file (smb, path, overrides)

This sends a SMB request to delete a file (or a pipe).

Parameters

  • smb: The SMB object associated with the connection
  • path: The path of the file to delete
  • overrides: The overrides table

Return value:

(status, result) If status is false, result is an error message. Otherwise, result is undefined.
disable_extended (smb)

Turn off extended security negotiations for this connection. There are a few reasons you might want to do that, the main ones being that extended security is going to be marginally slower and it's not going to give the same level of information in some cases (namely, it doesn't present the server's name).

Parameters

  • smb: The SMB state table.
file_delete (host, share, remotefile)

Delete a file from the remote machine

Parameters

  • host: The host object
  • share: The share to upload it to (eg, C$).
  • remotefile: The remote file on the machine. It is relative to the share's root. It can be a string, or an array.

Return value:

(status, err) If status is false, err is an error message. Otherwise, err is undefined.
file_read (host, share, remotefile, use_anonymous, overrides)

Write given data to the remote machine on the given share. This is similar to file_upload, except the data is given as a string, not a file.

Parameters

  • host: The host object
  • share: The share to read it from (eg, C$).
  • remotefile: The remote file on the machine. It is relative to the share's root.
  • use_anonymous: [optional] If set to 'true', test is done by the anonymous user rather than the current user.
  • overrides: [optional] Override various fields in the SMB packets.

Return value:

(status, err) If status is false, err is an error message. Otherwise, err is undefined.
file_upload (host, localfile, share, remotefile, overrides, encoded)

Upload a file from the local machine to the remote machine, on the given share.

Parameters

  • host: The host object
  • localfile: The file on the local machine, relative to the nmap path
  • share: The share to upload it to (eg, C$).
  • remotefile: The remote file on the machine. It is relative to the share's root.
  • overrides: A table of override values that's passed to the smb functions.
  • encoded: Set to 'true' if the file is encoded (xor'ed with 0xFF), It will be decoded before upload. Default: false

Return value:

(status, err) If status is false, err is an error message. Otherwise, err is undefined.
file_write (host, data, share, remotefile, use_anonymous)

Write given data to the remote machine on the given share. This is similar to file_upload, except the data is given as a string, not a file.

Parameters

  • host: The host object
  • data:
  • share: The share to upload it to (eg, C$).
  • remotefile: The remote file on the machine. It is relative to the share's root.
  • use_anonymous: [optional] If set to 'true', test is done by the anonymous user rather than the current user.

Return value:

(status, err) If status is false, err is an error message. Otherwise, err is undefined.
files_exist (host, share, files, overrides)

Check how many files, in a given list, exist on the given share.

Parameters

  • host: The host object
  • share: The share to read it from (eg, C$).
  • files: A list of files to look for; it is relative to the share's root.
  • overrides: [optional] Override various fields in the SMB packets.

Return values:

  1. status: A true/false value indicating success
  2. count: The number of files that existed, or an error message if status is 'false'
  3. files: A list of the files that existed.
get_account (host)

Wrapper around smbauth.get_account.

Parameters

  • host:
get_mutex (smbstate)

Returns the mutex that should be used by the current connection. This mutex attempts to use the name, first, then falls back to the IP if no name was returned.

Parameters

  • smbstate: The SMB object associated with the connection

Return value:

A mutex
get_os (host)

Retrieve information about the host's operating system. This should always be possible to call, as long as there isn't already a SMB session established.

Parameters

  • host: The host object

Return value:

(status, data) If status is true, data is a table of values; otherwise, data is an error message.
get_overrides (username, domain, password, password_hash, hash_type, overrides)

Create an 'overrides' table

Parameters

  • username:
  • domain:
  • password:
  • password_hash:
  • hash_type:
  • overrides:
get_overrides_anonymous (overrides)

Get an 'overrides' table for the anonymous user

Parameters

  • overrides: [optional] A base table of overrides. The appropriate fields will be added.
get_port (host)

Determines whether or not SMB checks are possible on this host, and, if they are, which port is best to use. This is how it decides:

  • If port tcp/445 is open, use it for a raw connection
  • Otherwise, if ports tcp/139 and udp/137 are open, do a NetBIOS connection. Since UDP scanning isn't default, we're also ok with udp/137 in an unknown state.

Parameters

  • host: The host object.

Return value:

The port number to use, or nil if we don't have an SMB port
get_socket_info (host)

Basically a wrapper around socket:get_info, except that it also makes a SMB connection before calling the get_info function. Returns the mac address as well, for convenience.

Parameters

  • host: The host object

Return values:

  1. status: true for successful, false otherwise.
  2. If status is true, the local ip address; otherwise, an error message.
  3. The local port (not really meaningful, since it'll change next time).
  4. The remote ip address.
  5. The report port.
  6. The mac address, if possible; nil otherwise.
get_status_name (status)

Convert a status number from the SMB header into a status name, returning an error message (not nil) if it wasn't found.

Parameters

  • status: The numerical status.

Return value:

A string representing the error. Never nil.
get_subnames (name)

This function will take a string like "a.b.c.d" and return "a", "a.b", "a.b.c", and "a.b.c.d". This is used for discovering NetBIOS names. If a NetBIOS name is unknown, the substrings of the DNS name can be used in this way.

Parameters

  • name: The name to take apart

Return value:

An array of the sub names
get_uniqueish_name (host, extension, seed)

Generate a string that's somewhat unique, but is based on factors that won't change on a host. At the moment, this is a very simple hash based on the IP address. This hash is *very* likely to have collisions, and that's by design -- while it should be somewhat unique, I don't want it to be trivial to uniquely determine who it originated from.

TODO: At some point, I should re-do this function properly, with a method of hashing that's somewhat proven.

Parameters

  • host: The host object
  • extension: [optional] The extension to add on the end of the file. Default: none.
  • seed: [optional] Some randomness on which to base the name. If you want to do multiple files, each with its own uniqueish name, this can be used.

Return value:

(status, data) If status is true, data is a table of values; otherwise, data is an error message. Can be any kind of string.
get_windows_version (os)

Converts numbered Windows version strings ("Windows 5.0", "Windows 5.1") to names ("Windows 2000", "Windows XP").

Parameters

  • os: The numbered OS version.

Return value:

The actual name of the OS (or the same as the os parameter if no match was found).
is_admin (host, username, domain, password, password_hash, hash_type)

Determines, as accurately as possible, whether or not an account is an administrator. If there is an error, 'false' is simply returned.

Parameters

  • host:
  • username:
  • domain:
  • password:
  • password_hash:
  • hash_type:
lock_mutex (smbstate, func)

Locks the mutex being used by this host. Doesn't return until it successfully obtains a lock.

Parameters

  • smbstate: The SMB object associated with the connection
  • func: A name to associate with this call (used purely for debugging and logging)
logoff (smb, overrides)

Logs off the current user. Strictly speaking this isn't necessary, but it's the polite thing to do.

Parameters

  • smb: The SMB object associated with the connection
  • overrides: THe overrides table

Return value:

(status, result) If statis is false, result is an error message. If status is true, the logoff was successful.
message_check_signature (smb, body)

Check the signature of the message. This is the opposite of message_sign, and works the same way (replaces the signature with the sequence number, calculates hash, checks)

Parameters

  • smb: The smb state object.
  • body: The body of the packet that's being checked.

Return value:

A true/false value -- true if the packet was signed properly, false if it wasn't.
message_sign (smb, body)

Sign the message, if possible. This is done by replacing the signature with the sequence number, creating a hash, then putting that hash in the signature location.

Parameters

  • smb: The smb state object.
  • body: The body of the packet that's being signed.

Return value:

The body of the packet, with the signature in place.
negotiate_protocol (smb, overrides)

Sends out SMB_COM_NEGOTIATE, which is typically the first SMB packet sent out. Sends the following:

  • List of known protocols

Receives:

  • The prefered dialect
  • The security mode
  • Max number of multiplexed connectiosn, virtual circuits, and buffer sizes
  • The server's system time and timezone
  • The "encryption key" (aka, the server challenge)
  • The capabilities
  • The server and domain names

Parameters

  • smb: The SMB object associated with the connection
  • overrides: [optional] Overrides for various fields

Return value:

(status, result) If status is false, result is an error message. Otherwise, result is nil and the following elements are added to smb: * 'security_mode' Whether or not to use cleartext passwords, message signatures, etc. * 'max_mpx' Maximum number of multiplexed connections * 'max_vc' Maximum number of virtual circuits * 'max_buffer' Maximum buffer size * 'max_raw_buffer' Maximum buffer size for raw connections (considered obsolete) * 'session_key' A value that's basically just echoed back * 'capabilities' The server's capabilities * 'time' The server's time (in UNIX-style seconds since 1970) * 'date' The server's date in a user-readable format * 'timezone' The server's timezone, in hours from UTC * 'timezone_str' The server's timezone, as a string * 'server_challenge' A random string used for challenge/response * 'domain' The server's primary domain * 'server' The server's name
read_file (smb, offset, count, overrides)

This sends a SMB request to read from a file (or a pipe).

Parameters

  • smb: The SMB object associated with the connection
  • offset: The offset to read from (ignored if it's a pipe)
  • count: The maximum number of bytes to read
  • overrides: The overrides table

Return value:

(status, result) If status is false, result is an error message. Otherwise, result is a table containing a lot of different elements.
send_transaction_named_pipe (smb, function_parameters, function_data, pipe, no_setup, overrides)

This is the core of making MSRPC calls. It sends out a MSRPC packet with the given parameters and data. Don't confuse these parameters and data with SMB's concepts of parameters and data -- they are completely different. In fact, these parameters and data are both sent in the SMB packet's 'data' section.

It is probably best to think of this as another protocol layer. This function will wrap SMB stuff around a MSRPC call, make the call, then unwrap the SMB stuff from it before returning.

Parameters

  • smb: The SMB object associated with the connection
  • function_parameters: The parameter data to pass to the function. This is untested, since none of the transactions I've done have required parameters.
  • function_data: The data to send with the packet. This is basically the next protocol layer
  • pipe: [optional] The pipe to transact on. Default: "\PIPE\".
  • no_setup: [optional] If set, the 'setup' is set to 0 and some parameters are left off. This occurs while using the LANMAN Remote API. Default: false.
  • overrides: The overrides table

Return value:

(status, result) If status is false, result is an error message. Otherwise, result is a table containing 'parameters' and 'data', representing the parameters and data returned by the server.
share_anonymous_can_read (host, share)

Check whether or not a share is accessible by the anonymous user. Assumes that share_host_returns_proper_error has been called and returns true.

Parameters

  • host: The host object
  • share: The share to test

Return value:

(status, result) If status is false, result is an error message. Otherwise, result is a boolean value: true if anonymous access is permitted, false otherwise.
share_anonymous_can_write (host, share)

Determine whether or not the anonymous user has write access on the share. This is done by creating then deleting a file.

Parameters

  • host: The host object
  • share: The share to test

Return value:

(status, result) If status is false, result is an error message. The error message 'NT_STATUS_OBJECT_NAME_NOT_FOUND' should be handled gracefully; it indicates that the share isn't a fileshare. Otherwise, result is a boolean value: true if the file was successfully written, false if it was not.
share_find_writable (host)

Find a share that the current user can write to. Return it, along with its path. If no share could be found, an error is returned. If the path cannot be determined, the returned path is nil.

Parameters

  • host: The host object.

Return value:

(status, name, path, names) If status is false, result is an error message. Otherwise, name is the name of the share, path is its path, if it could be determined, and names is a list of all writable shares.
share_get_details (host, share)

Get all the details we can about the share. These details are stored in a table and returned.

Parameters

  • host: The host object.
  • share: An array of shares to check.

Return value:

(status, result) If status is false, result is an error message. Otherwise, result is a boolean value: true if the file was successfully written, false if it was not.
share_get_list (host)

Retrieve a list of fileshares, along with any details that could be pulled. This is the core of smb-enum-shares.nse, but can also be used by any script that needs to find an open share.

In the best care, the shares are determined by calling msrpc.enum_shares, and information is gathered by calling msrpc.get_share_info. These require a certain level of access, though, so as a fallback, a pre-programmed list of shares is used, and these are verified by attempting a connection.

Parameters

  • host: The host object.

Return value:

(status, result, extra) If status is false, result is an error message. Otherwise, result is an array of shares with as much detail as we could get. If extra isn't nil, it is set to extra information that should be displayed (such as a warning).
share_host_returns_proper_error (host)

Determine whether or not a host will accept any share name (I've seen this on certain systems; it's bad, because it means we cannot tell whether or not a share exists).

Parameters

  • host: The host object

Return value:

(status, result) If status is false, result is an error message. Otherwise, result is a boolean value: true if the file was successfully written, false if it was not.
share_user_can_read (host, share)

Check whether or not a share is accessible by the current user. Assumes that share_host_returns_proper_error has been called and returns true.

Parameters

  • host: The host object
  • share: The share to test

Return value:

(status, result) If status is false, result is an error message. Otherwise, result is a boolean value: true if anonymous access is permitted, false otherwise.
share_user_can_write (host, share)

Determine whether or not the current user has read or read/write access on the share. This is done by creating then deleting a file.

Parameters

  • host: The host object
  • share: The share to test

Return value:

(status, result) If status is false, result is an error message. The error message 'NT_STATUS_OBJECT_NAME_NOT_FOUND' should be handled gracefully; it indicates that the share isn't a fileshare. Otherwise, result is a boolean value: true if the file was successfully written, false if it was not.
smb_encode_data (data, overrides)

Converts a string containing the data section into the encoded data string. The encoding is simple:

  • (2 bytes) The number of bytes in the data section
  • (variable) The data section
This is automatically done by smb_send.

Parameters

  • data: The data section.
  • overrides: The overrides table. The only thing possible to override here is the length.

Return value:

The encoded data.
smb_encode_header (smb, command, overrides)

Creates a string containing a SMB packet header. The header looks like this:

--------------------------------------------------------------------------------------------------
| 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9  8  7  6  5  4  3  2  1  0 |
--------------------------------------------------------------------------------------------------
|         0xFF           |          'S'          |        'M'            |         'B'           |
--------------------------------------------------------------------------------------------------
|        Command         |                             Status...                                 |
--------------------------------------------------------------------------------------------------
|    ...Status           |        Flags          |                    Flags2                     |
--------------------------------------------------------------------------------------------------
|                    PID_high                    |                  Signature.....               |
--------------------------------------------------------------------------------------------------
|                                        ....Signature....                                       |
--------------------------------------------------------------------------------------------------
|              ....Signature                     |                    Unused                     |
--------------------------------------------------------------------------------------------------
|                      TID                       |                     PID                       |
--------------------------------------------------------------------------------------------------
|                      UID                       |                     MID                       |
------------------------------------------------------------------------------------------------- 

All fields are, incidentally, encoded in little endian byte order.

For the purposes here, the program doesn't care about most of the fields so they're given default values. The "command" field is the only one we ever have to set manually, in my experience. The TID and UID need to be set, but those are stored in the smb state and don't require user intervention.

Parameters

  • smb: The smb state table.
  • command: The command to use.
  • overrides: The overrides table. Keep in mind that overriding things like flags is generally a very bad idea, unless you know what you're doing.

Return value:

A binary string containing the packed packet header.
smb_encode_parameters (parameters, overrides)

Converts a string containing the parameters section into the encoded parameters string. The encoding is simple:

  • (1 byte) The number of 2-byte values in the parameters section
  • (variable) The parameter section
This is automatically done by smb_send.

Parameters

  • parameters: The parameters section.
  • overrides: The overrides table. The only thing possible to override here is the length.

Return value:

The encoded parameters.
smb_read (smb, read_data)

Reads the next packet from the socket, and parses it into the header, parameters, and data.

Parameters

  • smb: The SMB object associated with the connection
  • read_data: [optional] This function will read the data section if and only if this value is true. This is a workaround for a bug in the tree connect packet, where the length is set incorrectly. Default: true.

Return value:

(status, header, parameters, data) If status is true, the header, parameters, and data are all the raw arrays (with the lengths already removed). If status is false, header contains an error message and parameters/ data are undefined.
smb_send (smb, header, parameters, data, overrides)

Prepends the NetBIOS header to the packet, which is essentially the length, encoded in 4 bytes of big endian, and sends it out. The length field is actually 17 or 24 bits wide, depending on whether or not we're using raw, but that shouldn't matter.

Parameters

  • smb: The SMB object associated with the connection
  • header: The header, encoded with smb_get_header.
  • parameters: The parameters.
  • data: The data.
  • overrides: Overrides table.

Return value:

(result, err) If result is false, err is the error message. Otherwise, err is undefined
start (host)

Begins a SMB session, automatically determining the best way to connect. Also starts a mutex with mutex_id. This prevents multiple threads from making queries at the same time (which breaks SMB).

Parameters

  • host: The host object

Return value:

(status, smb) if the status is true, result is the newly crated smb object; otherwise, socket is the error message.
start_ex (host, negotiate_protocol, start_session, tree_connect, create_file, disable_extended, overrides)

Initiates a SMB connection over whichever port it can, then optionally sends the common initialization packets. Note that each packet depends on the previous one, so if you want to go all the way up to create_file, you have to set all parameters.

If anything fails, we back out of the connection and return an error, so the calling functino doesn't have to call smb.stop().

Parameters

  • host: The host object.
  • negotiate_protocol: [optional] If 'true', send the protocol negotiation. Default: false.
  • start_session: [optional] If 'true', start the session. Default: false.
  • tree_connect: [optional] The tree to connect to, if given (eg. "IPC$" or "C$"). If not given, packet isn't sent.
  • create_file: [optional] The path and name of the file (or pipe) that's created, if given. If not given, packet isn't sent.
  • disable_extended: [optional] If set to true, disables extended security negotiations.
  • overrides: [optional] A table of overrides (for, for example, username, password, etc.) to pass to all functions.
start_netbios (host, port, name)

Begins a SMB session over NetBIOS. This requires a NetBIOS Session Start message to be sent first, which in turn requires the NetBIOS name. The name can be provided as a parameter, or it can be automatically determined.

Automatically determining the name is interesting, to say the least. Here are the names it tries, and the order it tries them in:

  • The name the user provided, if present
  • The name pulled from NetBIOS (udp/137), if possible
  • The generic name "*SMBSERVER"
  • Each subset of the domain name (for example, scanme.insecure.org would attempt "scanme",
"scanme.insecure", and "scanme.insecure.org")

This whole sequence is a little hackish, but it's the standard way of doing it.

Parameters

  • host: The host object to check.
  • port: The port to use (most likely 139).
  • name: [optional] The NetBIOS name of the host. Will attempt to automatically determine if it isn't given.

Return value:

(status, socket) if status is true, result is the port Otherwise, socket is the error message.
start_raw (host, port)

Begins a raw SMB session, likely over port 445. Since nothing extra is required, this function simply makes a connection and returns the socket.

Parameters

  • host: The host object to check.
  • port: The port to use (most likely 445).

Return value:

(status, socket) if status is true, result is the newly created socket. Otherwise, socket is the error message.
start_session (smb, overrides, log_errors)

Sends out SMB_COM_SESSION_SETUP_ANDX, which attempts to log a user in. Sends the following:

  • Negotiated parameters (multiplexed connections, virtual circuit, capabilities)
  • Passwords (plaintext, unicode, lanman, ntlm, lmv2, ntlmv2, etc)
  • Account name
  • OS (I just send "Nmap")
  • Native LAN Manager (no clue what that is, but it seems to be ignored)

Receives the following:

  • User ID
  • Server OS

Parameters

  • smb: The SMB object associated with the connection
  • overrides: [optional] A table of overrides for username, domain, password, password_hash, and hash_type. If any of these are given, it's used first. If they aren't, then Nmap parameters, Nmap registry entries, guest, and NULL sessions are used.
  • log_errors: [optional] If set, will display login. Default: true.

Return value:

(status, result) If status is false, result is an error message. Otherwise, result is nil and the following elements are added to the smb table: * 'uid' The UserID for the session * 'is_guest' If set, the username wasn't found so the user was automatically logged in as the guest account * 'os' The operating system * 'lanmanager' The servers's LAN Manager
stop (smb)

Kills the SMB connection, closes the socket, and releases the mutex. Because of the mutex being released, a script HAS to call stop before it exits, no matter why it's exiting!

In addition to killing the connection, this function will log off the user and disconnect the connected tree, if possible.

Parameters

  • smb: The SMB object associated with the connection

Return value:

(status, result) If status is false, result is an error message. Otherwise, result is undefined.
tree_connect (smb, path, overrides)

Sends out SMB_COM_SESSION_TREE_CONNECT_ANDX, which attempts to connect to a share. Sends the following:

  • Password (for share-level security, which we don't support)
  • Share name
  • Share type (or "?????" if it's unknown, that's what we do)

Receives the following:

  • Tree ID

Parameters

  • smb: The SMB object associated with the connection
  • path: The path to connect (eg, "\\servername\C$")
  • overrides: [optional] Overrides for various fields

Return value:

(status, result) If status is false, result is an error message. Otherwise, result is a table with the following elements: * 'tid' The TreeID for the session
tree_disconnect (smb, overrides)

Disconnects a tree session. Should be called before logging off and disconnecting.

Parameters

  • smb: The SMB object associated with the connection
  • overrides: THe overrides table

Return value:

(status, result) If status is false, result is an error message. If status is true, the disconnect was successful.
unlock_mutex (smbstate, func)

Unlocks the mutex being used by this host.

Parameters

  • smbstate: The SMB object associated with the connection
  • func: A name to associate with this call (used purely for debugging and logging)
write_file (smb, write_data, offset, overrides)

This sends a SMB request to write to a file (or a pipe).

Parameters

  • smb: The SMB object associated with the connection
  • write_data: The data to write
  • offset: The offset to write it to (ignored for pipes)
  • overrides: The overrides table

Return value:

(status, result) If status is false, result is an error message. Otherwise, result is a table containing a lot of different elements, the most important one being 'fid', the handle to the opened file.

Nmap Site Navigation

Intro Reference Guide Book Install Guide
Download Changelog Zenmap GUI Docs
Bug Reports OS Detection Propaganda Related Projects
In the Movies In the News
[ Nmap | Sec Tools | Mailing Lists | Site News | About/Contact | Advertising | Privacy ]