def genStub(self, userCmd):
        """
        Generate a valid deobfuscation stub and wrap an obfuscated
        command in it.

        :param userCmd: command that need to be wrapped in a
            deobfuscation stub
        :type userCmd: str
        """
        if self.escapeQuotes:
            userCmd = userCmd.replace("'", "'\"'\"'")

        genStub = self.stub
        for var in re.findall(r"VAR\d+", genStub):
            genStub = genStub.replace(var, self.randGen.randGenVar())

        genStub = self.mangler.getMangledLine(genStub)

        if "CMD" not in genStub:
            printError(f"Stub '{self.name}' is improperly formatted: no 'CMD' string found")

        else:
            genStub = genStub.replace("CMD", userCmd)

        return genStub
示例#2
0
    def choosePrefStub(self,
                       stubs,
                       sizePref,
                       timePref,
                       binaryPref,
                       filePref,
                       userStub=None):
        """
        Choose a stub which is of the desired sizeRating, timeRating,
        and uses desired binaries. If the userStub parameter is passed,
        the specific stub defined by userStub is searched for and is
        checked to make sure it aligns with the users preferences for
        used binaries.

        :param stubs: list of Stubs to choose from
        :param sizePref: payload size user preference
        :type sizePref: int
        :param timePref: execution time user preference
        :type timePref: int
        :param binaryPref: list of binaries that the chosen Mutator
            should or should not use
        :type binaryPref: tuple containing a list of strs, and a bool
        :param userStub: the specific Stub the user chose to use
        :type userStub: lowercase str
        :returns: a :class:`bashfuscator.common.objects.Stub`
            object
        """
        selStub = None

        if binaryPref is not None:
            binList = binaryPref[0]
            includeBinary = binaryPref[1]

        # attempt to find the specific stub the user wants
        if userStub is not None:
            for stub in stubs:
                if stub.longName == userStub:
                    if binaryPref is not None:
                        for binary in stub.binariesUsed:
                            if (binary in binList) != includeBinary:
                                printWarning(
                                    f"'{userStub}' stub contains an unwanted binary"
                                )

                    if filePref is False and stub.fileWrite != filePref:
                        printWarning(f"'{userStub}' stub preforms file writes")

                    selStub = stub

            if selStub is None:
                printError(f"'{userStub}' stub not found")

        else:
            selStub = self.randGen.randSelect(stubs)

        return selStub
    def getMutator(self, userMutator=None, userStub=None, sizePref=None, timePref=None, binaryPref=None, filePref=None):
        selMutator = None

        if userMutator:
            mutatorType = userMutator.split("/")[0]

            if mutatorType == "command":
                selMutator = self.choosePrefMutator(self.cmdObfuscators, sizePref, timePref,
                    binaryPref, filePref, self.prevCmdOb, userMutator, userStub)
                self.prevCmdOb = selMutator

            elif mutatorType == "string":
                selMutator = self.choosePrefMutator(self.strObfuscators, binaryPref=binaryPref, filePref=filePref, userMutator=userMutator)

            elif mutatorType == "token":
                selMutator = self.choosePrefMutator(self.tokObfuscators, binaryPref=binaryPref, filePref=filePref, userMutator=userMutator)

            elif mutatorType == "encode":
                selMutator = self.choosePrefMutator(self.encoders, binaryPref=binaryPref, filePref=filePref, userMutator=userMutator)

            elif mutatorType == "compress":
                selMutator = self.choosePrefMutator(self.compressors, binaryPref=binaryPref, filePref=filePref, userMutator=userMutator)

            else:
                printError(f"{mutatorType} isn't a valid mutator type")
        else:
            # TODO: handle case when no mutators of chosen type are compatible with user's preferences
            obChoice = self.randGen.randChoice(3)

            if obChoice == 0:
                selMutator = self.choosePrefMutator(self.cmdObfuscators, sizePref, timePref,
                    binaryPref, filePref, self.prevCmdOb)
                self.prevCmdOb = selMutator

            elif obChoice == 1:
                selMutator = self.choosePrefMutator(self.strObfuscators, sizePref, timePref,
                    binaryPref, filePref)

            else:
                selMutator = self.choosePrefMutator(self.tokObfuscators, sizePref, timePref)

        selMutator.sizePref = sizePref
        selMutator.timePref = timePref

        return selMutator
