mirror of
				https://github.com/sqlmapproject/sqlmap.git
				synced 2025-11-04 01:47:37 +03:00 
			
		
		
		
	Implements #2647 (Basic authorization for sqlmapapi)
This commit is contained in:
		
							parent
							
								
									68ee1f361b
								
							
						
					
					
						commit
						fac6712a35
					
				| 
						 | 
					@ -19,7 +19,7 @@ from lib.core.enums import DBMS_DIRECTORY_NAME
 | 
				
			||||||
from lib.core.enums import OS
 | 
					from lib.core.enums import OS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
 | 
					# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
 | 
				
			||||||
VERSION = "1.1.7.31"
 | 
					VERSION = "1.1.8.0"
 | 
				
			||||||
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
 | 
					TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
 | 
				
			||||||
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
 | 
					TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
 | 
				
			||||||
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
 | 
					VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,6 +7,7 @@ See the file 'doc/COPYING' for copying permission
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import contextlib
 | 
					import contextlib
 | 
				
			||||||
 | 
					import httplib
 | 
				
			||||||
import logging
 | 
					import logging
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
import re
 | 
					import re
 | 
				
			||||||
| 
						 | 
					@ -43,6 +44,7 @@ from lib.core.settings import RESTAPI_DEFAULT_ADDRESS
 | 
				
			||||||
from lib.core.settings import RESTAPI_DEFAULT_PORT
 | 
					from lib.core.settings import RESTAPI_DEFAULT_PORT
 | 
				
			||||||
from lib.core.subprocessng import Popen
 | 
					from lib.core.subprocessng import Popen
 | 
				
			||||||
from lib.parse.cmdline import cmdLineParser
 | 
					from lib.parse.cmdline import cmdLineParser
 | 
				
			||||||
 | 
					from thirdparty.bottle.bottle import abort
 | 
				
			||||||
from thirdparty.bottle.bottle import error as return_error
 | 
					from thirdparty.bottle.bottle import error as return_error
 | 
				
			||||||
from thirdparty.bottle.bottle import get
 | 
					from thirdparty.bottle.bottle import get
 | 
				
			||||||
from thirdparty.bottle.bottle import hook
 | 
					from thirdparty.bottle.bottle import hook
 | 
				
			||||||
| 
						 | 
					@ -52,13 +54,13 @@ from thirdparty.bottle.bottle import response
 | 
				
			||||||
from thirdparty.bottle.bottle import run
 | 
					from thirdparty.bottle.bottle import run
 | 
				
			||||||
from thirdparty.bottle.bottle import server_names
 | 
					from thirdparty.bottle.bottle import server_names
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Global data storage
 | 
				
			||||||
# global settings
 | 
					 | 
				
			||||||
class DataStore(object):
 | 
					class DataStore(object):
 | 
				
			||||||
    admin_id = ""
 | 
					    admin_id = ""
 | 
				
			||||||
    current_db = None
 | 
					    current_db = None
 | 
				
			||||||
    tasks = dict()
 | 
					    tasks = dict()
 | 
				
			||||||
 | 
					    username = None
 | 
				
			||||||
 | 
					    password = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# API objects
 | 
					# API objects
 | 
				
			||||||
class Database(object):
 | 
					class Database(object):
 | 
				
			||||||
| 
						 | 
					@ -118,7 +120,6 @@ class Database(object):
 | 
				
			||||||
                    "taskid INTEGER, error TEXT"
 | 
					                    "taskid INTEGER, error TEXT"
 | 
				
			||||||
                    ")")
 | 
					                    ")")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class Task(object):
 | 
					class Task(object):
 | 
				
			||||||
    def __init__(self, taskid, remote_addr):
 | 
					    def __init__(self, taskid, remote_addr):
 | 
				
			||||||
        self.remote_addr = remote_addr
 | 
					        self.remote_addr = remote_addr
 | 
				
			||||||
| 
						 | 
					@ -283,11 +284,32 @@ def setRestAPILog():
 | 
				
			||||||
        LOGGER_RECORDER = LogRecorder()
 | 
					        LOGGER_RECORDER = LogRecorder()
 | 
				
			||||||
        logger.addHandler(LOGGER_RECORDER)
 | 
					        logger.addHandler(LOGGER_RECORDER)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
