Skip to content

Commit

Permalink
Add a proper rex-based service for the SMB server
Browse files Browse the repository at this point in the history
  • Loading branch information
zeroSteiner committed Jan 8, 2024
1 parent b10e8d5 commit 024bdae
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 35 deletions.
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,6 @@ group :test do
# Manipulate Time.now in specs
gem 'timecop'
end

# remove after https://github.com/rapid7/ruby_smb/pull/260 is landed
gem 'ruby_smb', git: 'https://github.com/zeroSteiner/ruby_smb', branch: 'feat/server/remove-share'
19 changes: 13 additions & 6 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
GIT
remote: https://github.com/zeroSteiner/ruby_smb
revision: feba8f6592c33c252c6b4e5dd576f2722ada6bf2
branch: feat/server/remove-share
specs:
ruby_smb (3.3.2)
bindata
openssl-ccm
openssl-cmac
rubyntlm
windows_error (>= 0.1.4)

PATH
remote: .
specs:
Expand Down Expand Up @@ -473,12 +485,6 @@ GEM
ruby-progressbar (1.13.0)
ruby-rc4 (0.1.5)
ruby2_keywords (0.0.5)
ruby_smb (3.3.1)
bindata
openssl-ccm
openssl-cmac
rubyntlm
windows_error (>= 0.1.4)
rubyntlm (0.6.3)
rubyzip (2.3.2)
sawyer (0.9.2)
Expand Down Expand Up @@ -565,6 +571,7 @@ DEPENDENCIES
rspec-rerun
rubocop
ruby-prof (= 1.4.2)
ruby_smb!
simplecov (= 0.18.2)
test-prof
timecop
Expand Down
13 changes: 0 additions & 13 deletions lib/msf/core/exploit/remote/smb/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,19 +45,6 @@ def start_service(opts = {})
def on_client_connect(client)
vprint_status("Received SMB connection from #{client.peerhost}")
end

def cleanup_service
if service
begin
self.service.stop
self.service.wait
true
rescue ::Exception => e
print_error(e.message)
false
end
end
end
end
end
end
Expand Down
32 changes: 22 additions & 10 deletions lib/msf/core/exploit/remote/smb/server/share.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ def initialize(info = {})
register_options(
[
OptPort.new('SRVPORT', [ true, 'The local port to listen on.', 445 ]),
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)'])
OptString.new('SHARE', [ false, 'Share (Default: random); cannot contain spaces or slashes'], regex: /^[^\s\/\\]*$/),
OptString.new('FILE_NAME', [ false, 'File name to share (Default: random)']),
OptString.new('FOLDER_NAME', [ false, 'Folder name to share (Default: none)'])
], Msf::Exploit::Remote::SMB::Server::Share)
register_advanced_options(
[
Expand Down Expand Up @@ -58,21 +58,27 @@ def start_service(opts = {})

super(opts)

virtual_disk = RubySMB::Server::Share::Provider::VirtualDisk.new(@share)
# the virtual disk expects the path to use the native File::SEPARATOR so normalize on that here
virtual_disk.add_dynamic_file("#{@folder_name}#{File::SEPARATOR}#{@file_name}".gsub(/\/|\\/, File::SEPARATOR)) do |client, _smb_session|
get_file_contents(client: client)
if share.present?
if service.shares.key?(share)
fail_with(Msf::Module::Failure::BadConfig, "The specified SMB share '#{share}' already exists.")
end

virtual_disk = RubySMB::Server::Share::Provider::VirtualDisk.new(share)
# the virtual disk expects the path to use the native File::SEPARATOR so normalize on that here
virtual_disk.add_dynamic_file("#{@folder_name}#{File::SEPARATOR}#{@file_name}".gsub(/\/|\\/, File::SEPARATOR)) do |client, _smb_session|
get_file_contents(client: client)
end
service.add_share(virtual_disk)
end
service.add_share(virtual_disk)
end

# Setups the server configuration.
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))
self.share = datastore['SHARE'].present? ? datastore['SHARE'] : Rex::Text.rand_text_alpha(4 + rand(3))
self.file_name = datastore['FILE_NAME'].present? ? datastore['FILE_NAME'] : Rex::Text.rand_text_alpha(4 + rand(3))
end

# Builds the UNC Name for the shared file
Expand All @@ -92,6 +98,12 @@ def unc
def get_file_contents(client:)
file_contents
end

def cleanup
self.service.remove_share(share) if share.present?

super
end
end
end
end
6 changes: 1 addition & 5 deletions lib/rex/proto/smb/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class Server
include Proto
extend Forwardable

def_delegators :@rubysmb_server, :add_share, :dialects, :guid, :shares
def_delegators :@rubysmb_server, :dialects, :guid, :shares, :add_share, :remove_share

def initialize(port = 445, listen_host = '0.0.0.0', context = {}, comm = nil, gss_provider: nil, logger: nil)
self.listen_host = listen_host
Expand Down Expand Up @@ -99,10 +99,6 @@ def wait
@listener_thread.join if @listener_thread
end

def add_share(share_provider, *arg)

end

attr_accessor :context, :comm, :listener, :listen_host, :listen_port, :on_client_connect_proc
end

Expand Down
2 changes: 1 addition & 1 deletion lib/rex/service_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def start(klass, *args, **kwargs)
return inst
end

inst = klass.new(*args)
inst = klass.new(*args, **kwargs)
als = inst.alias

# Find an alias that isn't taken.
Expand Down

0 comments on commit 024bdae

Please sign in to comment.