def scan_output(taskid): """ Read the standard output of sqlmap core execution """ global procs global tasks json_stdout_message = [] json_stderr_message = [] if taskid not in tasks: abort(500, "Invalid task ID") # Read all stdout messages from the temporary I/O database procs[taskid].ipc_database_cursor.execute("SELECT message FROM stdout") db_stdout_messages = procs[taskid].ipc_database_cursor.fetchall() for message in db_stdout_messages: json_stdout_message.append(message) # Read all stderr messages from the temporary I/O database procs[taskid].ipc_database_cursor.execute("SELECT message FROM stderr") db_stderr_messages = procs[taskid].ipc_database_cursor.fetchall() for message in db_stderr_messages: json_stderr_message.append(message) return jsonize({"stdout": json_stdout_message, "stderr": json_stderr_message})
def scan_start(taskid): """ Launch a scan """ global tasks if taskid not in tasks: abort(500, "Invalid task ID") tasks[taskid].reset_options() # Initialize sqlmap engine's options with user's provided options, if any for option, value in request.json.items(): tasks[taskid].set_option(option, value) # Overwrite output directory value to a temporary directory tasks[taskid].set_output_directory() # Launch sqlmap engine in a separate process tasks[taskid].engine_start() logger.debug("Started scan for task ID %s" % taskid) return jsonize({ "success": True, "engineid": tasks[taskid].engine_get_id() })
def scan_log_limited(taskid, start, end): """ Retrieve a subset of log messages """ global procs json_log_messages = {} if taskid not in tasks: abort(500, "Invalid task ID") # Temporary "protection" against SQL injection FTW ;) if not start.isdigit() or not end.isdigit() or end <= start: abort(500, "Invalid start or end value, must be digits") start = max(1, int(start)) end = max(1, int(end)) # Read a subset of log messages from the temporary I/O database procs[taskid].ipc_database_cursor.execute("SELECT id, time, level, message FROM logs WHERE id >= %d AND id <= %d" % (start, end)) db_log_messages = procs[taskid].ipc_database_cursor.fetchall() for (id_, time_, level, message) in db_log_messages: json_log_messages[id_] = {"time": time_, "level": level, "message": message} return jsonize({"log": json_log_messages})
def scan_log_limited(taskid, start, end): """ Retrieve a subset of log messages """ global db global tasks json_log_messages = list() if taskid not in tasks: abort(500, "Invalid task ID") if not start.isdigit() or not end.isdigit() or end < start: abort(500, "Invalid start or end value, must be digits") start = max(1, int(start)) end = max(1, int(end)) # Read a subset of log messages from the IPC database for time_, level, message in db.execute( "SELECT time, level, message FROM logs WHERE taskid = ? AND id >= ? AND id <= ? ORDER BY id ASC", (taskid, start, end)): json_log_messages.append({ "time": time_, "level": level, "message": message }) logger.debug("Retrieved subset of log messages for scan for task ID %s" % taskid) return jsonize({"log": json_log_messages})
def scan_data(taskid): """ Retrieve the data of a scan """ global db global tasks json_data_message = list() json_errors_message = list() if taskid not in tasks: abort(500, "Invalid task ID") # Read all data from the IPC database for the taskid for status, content_type, value in db.execute( "SELECT status, content_type, value FROM data WHERE taskid = ? ORDER BY id ASC", (taskid, )): json_data_message.append({ "status": status, "type": content_type, "value": dejsonize(value) }) # Read all error messages from the IPC database for error in db.execute( "SELECT error FROM errors WHERE taskid = ? ORDER BY id ASC", (taskid, )): json_errors_message.append(error) logger.debug("Retrieved data and error messages for scan for task ID %s" % taskid) return jsonize({"data": json_data_message, "error": json_errors_message})
def scan_start(taskid): """ Launch a scan """ global tasks if taskid not in tasks: abort(500, "Invalid task ID") # Initialize sqlmap engine's options with user's provided options # within the JSON request for key, value in request.json.items(): tasks[taskid][key] = value # Overwrite output directory (oDir) value to a temporary directory tasks[taskid].oDir = tempfile.mkdtemp(prefix="sqlmap-") # Launch sqlmap engine in a separate thread logger.debug("starting a scan for task ID %s" % taskid) if _multiprocessing: #_multiprocessing.log_to_stderr(logging.DEBUG) p = _multiprocessing.Process(name=taskid, target=start_scan) p.daemon = True p.start() p.join() return jsonize({"success": True})
def scan_start(taskid): """ Launch a scan """ global tasks global procs global pipes if taskid not in tasks: abort(500, "Invalid task ID") # Initialize sqlmap engine's options with user's provided options # within the JSON request for key, value in request.json.items(): tasks[taskid][key] = value # Overwrite output directory (oDir) value to a temporary directory tasks[taskid].oDir = tempfile.mkdtemp(prefix="sqlmap-") # Launch sqlmap engine in a separate thread logger.debug("starting a scan for task ID %s" % taskid) pipes[taskid] = os.pipe() # Provide sqlmap engine with the writable pipe for logging tasks[taskid]["fdLog"] = pipes[taskid][1] # Launch sqlmap engine procs[taskid] = execute("python sqlmap.py --pickled-options %s" % base64pickle(tasks[taskid]), shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=False) return jsonize({"success": True})
def option_list(taskid): """ List options for a certain task ID """ if taskid not in tasks: abort(500, "Invalid task ID") return jsonize({"options": tasks[taskid].get_options()})
def task_list(taskid): """ List all active tasks """ if is_admin(taskid): return jsonize({"tasks": tasks}) else: abort(401)
def option_list(taskid): """ List options for a certain task ID """ if taskid not in tasks: abort(500, "Invalid task ID") return jsonize(tasks[taskid])
def scan_logstruct(taskid): """ Generic function to return the last N lines of structured output """ if taskid not in tasks: abort(500, "Invalid task ID") output = LOG_RECORDER.get_logs(request.GET.get('start'),request.GET.get('end')) return jsonize({"logstruct": output})
def task_destroy(taskid): """ Destroy own task ID """ if taskid in tasks and not is_admin(taskid): tasks.pop(taskid) return jsonize({"success": True}) else: abort(500, "Invalid task ID")
def task_list(taskid): """ List task pull """ if is_admin(taskid): logger.debug("Listed task pull") return jsonize({"tasks": tasks, "tasks_num": len(tasks)}) else: abort(401)
def status(taskid): """ Verify the status of the API as well as the core """ if is_admin(taskid): tasks_num = len(tasks) return jsonize({"tasks": tasks_num}) else: abort(401)
def scan_kill(taskid): """ Kill a scan """ global tasks if taskid not in tasks: abort(500, "Invalid task ID") return jsonize({"success": tasks[taskid].engine_kill()})
def task_destroy(taskid): """ Destroy own task ID """ if taskid in tasks: tasks[taskid].clean_filesystem() tasks.pop(taskid) return jsonize({"success": True}) else: abort(500, "Invalid task ID")
def status(taskid): """ Verify the status of the API as well as the core """ if is_admin(taskid): busy = kb.get("busyFlag") tasks_num = len(tasks) return jsonize({"busy": busy, "tasks": tasks_num}) else: abort(401)
def task_delete(taskid): """ Delete own task ID """ if taskid in tasks: tasks[taskid].clean_filesystem() tasks.pop(taskid) logger.debug("Deleted task ID: %s" % taskid) return jsonize({"success": True}) else: abort(500, "Invalid task ID")
def scan_log(taskid): """ Retrieve the log messages """ if taskid not in tasks: abort(500, "Invalid task ID") LOGGER_OUTPUT.seek(0) output = LOGGER_OUTPUT.read() LOGGER_OUTPUT.flush() LOGGER_OUTPUT.truncate(0) return jsonize({"log": output})
def option_get(taskid): """ Get the value of an option (command line switch) for a certain task ID """ if taskid not in tasks: abort(500, "Invalid task ID") option = request.json.get("option", "") if option in tasks[taskid]: return jsonize({option: tasks[taskid][option]}) else: return jsonize({option: None})
def scan_delete(taskid): """ Delete a scan and corresponding temporary output directory """ global tasks if taskid not in tasks: abort(500, "Invalid task ID") if "oDir" in tasks[taskid] and tasks[taskid].oDir is not None: shutil.rmtree(tasks[taskid].oDir) return jsonize({"success": True})
def scan_delete(taskid): """ Delete a scan and corresponding temporary output directory and IPC database """ global tasks if taskid not in tasks: abort(500, "Invalid task ID") scan_stop(taskid) tasks[taskid].clean_filesystem() return jsonize({"success": True})
def scan_kill(taskid): """ Kill a scan """ global tasks if taskid not in tasks: abort(500, "Invalid task ID") tasks[taskid].engine_kill() logger.debug("Killed scan for task ID %s" % taskid) return jsonize({"success": True})
def option_set(taskid): """ Set an option (command line switch) for a certain task ID """ global tasks if taskid not in tasks: abort(500, "Invalid task ID") for key, value in request.json.items(): tasks[taskid][key] = value return jsonize({"success": True})
def option_set(taskid): """ Set an option (command line switch) for a certain task ID """ global tasks if taskid not in tasks: abort(500, "Invalid task ID") for option, value in request.json.items(): tasks[taskid].set_option(option, value) return jsonize({"success": True})
def scan_status(taskid): """ Returns status of a scan """ global tasks if taskid not in tasks: abort(500, "Invalid task ID") status = "terminated" if tasks[taskid].engine_has_terminated() is True else "running" logger.debug("Requested status of scan for task ID %s" % taskid) return jsonize({"status": status, "returncode": tasks[taskid].engine_get_returncode()})
def scan_output(taskid): """ Read the standard output of sqlmap core execution """ global pipes global tasks if taskid not in tasks: abort(500, "Invalid task ID") stdout = recv_some(procs[taskid], t=1, e=0, stderr=0) stderr = recv_some(procs[taskid], t=1, e=0, stderr=1) return jsonize({"stdout": stdout, "stderr": stderr})
def task_flush(taskid): """ Flush task spool (destroy all tasks) """ global tasks if is_admin(taskid): for task in tasks: tasks[task].clean_filesystem() tasks = dict() return jsonize({"success": True}) else: abort(401)
def task_flush(taskid): """ Flush task spool (delete all tasks) """ global tasks if is_admin(taskid): for task in tasks: tasks[task].clean_filesystem() tasks = dict() logger.debug("Flushed task pull") return jsonize({"success": True}) else: abort(401)
def option_get(taskid): """ Get the value of an option (command line switch) for a certain task ID """ global tasks if taskid not in tasks: abort(500, "Invalid task ID") option = request.json.get("option", "") if option in tasks[taskid]: return jsonize({option: tasks[taskid].get_option(option)}) else: return jsonize({option: "not set"})
def scan_output(taskid): """ Read the standard output of sqlmap core execution """ global tasks if taskid not in tasks: abort(500, "Invalid task ID") sys.stdout.seek(0) output = sys.stdout.read() sys.stdout.flush() sys.stdout.truncate(0) return jsonize({"output": output})
def scan_log(taskid): """ Retrieve the log messages """ log = None if taskid not in tasks: abort(500, "Invalid task ID") pickledLog = os.read(pipes[taskid][0], 100000) try: log = base64unpickle(pickledLog) except (KeyError, IndexError, TypeError), e: logger.error("handled exception when trying to unpickle logger dictionary in scan_log(): %s" % str(e))
def task_flush(taskid): """ Flush task spool (destroy all tasks except admin) """ global adminid global tasks if is_admin(taskid): admin_task = tasks[adminid] tasks = AttribDict() tasks[adminid] = admin_task return jsonize({"success": True}) else: abort(401)
def scan_log(taskid): """ Retrieve the log messages """ global db global tasks json_log_messages = list() if taskid not in tasks: abort(500, "Invalid task ID") # Read all log messages from the IPC database for time_, level, message in db.execute("SELECT time, level, message FROM logs WHERE taskid = ? ORDER BY id ASC", (taskid,)): json_log_messages.append({"time": time_, "level": level, "message": message}) return jsonize({"log": json_log_messages})
def scan_status(taskid): """ Returns status of a scan """ global tasks if taskid not in tasks: abort(500, "Invalid task ID") status = "terminated" if tasks[taskid].engine_has_terminated( ) is True else "running" logger.debug("Requested status of scan for task ID %s" % taskid) return jsonize({ "status": status, "returncode": tasks[taskid].engine_get_returncode() })
def scan_log(taskid): """ Retrieve the log messages """ log = None if taskid not in tasks: abort(500, "Invalid task ID") pickledLog = os.read(pipes[taskid][0], 100000) try: log = base64unpickle(pickledLog) except (KeyError, IndexError, TypeError), e: logger.error( "handled exception when trying to unpickle logger dictionary in scan_log(): %s" % str(e))
def cleanup(taskid): """ Destroy all sessions except admin ID and all output directories """ global tasks if is_admin(taskid): for task, options in tasks.items(): if "oDir" in options and options.oDir is not None: shutil.rmtree(options.oDir) admin_task = tasks[adminid] tasks = AttribDict() tasks[adminid] = admin_task return jsonize({"success": True}) else: abort(401)
def scan_log(taskid): """ Retrieve the log messages """ global db global tasks json_log_messages = list() if taskid not in tasks: abort(500, "Invalid task ID") # Read all log messages from the IPC database for time_, level, message in db.execute( "SELECT time, level, message FROM logs WHERE taskid = ? ORDER BY id ASC", (taskid, )): json_log_messages.append({ "time": time_, "level": level, "message": message }) logger.debug("Retrieved log messages for scan for task ID %s" % taskid) return jsonize({"log": json_log_messages})
def scan_log_limited(taskid, start, end): """ Retrieve the log messages """ log = None if taskid not in tasks: abort(500, "Invalid task ID") if not start.isdigit() or not end.isdigit() or end <= start: abort(500, "Invalid start or end value, must be digits") start = max(0, int(start) - 1) end = max(1, int(end)) pickledLog = os.read(pipes[taskid][0], 100000) try: log = base64unpickle(pickledLog) log = log[slice(start, end)] except (KeyError, IndexError, TypeError), e: logger.error( "handled exception when trying to unpickle logger dictionary in scan_log_limited(): %s" % str(e))
def download(taskid, target, filename): """ Download a certain file from the file system """ if taskid not in tasks: abort(500, "Invalid task ID") # Prevent file path traversal - the lame way if target.startswith("."): abort(500) path = os.path.join(paths.SQLMAP_OUTPUT_PATH, target) if os.path.exists(path): return static_file(filename, root=path) else: abort(500)