# Generic functions
 | 
					# Generic functions
 | 
				
			||||||
def is_admin(taskid):
 | 
					def is_admin(taskid):
 | 
				
			||||||
    return DataStore.admin_id == taskid
 | 
					    return DataStore.admin_id == taskid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@hook('before_request')
 | 
				
			||||||
 | 
					def check_authentication():
 | 
				
			||||||
 | 
					    if not any((DataStore.username, DataStore.password)):
 | 
				
			||||||
 | 
					        return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    authorization = request.headers.get("Authorization", "")
 | 
				
			||||||
 | 
					    match = re.search(r"(?i)\ABasic\s+([^\s]+)", authorization)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if not match:
 | 
				
			||||||
 | 
					        request.environ["PATH_INFO"] = "/error/401"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        creds = match.group(1).decode("base64")
 | 
				
			||||||
 | 
					    except:
 | 
				
			||||||
 | 
					        request.environ["PATH_INFO"] = "/error/401"
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        if creds.count(':') != 1:
 | 
				
			||||||
 | 
					            request.environ["PATH_INFO"] = "/error/401"
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            username, password = creds.split(':')
 | 
				
			||||||
 | 
					            if username.strip() != (DataStore.username or "") or password.strip() != (DataStore.password or ""):
 | 
				
			||||||
 | 
					                request.environ["PATH_INFO"] = "/error/401"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@hook("after_request")
 | 
					@hook("after_request")
 | 
				
			||||||
def security_headers(json_header=True):
 | 
					def security_headers(json_header=True):
 | 
				
			||||||
| 
						 | 
					@ -301,6 +323,7 @@ def security_headers(json_header=True):
 | 
				
			||||||
    response.headers["Pragma"] = "no-cache"
 | 
					    response.headers["Pragma"] = "no-cache"
 | 
				
			||||||
    response.headers["Cache-Control"] = "no-cache"
 | 
					    response.headers["Cache-Control"] = "no-cache"
 | 
				
			||||||
    response.headers["Expires"] = "0"
 | 
					    response.headers["Expires"] = "0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if json_header:
 | 
					    if json_header:
 | 
				
			||||||
        response.content_type = "application/json; charset=UTF-8"
 | 
					        response.content_type = "application/json; charset=UTF-8"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -308,35 +331,39 @@ def security_headers(json_header=True):
 | 
				
			||||||
# HTTP Status Code functions #
 | 
					# HTTP Status Code functions #
 | 
				
			||||||
##############################
 | 
					##############################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
@return_error(401)  # Access Denied
 | 
					@return_error(401)  # Access Denied
 | 
				
			||||||
def error401(error=None):
 | 
					def error401(error=None):
 | 
				
			||||||
    security_headers(False)
 | 
					    security_headers(False)
 | 
				
			||||||
    return "Access denied"
 | 
					    return "Access denied"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
@return_error(404)  # Not Found
 | 
					@return_error(404)  # Not Found
 | 
				
			||||||
def error404(error=None):
 | 
					def error404(error=None):
 | 
				
			||||||
    security_headers(False)
 | 
					    security_headers(False)
 | 
				
			||||||
    return "Nothing here"
 | 
					    return "Nothing here"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
@return_error(405)  # Method Not Allowed (e.g. when requesting a POST method via GET)
 | 
					@return_error(405)  # Method Not Allowed (e.g. when requesting a POST method via GET)
 | 
				
			||||||
def error405(error=None):
 | 
					def error405(error=None):
 | 
				
			||||||
    security_headers(False)
 | 
					    security_headers(False)
 | 
				
			||||||
    return "Method not allowed"
 | 
					    return "Method not allowed"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
@return_error(500)  # Internal Server Error
 | 
					@return_error(500)  # Internal Server Error
 | 
				
			||||||
