Class: Rex::Proto::SMB::Server

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Rex::Proto
Defined in:
lib/rex/proto/smb/server.rb

Overview

Acts as an SMB server, processing requests and dispatching them to registered procs.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(port = 445, listen_host = '0.0.0.0', context = {}, comm = nil, gss_provider: nil, logger: nil) ⇒ Server

Returns a new instance of Server.



23
24
25
26
27
28
29
30
31
32
33
# File 'lib/rex/proto/smb/server.rb', line 23

def initialize(port = 445, listen_host = '0.0.0.0', context = {}, comm = nil, gss_provider: nil, logger: nil)
  self.listen_host     = listen_host
  self.listen_port     = port
  self.context         = context
  self.comm            = comm
  @gss_provider        = gss_provider
  @logger              = logger
  self.listener        = nil
  @listener_thread     = nil
  @rubysmb_server      = nil
end

Instance Attribute Details

#commObject

Returns the value of attribute comm.



107
108
109
# File 'lib/rex/proto/smb/server.rb', line 107

def comm
  @comm
end

#contextObject

Returns the value of attribute context.



107
108
109
# File 'lib/rex/proto/smb/server.rb', line 107

def context
  @context
end

#listen_hostObject

Returns the value of attribute listen_host.



107
108
109
# File 'lib/rex/proto/smb/server.rb', line 107

def listen_host
  @listen_host
end

#listen_portObject

Returns the value of attribute listen_port.



107
108
109
# File 'lib/rex/proto/smb/server.rb', line 107

def listen_port
  @listen_port
end

#listenerObject

Returns the value of attribute listener.



107
108
109
# File 'lib/rex/proto/smb/server.rb', line 107

def listener
  @listener
end

#on_client_connect_procObject

Returns the value of attribute on_client_connect_proc.



107
108
109
# File 'lib/rex/proto/smb/server.rb', line 107

def on_client_connect_proc
  @on_client_connect_proc
end

Class Method Details

.hardcore_alias(*args, **kwargs) ⇒ Object

Returns the hardcore alias for the SMB service



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/rex/proto/smb/server.rb', line 43

def self.hardcore_alias(*args, **kwargs)
  gss_alias = ''
  if (gss_provider = kwargs[:gss_provider])
    gss_alias << "#{gss_provider.class}("
    attrs = {}
    if gss_provider.is_a?(RubySMB::Gss::Provider::NTLM)
      allows = []
      allows << 'ANONYMOUS' if gss_provider.allow_anonymous
      allows << 'GUESTS' if gss_provider.allow_guests
      attrs['allow'] = allows.join('|') unless allows.empty?
      attrs['default_domain'] = gss_provider.default_domain if gss_provider.respond_to?(:default_domain) && gss_provider.default_domain.present?
      attrs['ntlm_status'] = gss_provider.ntlm_type3_status.name if gss_provider.respond_to?(:ntlm_type3_status) && gss_provider.ntlm_type3_status.present?
    end
    gss_alias << attrs.map { |k,v| "#{k}=#{v}"}.join(', ')
    gss_alias << ')'
  end
  "#{(args[0] || '')}-#{(args[1] || '')}-#{args[3] || ''}-#{gss_alias}"
end

Instance Method Details

#aliasObject



62
63
64
# File 'lib/rex/proto/smb/server.rb', line 62

def alias
  super || "SMB Server"
end

#inspectString

Returns:

  • (String)


36
37
38
# File 'lib/rex/proto/smb/server.rb', line 36

def inspect
  "#<#{self.class} smb://#{listen_host}:#{listen_port} >"
end

#startObject



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/rex/proto/smb/server.rb', line 66

def start
  self.listener = Rex::Socket::TcpServer.create(
    'LocalHost'      => self.listen_host,
    'LocalPort'      => self.listen_port,
    'Context'        => self.context,
    'Comm'           => self.comm
  )

  thread_factory = Proc.new do |server_client, &block|
    Rex::ThreadFactory.spawn("SMBServerClient(#{server_client.peerhost}->#{server_client.dispatcher.tcp_socket.localhost})", false, &block)
  end

  @rubysmb_server = RubySMB::Server.new(
    server_sock: self.listener,
    gss_provider: @gss_provider,
    logger: @logger,
    thread_factory: thread_factory
  )

  localinfo = Rex::Socket.to_authority(self.listener.localhost, self.listener.localport)
  @listener_thread = Rex::ThreadFactory.spawn("SMBServerListener(#{localinfo})", false) do
    begin
      @rubysmb_server.run do |server_client|
        on_client_connect_proc.call(server_client) if on_client_connect_proc
        true
      end
    rescue IOError => e
      # this 'IOError: stream closed in another thread' is expected, so disregard it
      wlog("#{e.class}: #{e.message}")
    end
  end
end

#stopObject



99
100
101
# File 'lib/rex/proto/smb/server.rb', line 99

def stop
  self.listener.close
end

#waitObject



103
104
105
# File 'lib/rex/proto/smb/server.rb', line 103

def wait
  @listener_thread.join if @listener_thread
end