Library smb
Implements functionality related to Server Message Block (SMB, an extension of 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 compatible. As a result, creating an implementation that accepts everything is a bit of a minefield. Microsoft's extensive documentation is available at the following URLs:
- SMB: http://msdn.microsoft.com/en-us/library/cc246231(v=prot.13).aspx
- CIFS: http://msdn.microsoft.com/en-us/library/ee442092(v=prot.13).aspx
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:
Copyright © Same as Nmap--See https://nmap.org/book/man-legal.html
Source: https://svn.nmap.org/nmap/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 insmbauth.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.
- 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.
- 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.
- find_files (smbstate, fname, options)
List files based on a pattern within a given share and directory
- get_account (host)
Wrapper around
smbauth.get_account
.- get_fqpn (host, sharename)
Returns the fully qualified path name (FQPN) for shares. This is required for modern versions of Windows. Returns \\<ip>\<sharename> when successful. Otherwise, returns the same share name.
- 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 theget_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_uniqueish_name (host, extension, seed)
Generate a string that's somewhat unique, but is based on factors that won't change on a host.
- 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.
- list_dialects (host, overrides)
Returns list of supported dialects for SMBv1, SMBv2 and SMBv3.
- logoff (smb, overrides)
Logs off the current user. Strictly speaking this isn't necessary, but it's the polite thing to do.
- negotiate_protocol (smb, overrides)
Wrapper function to negotiate the protocol to use in the SMB connection. By default it attempts to negotiate with using following dialects:
- NT LM 12.0 (SMBv1)
- negotiate_v1 (smb, overrides)
Negotiates SMBv1 connections
- 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.
- 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 returnstrue
.- 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, use_anonymous)
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 returnstrue
.- 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_header (smb, command, overrides)
Creates a string containing a SMB packet header. The header looks like this:
- 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.
- start (host)
Begins a SMB session, automatically determining the best way to connect.
- start_ex (host, bool_negotiate_protocol, bool_start_session, str_tree_connect, str_create_file, bool_disable_extended, overrides)
Initiates a SMB connection over whichever port it can, then optionally sends the common initialization packets.
- start_netbios (host, port, name)
Begins a SMB session over NetBIOS.
- 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.
- stop (smb)
Kills the SMB connection and closes the socket.
- tree_connect (smb, path, overrides)
Sends out
SMB_COM_SESSION_TREE_CONNECT_ANDX
, which attempts to connect to a share.- tree_disconnect (smb, overrides)
Disconnects a tree session. Should be called before logging off and disconnecting.
- 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
- The string containing the data to be written
- 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:
- status: A true/false value indicating success
- count: The number of files that existed, or an error message if status is 'false'
- files: A list of the files that existed.
- find_files (smbstate, fname, options)
-
List files based on a pattern within a given share and directory
Parameters
- smbstate
- the SMB object associated with the connection
- fname
- filename to search for, relative to share path
- options
- table containing none or more of the following
maxfiles
how many files to request in a single Trans2 opsrch_attrs
table containing one or more of the following boolean attributes:ro
- find read only fileshidden
- find hidden filessystem
- find system filesvolid
- include volume ids in resultdir
- find directoriesarchive
- find archived files
Return value:
iterator function retrieving the next result - get_account (host)
-
Wrapper around
smbauth.get_account
.Parameters
- host
- get_fqpn (host, sharename)
-
Returns the fully qualified path name (FQPN) for shares. This is required for modern versions of Windows. Returns \\<ip>\<sharename> when successful. Otherwise, returns the same share name.
Parameters
- host
- sharename
- 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.
The returned table has the following keys (shown here with sample values).
os
:"Windows 7 Professional 7601 Service Pack 1"
lanmanager
:"Windows 7 Professional 6.1"
domain
:"WORKGROUP"
server
:"COMPUTERNAME"
time
:1347121470.0462
date
:"2012-09-08 09:24:30"
timezone
:-7
timezone_str
:UTC-7
port
:445
fqdn
:"Sql2008.lab.test.local"
domain_dns
:"lab.test.local"
forest_dns
:"test.local"
workgroup
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 theget_info
function. Returns the mac address as well, for convenience.Parameters
- host
- The host object
Return values:
- status: true for successful, false otherwise.
- If status is true, the local ip address; otherwise, an error message.
- The local port (not really meaningful, since it'll change next time).
- The remote ip address.
- The report port.
- 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_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 theos
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
- list_dialects (host, overrides)
-
Returns list of supported dialects for SMBv1, SMBv2 and SMBv3.
Parameters
- host
- The SMB host to connect to.
- overrides
- [optional] Overrides for various fields.
Return values:
- Boolean status
- Table of supported dialects or error message
- 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 status is false, result is an error message. If status is true, the logoff was successful. - negotiate_protocol (smb, overrides)
-
Wrapper function to negotiate the protocol to use in the SMB connection. By default it attempts to negotiate with using following dialects:
- NT LM 12.0 (SMBv1)
Parameters
- smb
- The SMB object
- overrides
- Overrides table
Return value:
Boolean status - negotiate_v1 (smb, overrides)
-
Negotiates SMBv1 connections
Sends the following:
- List of known protocols
This function adds 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 or workgroup
- 'server' The server's name
Parameters
- smb
- The SMB object associated with the connection.
- overrides
- Overrides table.
Return values:
- Boolean status
- The negotiated dialect in human readable form or an error message.
- 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. -
Check whether or not a share is accessible by the anonymous user. Assumes that
share_host_returns_proper_error
has been called and returnstrue
.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. -
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. -
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. -
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. -
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 callingmsrpc.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). -
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
- use_anonymous
- [optional] If set to 'true', test is done by the anonymous user rather than the current user.
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. -
Check whether or not a share is accessible by the current user. Assumes that
share_host_returns_proper_error
has been called and returnstrue
.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. -
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_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_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.
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, bool_negotiate_protocol, bool_start_session, str_tree_connect, str_create_file, bool_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 function doesn't have to call smb.stop().
Parameters
- host
- The host object.
- bool_negotiate_protocol
- [optional] If 'true', send the protocol negotiation. Default: false.
- bool_start_session
- [optional] If 'true', start the session. Default: false.
- str_tree_connect
- [optional] The tree to connect to, if given (eg. "IPC$" or "C$"). If not given, packet isn't sent.
- str_create_file
- [optional] The path and name of the file (or pipe) that's created, if given. If not given, packet isn't sent.
- bool_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 server's LAN Manager - stop (smb)
-
Kills the SMB connection and closes the socket.
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. - 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.