def error500(error=None):
 | 
					def error500(error=None):
 | 
				
			||||||
    security_headers(False)
 | 
					    security_headers(False)
 | 
				
			||||||
    return "Internal server error"
 | 
					    return "Internal server error"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#############
 | 
				
			||||||
 | 
					# Auxiliary #
 | 
				
			||||||
 | 
					#############
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@get('/error/401')
 | 
				
			||||||
 | 
					def path_401():
 | 
				
			||||||
 | 
					    response.status = 401
 | 
				
			||||||
 | 
					    return response
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#############################
 | 
					#############################
 | 
				
			||||||
# Task management functions #
 | 
					# Task management functions #
 | 
				
			||||||
#############################
 | 
					#############################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
# Users' methods
 | 
					# Users' methods
 | 
				
			||||||
@get("/task/new")
 | 
					@get("/task/new")
 | 
				
			||||||
def task_new():
 | 
					def task_new():
 | 
				
			||||||
| 
						 | 
					@ -351,7 +378,6 @@ def task_new():
 | 
				
			||||||
    logger.debug("Created new task: '%s'" % taskid)
 | 
					    logger.debug("Created new task: '%s'" % taskid)
 | 
				
			||||||
    return jsonize({"success": True, "taskid": taskid})
 | 
					    return jsonize({"success": True, "taskid": taskid})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
@get("/task/<taskid>/delete")
 | 
					@get("/task/<taskid>/delete")
 | 
				
			||||||
def task_delete(taskid):
 | 
					def task_delete(taskid):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
| 
						 | 
					@ -370,7 +396,6 @@ def task_delete(taskid):
 | 
				
			||||||
# Admin functions #
 | 
					# Admin functions #
 | 
				
			||||||
###################
 | 
					###################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
@get("/admin/<taskid>/list")
 | 
					@get("/admin/<taskid>/list")
 | 
				
			||||||
def task_list(taskid=None):
 | 
					def task_list(taskid=None):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
| 
						 | 
					@ -403,7 +428,6 @@ def task_flush(taskid):
 | 
				
			||||||
# sqlmap core interact functions #
 | 
					# sqlmap core interact functions #
 | 
				
			||||||
##################################
 | 
					##################################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
# Handle task's options
 | 
					# Handle task's options
 | 
				
			||||||
@get("/option/<taskid>/list")
 | 
					@get("/option/<taskid>/list")
 | 
				
			||||||
def option_list(taskid):
 | 
					def option_list(taskid):
 | 
				
			||||||
| 
						 | 
					@ -417,7 +441,6 @@ def option_list(taskid):
 | 
				
			||||||
    logger.debug("[%s] Listed task options" % taskid)
 | 
					    logger.debug("[%s] Listed task options" % taskid)
 | 
				
			||||||
    return jsonize({"success": True, "options": DataStore.tasks[taskid].get_options()})
 | 
					    return jsonize({"success": True, "options": DataStore.tasks[taskid].get_options()})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
@post("/option/<taskid>/get")
 | 
					@post("/option/<taskid>/get")
 | 
				
			||||||
def option_get(taskid):
 | 
					def option_get(taskid):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
| 
						 | 
					@ -436,12 +459,12 @@ def option_get(taskid):
 | 
				
			||||||
        logger.debug("[%s] Requested value for unknown option %s" % (taskid, option))
 | 
					        logger.debug("[%s] Requested value for unknown option %s" % (taskid, option))
 | 
				
			||||||
        return jsonize({"success": False, "message": "Unknown option", option: "not set"})
 | 
					        return jsonize({"success": False, "message": "Unknown option", option: "not set"})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
@post("/option/<taskid>/set")
 | 
					@post("/option/<taskid>/set")
 | 
				
			||||||
def option_set(taskid):
 | 
					def option_set(taskid):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Set an option (command line switch) for a certain task ID
 | 
					    Set an option (command line switch) for a certain task ID
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if taskid not in DataStore.tasks:
 | 
					    if taskid not in DataStore.tasks:
 | 
				
			||||||
        logger.warning("[%s] Invalid task ID provided to option_set()" % taskid)
 | 
					        logger.warning("[%s] Invalid task ID provided to option_set()" % taskid)
 | 
				
			||||||
        return jsonize({"success": False, "message": "Invalid task ID"})
 | 
					        return jsonize({"success": False, "message": "Invalid task ID"})
 | 
				
			||||||
