Path: blob/master/lib/rex/post/meterpreter/extensions/powershell/powershell.rb
19500 views
# -*- coding: binary -*-12require 'rex/post/meterpreter/extensions/powershell/tlv'3require 'rex/post/meterpreter/extensions/powershell/command_ids'45module Rex6module Post7module Meterpreter8module Extensions9module Powershell1011###12#13# This meterpreter extensions a privilege escalation interface that is capable14# of doing things like dumping password hashes and performing local15# exploitation.16#17###18class Powershell < Extension1920def self.extension_id21EXTENSION_ID_POWERSHELL22end2324def initialize(client)25super(client, 'powershell')2627client.register_extension_aliases(28[29{30'name' => 'powershell',31'ext' => self32},33])34end353637def import_file(opts={})38return nil unless opts[:file]3940# if it's a script, then we'll just use execute_string41if opts[:file].end_with?('.ps1')42opts[:code] = ::File.read(opts[:file])43return execute_string(opts)44end4546# if it's a dll (hopefully a .NET 2.0 one) then do something different47if opts[:file].end_with?('.dll')48# TODO: perhaps do some kind of check to see if the DLL is a .NET assembly?49binary = ::File.read(opts[:file])5051request = Packet.create_request(COMMAND_ID_POWERSHELL_ASSEMBLY_LOAD)52request.add_tlv(TLV_TYPE_POWERSHELL_ASSEMBLY_SIZE, binary.length)53request.add_tlv(TLV_TYPE_POWERSHELL_ASSEMBLY, binary)54client.send_request(request)55return { loaded: true }56end5758return { loaded: false }59end6061def session_remove(opts={})62return false unless opts[:session_id]63request = Packet.create_request(COMMAND_ID_POWERSHELL_SESSION_REMOVE)64request.add_tlv(TLV_TYPE_POWERSHELL_SESSIONID, opts[:session_id]) if opts[:session_id]65client.send_request(request)66return true67end6869def execute_string(opts={})70return nil unless opts[:code]7172request = Packet.create_request(COMMAND_ID_POWERSHELL_EXECUTE)73request.add_tlv(TLV_TYPE_POWERSHELL_CODE, opts[:code])74request.add_tlv(TLV_TYPE_POWERSHELL_SESSIONID, opts[:session_id]) if opts[:session_id]7576response = client.send_request(request)77result = {}78handle = client.sys.config.get_token_handle()79if handle != 080result[:warning] = 'Impersonation will not apply to PowerShell.'81end8283result[:output] = response.get_tlv_value(TLV_TYPE_POWERSHELL_RESULT)84return result85end8687def shell(opts={})88request = Packet.create_request(COMMAND_ID_POWERSHELL_SHELL)89request.add_tlv(TLV_TYPE_POWERSHELL_SESSIONID, opts[:session_id]) if opts[:session_id]9091response = client.send_request(request)92channel_id = response.get_tlv_value(TLV_TYPE_CHANNEL_ID)93if channel_id.nil?94raise Exception, "We did not get a channel back!"95end9697result = {}98handle = client.sys.config.get_token_handle()99if handle != 0100result[:warning] = 'Impersonation will not apply to PowerShell.'101end102103result[:channel] = Rex::Post::Meterpreter::Channels::Pools::StreamPool.new(client, channel_id, 'powershell_psh', CHANNEL_FLAG_SYNCHRONOUS, response)104105result106end107108end109110end; end; end; end; end111112113