added first methods to interact with sqlmap core, it is now possible to launch a scan from the API, hurray! (issue #297)

This commit is contained in:
Bernardo Damele 2012-12-14 14:51:01 +00:00
parent f52d81c834
commit 27906f388f
2 changed files with 82 additions and 16 deletions

View File

@ -45,6 +45,7 @@ from lib.core.testing import smokeTest
from lib.core.testing import liveTest
from lib.parse.cmdline import cmdLineParser
from lib.utils.restapi import restAPIrun
from lib.utils.restapi import restAPIsetup
def modulePath():
"""
@ -58,13 +59,14 @@ def restApiServe():
logger.setLevel(logging.INFO)
cmdLineOptions.batch = True
cmdLineOptions.disableColoring = True
restAPIrun(port=cmdLineOptions.restApiPort or RESTAPI_SERVER_PORT)
restAPIsetup(port=cmdLineOptions.restApiPort or RESTAPI_SERVER_PORT)
def emit(self, record):
message = stdoutencode(FORMATTER.format(record))
sys.stdout.write("%s\n" % message.strip('\r'))
LOGGER_HANDLER.emit = types.MethodType(emit, LOGGER_HANDLER, type(LOGGER_HANDLER))
sys.stdout = StringIO.StringIO()
sys.stderr = StringIO.StringIO()
#sys.stderr = StringIO.StringIO()
restAPIrun(port=cmdLineOptions.restApiPort or RESTAPI_SERVER_PORT)
def main():
"""

View File

@ -18,7 +18,6 @@ except ImportError:
sys.path.append(os.path.join(os.path.abspath(os.path.dirname(__file__)), "..", ".."))
from extra.bottle.bottle import abort
from extra.bottle.bottle import debug
from extra.bottle.bottle import error
from extra.bottle.bottle import get
from extra.bottle.bottle import hook
@ -41,7 +40,8 @@ from lib.core.settings import UNICODE_ENCODING
from lib.core.settings import RESTAPI_SERVER_PORT
# Local global variables
options = AttribDict()
options = {}
output = ""
adminid = ""
tasks = []
@ -51,8 +51,6 @@ def jsonize(data):
def is_admin(taskid):
global adminid
#print "[INFO] Admin ID: %s" % adminid
#print "[INFO] Task ID: %s" % taskid
if adminid != taskid:
return False
else:
@ -103,7 +101,8 @@ def task_new():
Create new task ID
"""
global tasks
taskid = hexencode(os.urandom(32))
taskid = hexencode(os.urandom(16))
options[taskid] = AttribDict(cmdLineOptions)
tasks.append(taskid)
return jsonize({"taskid": taskid})
@ -144,22 +143,63 @@ def task_flush(taskid):
##################################
# sqlmap core interact functions #
##################################
@get("/option/<taskid>/list")
def option_list(taskid):
"""
List options for a certain task ID
"""
global options
if taskid not in tasks:
abort(500, "Invalid task ID")
return jsonize(options[taskid])
@post("/option/<taskid>/get")
def option_get(taskid):
"""
Get the value of an option (command line switch) for a certain task ID
"""
global options
if taskid not in tasks:
abort(500, "Invalid task ID")
option = request.json.get("option", "")
if option in options[taskid]:
print {option: options[taskid][option]}
return jsonize({option: options[taskid][option]})
else:
return jsonize({option: None})
@post("/option/<taskid>/set")
def option_set(taskid):
"""
Set an option (command line switch) for a certain task ID
"""
global options
if taskid not in tasks:
abort(500, "Invalid task ID")
for key, value in request.json.items():
options[taskid][key] = value
return jsonize({"success": True})
@post("/scan/<taskid>")
def scan(taskid):
"""
Mount a scan with sqlmap
Launch a scan
"""
global options
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():
if key != "taskid":
options[key] = value
init(options, True)
options[taskid][key] = value
init(options[taskid], True)
# Launch sqlmap engine in a separate thread
thread = threading.Thread(target=start)
@ -168,6 +208,29 @@ def scan(taskid):
return jsonize({"success": True})
@get("/scan/<taskid>/status")
def scan_status(taskid):
"""
Verify if sqlmap core is currently running
"""
if taskid not in tasks:
abort(500, "Invalid task ID")
return jsonize({"busy": kb.get("busyFlag")})
@get("/scan/<taskid>/output")
def scan_output(taskid):
"""
Read the standard output of sqlmap core execution
"""
if taskid not in tasks:
abort(500, "Invalid task ID")
global output
sys.stdout.seek(len(output))
output = sys.stdout.read()
return jsonize({"output": output})
@post("/download/<taskid>/<target>/<filename:path>")
def download(taskid, target, filename):
"""
@ -182,18 +245,19 @@ def download(taskid, target, filename):
else:
abort(500)
def restAPIrun(host="0.0.0.0", port=RESTAPI_SERVER_PORT):
def restAPIsetup(host="0.0.0.0", port=RESTAPI_SERVER_PORT):
"""
Initiate REST-JSON API
"""
global adminid
global options
global tasks
adminid = hexencode(os.urandom(32))
adminid = hexencode(os.urandom(16))
options[adminid] = AttribDict(cmdLineOptions)
tasks.append(adminid)
options = AttribDict(cmdLineOptions)
logger.info("Running REST-JSON API server at '%s:%d'.." % (host, port))
logger.info("The admin task ID is: %s" % adminid)
def restAPIrun(host="0.0.0.0", port=RESTAPI_SERVER_PORT):
run(host=host, port=port)
def client(host, port):