| 
						 | 
					@ -452,13 +475,13 @@ def option_set(taskid):
 | 
				
			||||||
    logger.debug("[%s] Requested to set options" % taskid)
 | 
					    logger.debug("[%s] Requested to set options" % taskid)
 | 
				
			||||||
    return jsonize({"success": True})
 | 
					    return jsonize({"success": True})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
# Handle scans
 | 
					# Handle scans
 | 
				
			||||||
@post("/scan/<taskid>/start")
 | 
					@post("/scan/<taskid>/start")
 | 
				
			||||||
def scan_start(taskid):
 | 
					def scan_start(taskid):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Launch a scan
 | 
					    Launch a scan
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if taskid not in DataStore.tasks:
 | 
					    if taskid not in DataStore.tasks:
 | 
				
			||||||
        logger.warning("[%s] Invalid task ID provided to scan_start()" % taskid)
 | 
					        logger.warning("[%s] Invalid task ID provided to scan_start()" % taskid)
 | 
				
			||||||
        return jsonize({"success": False, "message": "Invalid task ID"})
 | 
					        return jsonize({"success": False, "message": "Invalid task ID"})
 | 
				
			||||||
| 
						 | 
					@ -473,12 +496,12 @@ def scan_start(taskid):
 | 
				
			||||||
    logger.debug("[%s] Started scan" % taskid)
 | 
					    logger.debug("[%s] Started scan" % taskid)
 | 
				
			||||||
    return jsonize({"success": True, "engineid": DataStore.tasks[taskid].engine_get_id()})
 | 
					    return jsonize({"success": True, "engineid": DataStore.tasks[taskid].engine_get_id()})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
@get("/scan/<taskid>/stop")
 | 
					@get("/scan/<taskid>/stop")
 | 
				
			||||||
def scan_stop(taskid):
 | 
					def scan_stop(taskid):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Stop a scan
 | 
					    Stop a scan
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (taskid not in DataStore.tasks or
 | 
					    if (taskid not in DataStore.tasks or
 | 
				
			||||||
            DataStore.tasks[taskid].engine_process() is None or
 | 
					            DataStore.tasks[taskid].engine_process() is None or
 | 
				
			||||||
            DataStore.tasks[taskid].engine_has_terminated()):
 | 
					            DataStore.tasks[taskid].engine_has_terminated()):
 | 
				
			||||||
| 
						 | 
					@ -490,12 +513,12 @@ def scan_stop(taskid):
 | 
				
			||||||
    logger.debug("[%s] Stopped scan" % taskid)
 | 
					    logger.debug("[%s] Stopped scan" % taskid)
 | 
				
			||||||
    return jsonize({"success": True})
 | 
					    return jsonize({"success": True})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
@get("/scan/<taskid>/kill")
 | 
					@get("/scan/<taskid>/kill")
 | 
				
			||||||
def scan_kill(taskid):
 | 
					def scan_kill(taskid):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Kill a scan
 | 
					    Kill a scan
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (taskid not in DataStore.tasks or
 | 
					    if (taskid not in DataStore.tasks or
 | 
				
			||||||
            DataStore.tasks[taskid].engine_process() is None or
 | 
					            DataStore.tasks[taskid].engine_process() is None or
 | 
				
			||||||
            DataStore.tasks[taskid].engine_has_terminated()):
 | 
					            DataStore.tasks[taskid].engine_has_terminated()):
 | 
				
			||||||
| 
						 | 
					@ -507,12 +530,12 @@ def scan_kill(taskid):
 | 
				
			||||||
    logger.debug("[%s] Killed scan" % taskid)
 | 
					    logger.debug("[%s] Killed scan" % taskid)
 | 
				
			||||||
    return jsonize({"success": True})
 | 
					    return jsonize({"success": True})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
@get("/scan/<taskid>/status")
 | 
					@get("/scan/<taskid>/status")
 | 
				
			||||||