示例#4
0
    def choosePrefMutator(self,
                          mutators,
                          sizePref=None,
                          timePref=None,
                          binaryPref=None,
                          filePref=None,
                          prevCmdOb=None,
                          userMutator=None,
                          userStub=None):
        """
        Chooses a Mutator from a list of mutators which is of the
        desired preferences, with a stub that uses desired binaries if
        appropriate. If called with the userMutator or userStub
        parameters, the Mutator and/or Stub specified by userMutator
        and/or userStub will be chosen. If those parameters are not
        used, a Mutator and Stub (if appropriate) will be chosen
        automatically based off of the values of the other parameters.

        :param mutators: list of Mutators to choose a Mutator from
        :param sizePref: payload size user preference
        :type sizePref: int
        :param timePref: execution time user preference
        :type timePref: int
        :param binaryPref: list of binaries that the chosen Mutator
            should or should not use
        :type binaryPref: tuple containing a list of strs, and a bool
        :param filePref: file write user preference
        :type filePref: bool
        :param prevCmdOb: the previous CommandObfuscator used. Should
            only be passed if a CommandObfuscator was used to generate
            the most recent obfuscation layer
        :type prevCmdOb:
            :class:`bashfuscator.lib.command_mutators.CommandObfuscator`
        :param userMutator: the specific Mutator the user chose to use
        :type userMutator: lowercase str
        :param userStub: the specific Stub the user chose to use
        :type userStub: lowercase str
        :returns: a :class:`bashfuscator.common.objects.Mutator`
            object
        """
        selMutator = None

        if userMutator:
            if binaryPref:
                binList = binaryPref[0]
                includeBinary = binaryPref[1]

            for mutator in mutators:
                if mutator.longName == userMutator:
                    if filePref is False and mutator.mutatorType != "command" and mutator.fileWrite != filePref:
                        printWarning(
                            f"'{userMutator}' mutator preforms file writes")

                    elif binaryPref and mutator.mutatorType != "command":
                        for binary in mutator.binariesUsed:
                            if (binary in binList) != includeBinary:
                                printWarning(
                                    f"'{userMutator}' mutator contains an unwanted binary"
                                )

                    selMutator = mutator
                    if selMutator.mutatorType == "command":
                        selMutator.prefStubs = self.getPrefStubs(
                            selMutator.stubs, sizePref, timePref, binaryPref,
                            filePref)

                    break

            if selMutator is None:
                printError(f"Selected mutator '{userMutator}' not found")

        else:
            prefMutators = self.getPrefMutators(mutators, sizePref, timePref,
                                                binaryPref, filePref,
                                                prevCmdOb)
            selMutator = self.randGen.randSelect(prefMutators)

        if selMutator is not None and selMutator.mutatorType == "command":
            selMutator.deobStub = self.choosePrefStub(selMutator.prefStubs,
                                                      sizePref, timePref,
                                                      binaryPref, filePref,
                                                      userStub)

            if selMutator.deobStub:
                selMutator.deobStub.mangler = selMutator.mangler
                selMutator.deobStub.randGen = selMutator.mangler.randGen
            else:
                printError(
                    f"All of '{selMutator.longName}'s Stubs do not fulfil your requirements"
                )

        return selMutator
