Add a proper rex-based service for the SMB server
This commit is contained in:
@@ -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'
|
||||
|
||||
+13
-6
@@ -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:
|
||||
@@ -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)
|
||||
@@ -565,6 +571,7 @@ DEPENDENCIES
|
||||
rspec-rerun
|
||||
rubocop
|
||||
ruby-prof (= 1.4.2)
|
||||
ruby_smb!
|
||||
simplecov (= 0.18.2)
|
||||
test-prof
|
||||
timecop
|
||||
|
||||
@@ -45,19 +45,6 @@ module Msf
|
||||
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
|
||||
|
||||
@@ -28,9 +28,9 @@ module Msf
|
||||
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(
|
||||
[
|
||||
@@ -58,12 +58,18 @@ module Msf
|
||||
|
||||
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.
|
||||
@@ -71,8 +77,8 @@ module Msf
|
||||
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
|
||||
@@ -92,6 +98,12 @@ module Msf
|
||||
def get_file_contents(client:)
|
||||
file_contents
|
||||
end
|
||||
|
||||
def cleanup
|
||||
self.service.remove_share(share) if share.present?
|
||||
|
||||
super
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -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
|
||||
@@ -99,10 +99,6 @@ class Server
|
||||
@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
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ class ServiceManager < Hash
|
||||
return inst
|
||||
end
|
||||
|
||||
inst = klass.new(*args)
|
||||
inst = klass.new(*args, **kwargs)
|
||||
als = inst.alias
|
||||
|
||||
# Find an alias that isn't taken.
|
||||
|
||||
Reference in New Issue
Block a user