def scan_status(taskid):
 | 
					def scan_status(taskid):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Returns status of a scan
 | 
					    Returns status of a scan
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if taskid not in DataStore.tasks:
 | 
					    if taskid not in DataStore.tasks:
 | 
				
			||||||
        logger.warning("[%s] Invalid task ID provided to scan_status()" % taskid)
 | 
					        logger.warning("[%s] Invalid task ID provided to scan_status()" % taskid)
 | 
				
			||||||
        return jsonize({"success": False, "message": "Invalid task ID"})
 | 
					        return jsonize({"success": False, "message": "Invalid task ID"})
 | 
				
			||||||
| 
						 | 
					@ -529,12 +552,12 @@ def scan_status(taskid):
 | 
				
			||||||
        "returncode": DataStore.tasks[taskid].engine_get_returncode()
 | 
					        "returncode": DataStore.tasks[taskid].engine_get_returncode()
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
@get("/scan/<taskid>/data")
 | 
					@get("/scan/<taskid>/data")
 | 
				
			||||||
def scan_data(taskid):
 | 
					def scan_data(taskid):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Retrieve the data of a scan
 | 
					    Retrieve the data of a scan
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    json_data_message = list()
 | 
					    json_data_message = list()
 | 
				
			||||||
    json_errors_message = list()
 | 
					    json_errors_message = list()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -560,6 +583,7 @@ def scan_log_limited(taskid, start, end):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Retrieve a subset of log messages
 | 
					    Retrieve a subset of log messages
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    json_log_messages = list()
 | 
					    json_log_messages = list()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if taskid not in DataStore.tasks:
 | 
					    if taskid not in DataStore.tasks:
 | 
				
			||||||
| 
						 | 
					@ -586,6 +610,7 @@ def scan_log(taskid):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Retrieve the log messages
 | 
					    Retrieve the log messages
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    json_log_messages = list()
 | 
					    json_log_messages = list()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if taskid not in DataStore.tasks:
 | 
					    if taskid not in DataStore.tasks:
 | 
				
			||||||
| 
						 | 
					@ -606,6 +631,7 @@ def download(taskid, target, filename):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Download a certain file from the file system
 | 
					    Download a certain file from the file system
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if taskid not in DataStore.tasks:
 | 
					    if taskid not in DataStore.tasks:
 | 
				
			||||||
        logger.warning("[%s] Invalid task ID provided to download()" % taskid)
 | 
					        logger.warning("[%s] Invalid task ID provided to download()" % taskid)
 | 
				
			||||||
        return jsonize({"success": False, "message": "Invalid task ID"})
 | 
					        return jsonize({"success": False, "message": "Invalid task ID"})
 | 
				
			||||||
| 
						 | 
					@ -626,13 +652,17 @@ def download(taskid, target, filename):
 | 
				
			||||||
        return jsonize({"success": False, "message": "File does not exist"})
 | 
					        return jsonize({"success": False, "message": "File does not exist"})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def server(host=RESTAPI_DEFAULT_ADDRESS, port=RESTAPI_DEFAULT_PORT, adapter=RESTAPI_DEFAULT_ADAPTER):
 | 
					def server(host=RESTAPI_DEFAULT_ADDRESS, port=RESTAPI_DEFAULT_PORT, adapter=RESTAPI_DEFAULT_ADAPTER, username=None, password=None):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    REST-JSON API server
 | 
					    REST-JSON API server
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    DataStore.admin_id = hexencode(os.urandom(16))
 | 
					    DataStore.admin_id = hexencode(os.urandom(16))
 | 
				
			||||||
    handle, Database.filepath = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.IPC, text=False)
 | 
					    DataStore.username = username
 | 
				
			||||||
    os.close(handle)
 | 
					    DataStore.password = password
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    _, Database.filepath = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.IPC, text=False)
 | 
				
			||||||
 | 
					    os.close(_)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if port == 0:  # random
 | 
					    if port == 0:  # random
 | 
				
			||||||
        with contextlib.closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
 | 
					        with contextlib.closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
 | 
				
			||||||