示例#5
0
    def genObfuscationLayer(self,
                            payload,
                            userMutator=None,
                            userStub=None,
                            sizePref=None,
                            timePref=None,
                            binaryPref=None,
                            filePref=None,
                            enableMangling=None,
                            mangleBinaries=None,
                            binaryManglePercent=None,
                            randWhitespace=None,
                            randWhitespaceRange=None,
                            insertChars=None,
                            insertCharsRange=None,
                            misleadingCmds=None,
                            misleadingCmdsRange=None,
                            writeDir=None,
                            debug=None):
        """
        Generate one layer of obfuscation. If called with the
        userMutator or userStub parameters, the Mutator and/or Stub
        specified by userMutator and/or userStub will be used to mutate
        the payload. If those parameters are not used, a Mutator and
        Stub (if appropriate) will be chosen automatically.

        .. note::
            If not set, the sizePref, timePref, binaryPref, filePref,
            and writeDir parameters will be set to the coresponding
            attributes of the ObfuscationHandler object being called
            from.

        :param payload: input command(s) to obfuscate
        :type payload: str
        :param userMutator: the `longName` attribute of a
            :class:`bashfuscator.common.objects.Mutator`
        :type userMutator: lowercase str
        :param userStub: the `longName` attribute of a
            :class:`bashfuscator.common.objects.Stub`
        :type userStub: lowercase str
        :param sizePref: payload size user preference
        :type sizePref: int
        :param timePref: execution time user preference
        :type timePref: int
        :param binaryPref: list of binaries that the chosen Mutator
            should or should not use
        :type binaryPref: tuple containing a list of strs, and a bool
        :param filePref: file write user preference
        :type filePref: bool
        :returns: a str containing the 'payload' argument obfuscated by
            a single Mutator
        """
        if sizePref is None:
            sizePref = self.sizePref
        if timePref is None:
            timePref = self.timePref
        if binaryPref is None:
            binaryPref = self.binaryPref
        if filePref is None:
            filePref = self.filePref
        if enableMangling is None:
            enableMangling = self.enableMangling
        if mangleBinaries is None:
            mangleBinaries = self.mangleBinaries
        if binaryManglePercent is None:
            binaryManglePercent = self.binaryManglePercent
        if randWhitespace is None:
            randWhitespace = self.randWhitespace
        if randWhitespaceRange is None:
            randWhitespaceRange = self.randWhitespaceRange
        if insertChars is None:
            insertChars = self.insertChars
        if insertCharsRange is None:
            insertCharsRange = self.insertCharsRange
        if misleadingCmds is None:
            misleadingCmds = self.misleadingCmds
        if misleadingCmdsRange is None:
            misleadingCmdsRange = self.misleadingCmdsRange
        if debug is None:
            debug = self.debug
        if writeDir is None:
            writeDir = self.writeDir

        selMutator = None

        if userMutator:
            mutatorType = userMutator.split("/")[0]

            if mutatorType == "command":
                selMutator = self.choosePrefMutator(self.cmdObfuscators,
                                                    sizePref, timePref,
                                                    binaryPref, filePref,
                                                    self.prevCmdOb,
                                                    userMutator, userStub)
                self.prevCmdOb = selMutator

            elif mutatorType == "string":
                selMutator = self.choosePrefMutator(self.strObfuscators,
                                                    binaryPref=binaryPref,
                                                    filePref=filePref,
                                                    userMutator=userMutator)

            elif mutatorType == "token":
                selMutator = self.choosePrefMutator(self.tokObfuscators,
                                                    binaryPref=binaryPref,
                                                    filePref=filePref,
                                                    userMutator=userMutator)

            elif mutatorType == "encode":
                selMutator = self.choosePrefMutator(self.encoders,
                                                    binaryPref=binaryPref,
                                                    filePref=filePref,
                                                    userMutator=userMutator)

            elif mutatorType == "compress":
                selMutator = self.choosePrefMutator(self.compressors,
                                                    binaryPref=binaryPref,
                                                    filePref=filePref,
                                                    userMutator=userMutator)

            else:
                printError(f"ERROR: {mutatorType} isn't a valid mutator type")
        else:
            # TODO: handle case when no mutators of chosen type are compatible with user's preferences
            obChoice = self.randGen.randChoice(3)

            if obChoice == 0:
                selMutator = self.choosePrefMutator(self.cmdObfuscators,
                                                    sizePref, timePref,
                                                    binaryPref, filePref,
                                                    self.prevCmdOb)
                self.prevCmdOb = selMutator

            elif obChoice == 1:
                selMutator = self.choosePrefMutator(self.strObfuscators,
                                                    sizePref, timePref,
                                                    binaryPref, filePref)

            else:
                selMutator = self.choosePrefMutator(self.tokObfuscators,
                                                    sizePref, timePref)

        selMutator.sizePref = sizePref
        selMutator.timePref = timePref
        selMutator.writeDir = writeDir
        selMutator._originalCmd = payload
        selMutator.mangler.initialize(sizePref, enableMangling, mangleBinaries,
                                      binaryManglePercent, randWhitespace,
                                      randWhitespaceRange, insertChars,
                                      insertCharsRange, misleadingCmds,
                                      misleadingCmdsRange, debug)
        payload = selMutator.mutate(payload)
        selMutator._obfuscatedCmd = payload

        self.randGen.forgetUniqueStrs()
        payload = self.evalWrap(payload, selMutator)

        return payload