| 
						 | 
					@ -660,7 +690,7 @@ def server(host=RESTAPI_DEFAULT_ADDRESS, port=RESTAPI_DEFAULT_PORT, adapter=REST
 | 
				
			||||||
            import eventlet
 | 
					            import eventlet
 | 
				
			||||||
            eventlet.monkey_patch()
 | 
					            eventlet.monkey_patch()
 | 
				
			||||||
        logger.debug("Using adapter '%s' to run bottle" % adapter)
 | 
					        logger.debug("Using adapter '%s' to run bottle" % adapter)
 | 
				
			||||||
        run(host=host, port=port, quiet=True, debug=False, server=adapter)
 | 
					        run(host=host, port=port, quiet=True, debug=True, server=adapter)
 | 
				
			||||||
    except socket.error, ex:
 | 
					    except socket.error, ex:
 | 
				
			||||||
        if "already in use" in getSafeExString(ex):
 | 
					        if "already in use" in getSafeExString(ex):
 | 
				
			||||||
            logger.error("Address already in use ('%s:%s')" % (host, port))
 | 
					            logger.error("Address already in use ('%s:%s')" % (host, port))
 | 
				
			||||||
| 
						 | 
					@ -681,7 +711,12 @@ def _client(url, options=None):
 | 
				
			||||||
        data = None
 | 
					        data = None
 | 
				
			||||||
        if options is not None:
 | 
					        if options is not None:
 | 
				
			||||||
            data = jsonize(options)
 | 
					            data = jsonize(options)
 | 
				
			||||||
        req = urllib2.Request(url, data, {"Content-Type": "application/json"})
 | 
					        headers = {"Content-Type": "application/json"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if DataStore.username or DataStore.password:
 | 
				
			||||||
 | 
					            headers["Authorization"] = "Basic %s" % ("%s:%s" % (DataStore.username or "", DataStore.password or "")).encode("base64").strip()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        req = urllib2.Request(url, data, headers)
 | 
				
			||||||
        response = urllib2.urlopen(req)
 | 
					        response = urllib2.urlopen(req)
 | 
				
			||||||
        text = response.read()
 | 
					        text = response.read()
 | 
				
			||||||
    except:
 | 
					    except:
 | 
				
			||||||
| 
						 | 
					@ -690,12 +725,14 @@ def _client(url, options=None):
 | 
				
			||||||
        raise
 | 
					        raise
 | 
				
			||||||
    return text
 | 
					    return text
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def client(host=RESTAPI_DEFAULT_ADDRESS, port=RESTAPI_DEFAULT_PORT, username=None, password=None):
 | 
				
			||||||
def client(host=RESTAPI_DEFAULT_ADDRESS, port=RESTAPI_DEFAULT_PORT):
 | 
					 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    REST-JSON API client
 | 
					    REST-JSON API client
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    DataStore.username = username
 | 
				
			||||||
 | 
					    DataStore.password = password
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    dbgMsg = "Example client access from command line:"
 | 
					    dbgMsg = "Example client access from command line:"
 | 
				
			||||||
    dbgMsg += "\n\t$ taskid=$(curl http://%s:%d/task/new 2>1 | grep -o -I '[a-f0-9]\{16\}') && echo $taskid" % (host, port)
 | 
					    dbgMsg += "\n\t$ taskid=$(curl http://%s:%d/task/new 2>1 | grep -o -I '[a-f0-9]\{16\}') && echo $taskid" % (host, port)
 | 
				
			||||||
    dbgMsg += "\n\t$ curl -H \"Content-Type: application/json\" -X POST -d '{\"url\": \"http://testphp.vulnweb.com/artists.php?artist=1\"}' http://%s:%d/scan/$taskid/start" % (host, port)
 | 
					    dbgMsg += "\n\t$ curl -H \"Content-Type: application/json\" -X POST -d '{\"url\": \"http://testphp.vulnweb.com/artists.php?artist=1\"}' http://%s:%d/scan/$taskid/start" % (host, port)
 | 
				
			||||||
| 
						 | 
					@ -709,7 +746,7 @@ def client(host=RESTAPI_DEFAULT_ADDRESS, port=RESTAPI_DEFAULT_PORT):
 | 
				
			||||||
    try:
 | 
					    try:
 | 
				
			||||||
        _client(addr)
 | 
					        _client(addr)
 | 
				
			||||||
    except Exception, ex:
 | 
					    except Exception, ex:
 | 
				
			||||||
        if not isinstance(ex, urllib2.HTTPError):
 | 
					        if not isinstance(ex, urllib2.HTTPError) or ex.code == httplib.UNAUTHORIZED:
 | 
				
			||||||
            errMsg = "There has been a problem while connecting to the "
 | 
					            errMsg = "There has been a problem while connecting to the "
 | 
				
			||||||
            errMsg += "REST-JSON API server at '%s' " % addr
 | 
					            errMsg += "REST-JSON API server at '%s' " % addr
 | 
				
			||||||
            errMsg += "(%s)" % ex
 | 
					            errMsg += "(%s)" % ex
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,13 +40,15 @@ def main():
 | 
				
			||||||
    apiparser.add_option("-H", "--host", help="Host of the REST-JSON API server (default \"%s\")" % RESTAPI_DEFAULT_ADDRESS, default=RESTAPI_DEFAULT_ADDRESS, action="store")
 | 
					    apiparser.add_option("-H", "--host", help="Host of the REST-JSON API server (default \"%s\")" % RESTAPI_DEFAULT_ADDRESS, default=RESTAPI_DEFAULT_ADDRESS, action="store")
 | 
				
			||||||
    apiparser.add_option("-p", "--port", help="Port of the the REST-JSON API server (default %d)" % RESTAPI_DEFAULT_PORT, default=RESTAPI_DEFAULT_PORT, type="int", action="store")
 | 
					    apiparser.add_option("-p", "--port", help="Port of the the REST-JSON API server (default %d)" % RESTAPI_DEFAULT_PORT, default=RESTAPI_DEFAULT_PORT, type="int", action="store")
 | 
				
			||||||
    apiparser.add_option("--adapter", help="Server (bottle) adapter to use (default \"%s\")" % RESTAPI_DEFAULT_ADAPTER, default=RESTAPI_DEFAULT_ADAPTER, action="store")
 | 
					    apiparser.add_option("--adapter", help="Server (bottle) adapter to use (default \"%s\")" % RESTAPI_DEFAULT_ADAPTER, default=RESTAPI_DEFAULT_ADAPTER, action="store")
 | 
				
			||||||
 | 
					    apiparser.add_option("--username", help="Basic authentication username (optional)", action="store")
 | 
				
			||||||
 | 
					    apiparser.add_option("--password", help="Basic authentication password (optional)", action="store")
 | 
				
			||||||
    (args, _) = apiparser.parse_args()
 | 
					    (args, _) = apiparser.parse_args()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Start the client or the server
 | 
					    # Start the client or the server
 | 
				
			||||||
    if args.server is True:
 | 
					    if args.server is True:
 | 
				
			||||||
        server(args.host, args.port, adapter=args.adapter)
 | 
					        server(args.host, args.port, adapter=args.adapter, username=args.username, password=args.password)
 | 
				
			||||||
    elif args.client is True:
 | 
					    elif args.client is True:
 | 
				
			||||||
        client(args.host, args.port)
 | 
					        client(args.host, args.port, username=args.username, password=args.password)
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
        apiparser.print_help()
 | 
					        apiparser.print_help()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -46,7 +46,7 @@ fbf750dc617c3549ee423d6c2334ba4d  lib/core/option.py
 | 
				
			||||||
d8e9250f3775119df07e9070eddccd16  lib/core/replication.py
 | 
					d8e9250f3775119df07e9070eddccd16  lib/core/replication.py
 | 
				
			||||||
785f86e3f963fa3798f84286a4e83ff2  lib/core/revision.py
 | 
					785f86e3f963fa3798f84286a4e83ff2  lib/core/revision.py
 | 
				
			||||||
40c80b28b3a5819b737a5a17d4565ae9  lib/core/session.py
 | 
					40c80b28b3a5819b737a5a17d4565ae9  lib/core/session.py
 | 
				
			||||||
d6dc3f75b2f3aff43a7f3382059bea76  lib/core/settings.py
 | 
					2a84a6aba8a3c553fdf6058a011a491f  lib/core/settings.py
 | 
				
			||||||
d91291997d2bd2f6028aaf371bf1d3b6  lib/core/shell.py
 | 
					d91291997d2bd2f6028aaf371bf1d3b6  lib/core/shell.py
 | 
				
			||||||
2ad85c130cc5f2b3701ea85c2f6bbf20  lib/core/subprocessng.py
 | 
					2ad85c130cc5f2b3701ea85c2f6bbf20  lib/core/subprocessng.py
 | 
				
			||||||
85e3a98bc9ba62125baa13e864f37a3f  lib/core/target.py
 | 
					85e3a98bc9ba62125baa13e864f37a3f  lib/core/target.py
 | 
				
			||||||
| 
						 | 
					@ -98,7 +98,7 @@ d3da4c7ceaf57c4687a052d58722f6bb  lib/techniques/dns/use.py
 | 
				
			||||||
310efc965c862cfbd7b0da5150a5ad36  lib/techniques/union/__init__.py
 | 
					310efc965c862cfbd7b0da5150a5ad36  lib/techniques/union/__init__.py
 | 
				
			||||||
d71e48e6fd08f75cc612bf8b260994ce  lib/techniques/union/test.py
 | 
					d71e48e6fd08f75cc612bf8b260994ce  lib/techniques/union/test.py
 | 
				
			||||||
db3090ff9a740ba096ba676fcf44ebfc  lib/techniques/union/use.py
 | 
					db3090ff9a740ba096ba676fcf44ebfc  lib/techniques/union/use.py
 | 
				
			||||||
9e903297f6d6bb11660af5c7b109ccab  lib/utils/api.py
 | 
					720e899d5097d701d258bdc30eb8aa51  lib/utils/api.py
 | 
				
			||||||
7d10ba0851da8ee9cd3c140dcd18798e  lib/utils/brute.py
 | 
					7d10ba0851da8ee9cd3c140dcd18798e  lib/utils/brute.py
 | 
				
			||||||
c08d2487a53a1db8170178ebcf87c864  lib/utils/crawler.py
 | 
					c08d2487a53a1db8170178ebcf87c864  lib/utils/crawler.py
 | 
				
			||||||
ba12c69a90061aa14d848b8396e79191  lib/utils/deps.py
 | 
					ba12c69a90061aa14d848b8396e79191  lib/utils/deps.py
 | 
				
			||||||
| 
						 | 
					@ -223,7 +223,7 @@ b04db3e861edde1f9dd0a3850d5b96c8  shell/backdoor.asp_
 | 
				
			||||||
c3cc8b7727161e64ab59f312c33b541a  shell/stager.aspx_
 | 
					c3cc8b7727161e64ab59f312c33b541a  shell/stager.aspx_
 | 
				
			||||||
1f7f125f30e0e800beb21e2ebbab18e1  shell/stager.jsp_
 | 
					1f7f125f30e0e800beb21e2ebbab18e1  shell/stager.jsp_
 | 
				
			||||||
01e3505e796edf19aad6a996101c81c9  shell/stager.php_
 | 
					01e3505e796edf19aad6a996101c81c9  shell/stager.php_
 | 
				
			||||||
0751a45ac4c130131f2cdb74d866b664  sqlmapapi.py
 | 
					8755985bcb91e3fea7aaaea3e98ec2dc  sqlmapapi.py
 | 
				
			||||||
41a637eda3e182d520fa4fb435edc1ec  sqlmap.py
 | 
					41a637eda3e182d520fa4fb435edc1ec  sqlmap.py
 | 
				
			||||||
08c711a470d7e0bf705320ba3c48b886  tamper/apostrophemask.py
 | 
					08c711a470d7e0bf705320ba3c48b886  tamper/apostrophemask.py
 | 
				
			||||||
e8509df10d3f1c28014d7825562d32dd  tamper/apostrophenullencode.py
 | 
					e8509df10d3f1c28014d7825562d32dd  tamper/apostrophenullencode.py
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user