[19:53:57] [INFO] Running REST-JSON API server at '127.0.0.1:8775'..
[19:53:57] [INFO] Admin (secret) token: 1acac56427f272e316fceabe5ddff5a5
[19:53:57] [DEBUG] IPC database: '/tmp/sqlmapipc-zOIGm_'
[19:53:57] [DEBUG] REST-JSON API server connected to IPC database
[19:53:57] [DEBUG] Using adapter 'wsgiref' to run bottle
api> help
help 显示帮助信息
new ARGS 开启一个新的扫描任务
use TASKID 切换taskid
data 获取当前任务返回的数据
log 获取当前任务的扫描日志
status 获取当前任务的扫描状态
option OPTION 获取当前任务的选项
options 获取当前任务的所有配置信息
stop 停止当前任务
kill 杀死当前任务
list 显示所有任务列表
flush 清空所有任务
exit 退出客户端 t
def task_flush(token=None):
"""
Flush task spool (delete all tasks)
"""
for key in list(DataStore.tasks):
if is_admin(token) or DataStore.tasks[key].remote_addr == request.remote_addr:
DataStore.tasks[key].engine_kill()
del DataStore.tasks[key]
logger.debug("(%s) Flushed task pool (%s)" % (token, "admin" if is_admin(token) else request.remote_addr))
return jsonize({"success": True})
下图是调用该接口的截图:
@get("/option//list")
该接口可获取特定任务ID的列表选项,调用时请指定taskid,不然会出现问题。具体代码如下:
def option_list(taskid):
"""
List options for a certain task ID
"""
if taskid not in DataStore.tasks:
logger.warning("[%s] Invalid task ID provided to option_list()" % taskid)
return jsonize({"success": False, "message": "Invalid task ID"})
logger.debug("(%s) Listed task options" % taskid)
return jsonize({"success": True, "options": DataStore.tasks[taskid].get_options()})
下图是调用该接口的截图:
@post("/option//get")
该接口可获取特定任务ID的选项值,调用时请指定taskid,不然会出现问题。具体代码如下:
def option_get(taskid):
"""
Get value of option(s) for a certain task ID
"""
if taskid not in DataStore.tasks:
logger.warning("[%s] Invalid task ID provided to option_get()" % taskid)
return jsonize({"success": False, "message": "Invalid task ID"})
options = request.json or []
results = {}
for option in options:
if option in DataStore.tasks[taskid].options:
results[option] = DataStore.tasks[taskid].options[option]
else:
logger.debug("(%s) Requested value for unknown option '%s'" % (taskid, option))
return jsonize({"success": False, "message": "Unknown option '%s'" % option})
logger.debug("(%s) Retrieved values for option(s) '%s'" % (taskid, ",".join(options)))
return jsonize({"success": True, "options": results})
下图是调用该接口的截图:
@post("/option//set")
该接口为特定任务ID设置选项值,调用时请指定taskid,不然会出现问题。具体代码如下:
def option_set(taskid):
"""
Set value of option(s) for a certain task ID
"""
if taskid not in DataStore.tasks:
logger.warning("[%s] Invalid task ID provided to option_set()" % taskid)
return jsonize({"success": False, "message": "Invalid task ID"})
if request.json is None:
logger.warning("[%s] Invalid JSON options provided to option_set()" % taskid)
return jsonize({"success": False, "message": "Invalid JSON options"})
for option, value in request.json.items():
DataStore.tasks[taskid].set_option(option, value)
logger.debug("(%s) Requested to set options" % taskid)
return jsonize({"success": True})
下图是调用该接口的截图:
@post("/scan//start")
该接口定义开始扫描特定任务,调用时请指定taskid,不然会出现问题。具体代码如下:
def scan_start(taskid):
"""
Launch a scan
"""
if taskid not in DataStore.tasks:
logger.warning("[%s] Invalid task ID provided to scan_start()" % taskid)
return jsonize({"success": False, "message": "Invalid task ID"})
if request.json is None:
logger.warning("[%s] Invalid JSON options provided to scan_start()" % taskid)
return jsonize({"success": False, "message": "Invalid JSON options"})
# Initialize sqlmap engine's options with user's provided options, if any
for option, value in request.json.items():
DataStore.tasks[taskid].set_option(option, value)
# Launch sqlmap engine in a separate process
DataStore.tasks[taskid].engine_start()
logger.debug("(%s) Started scan" % taskid)
return jsonize({"success": True, "engineid": DataStore.tasks[taskid].engine_get_id()})
下图是调用该接口的截图:
@get("/scan//stop")
该接口定义停止扫描特定任务,调用时请指定taskid,不然会出现问题。具体代码如下:
def scan_stop(taskid):
"""
Stop a scan
"""
if (taskid not in DataStore.tasks or DataStore.tasks[taskid].engine_process() is None or DataStore.tasks[taskid].engine_has_terminated()):
logger.warning("[%s] Invalid task ID provided to scan_stop()" % taskid)
return jsonize({"success": False, "message": "Invalid task ID"})
DataStore.tasks[taskid].engine_stop()
logger.debug("(%s) Stopped scan" % taskid)
return jsonize({"success": True})
下图是调用该接口的截图:
@get("/scan//kill")
该接口可杀死特定任务,需要指定taskid,不然会出现问题。具体代码如下:
def scan_kill(taskid):
"""
Kill a scan
"""
if (taskid not in DataStore.tasks or DataStore.tasks[taskid].engine_process() is None or DataStore.tasks[taskid].engine_has_terminated()):
logger.warning("[%s] Invalid task ID provided to scan_kill()" % taskid)
return jsonize({"success": False, "message": "Invalid task ID"})
DataStore.tasks[taskid].engine_kill()
logger.debug("(%s) Killed scan" % taskid)
return jsonize({"success": True})
@get("/scan//status")
该接口可查询扫描状态,调用时请指定taskid,不然会出现问题。具体代码如下:
def scan_status(taskid):
"""
Returns status of a scan
"""
if taskid not in DataStore.tasks:
logger.warning("[%s] Invalid task ID provided to scan_status()" % taskid)
return jsonize({"success": False, "message": "Invalid task ID"})
if DataStore.tasks[taskid].engine_process() is None:
status = "not running"
else:
status = "terminated" if DataStore.tasks[taskid].engine_has_terminated() is True else "running"
logger.debug("(%s) Retrieved scan status" % taskid)
return jsonize({
"success": True,
"status": status,
"returncode": DataStore.tasks[taskid].engine_get_returncode()
})
下图是调用该接口的截图:
@get("/scan//data")
该接口可获得到扫描结果,调用时请指定taskid,不然会出现问题。具体代码如下:
def scan_data(taskid):
"""
Retrieve the data of a scan
"""
json_data_message = list()
json_errors_message = list()
if taskid not in DataStore.tasks:
logger.warning("[%s] Invalid task ID provided to scan_data()" % taskid)
return jsonize({"success": False, "message": "Invalid task ID"})
# Read all data from the IPC database for the taskid
for status, content_type, value in DataStore.current_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 DataStore.current_db.execute("SELECT error FROM errors WHERE taskid = ? ORDER BY id ASC", (taskid,)):
json_errors_message.append(error)
logger.debug("(%s) Retrieved scan data and error messages" % taskid)
return jsonize({"success": True, "data": json_data_message, "error": json_errors_message})
下图是调用该接口的截图:存在SQL注入的返回结果,返回的内容包括payload、数据库类型等等。
@get("/scan//log") /@get("/scan//log//")
该接口可查询特定任务的扫描的日志,调用时请指定taskid,不然会出现问题。具体代码如下:
def scan_log(taskid):
"""
Retrieve the log messages
"""
json_log_messages = list()
if taskid not in DataStore.tasks:
logger.warning("[%s] Invalid task ID provided to scan_log()" % taskid)
return jsonize({"success": False, "message": "Invalid task ID"})
# Read all log messages from the IPC database
for time_, level, message in DataStore.current_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("(%s) Retrieved scan log messages" % taskid)
return jsonize({"success": True, "log": json_log_messages})
def scan_log_limited(taskid, start, end):
"""
Retrieve a subset of log messages
"""
json_log_messages = list()
if taskid not in DataStore.tasks:
logger.warning("[%s] Invalid task ID provided to scan_log_limited()" % taskid)
return jsonize({"success": False, "message": "Invalid task ID"})
if not start.isdigit() or not end.isdigit() or end < start:
logger.warning("[%s] Invalid start or end value provided to scan_log_limited()" % taskid)
return jsonize({"success": False, "message": "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 DataStore.current_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("(%s) Retrieved scan log messages subset" % taskid)
return jsonize({"success": True, "log": json_log_messages})
下图是调用该接口的截图:
@get("/download///")
下载服务端指定任务的文件。具体代码如下:
def download(taskid, target, filename):
"""
Download a certain file from the file system
"""
if taskid not in DataStore.tasks:
logger.warning("[%s] Invalid task ID provided to download()" % taskid)
return jsonize({"success": False, "message": "Invalid task ID"})
path = os.path.abspath(os.path.join(paths.SQLMAP_OUTPUT_PATH, target, filename))
# Prevent file path traversal
if not path.startswith(paths.SQLMAP_OUTPUT_PATH):
logger.warning("[%s] Forbidden path (%s)" % (taskid, target))
return jsonize({"success": False, "message": "Forbidden path"})
if os.path.isfile(path):
logger.debug("(%s) Retrieved content of file %s" % (taskid, target))
with open(path, 'rb') as inf:
file_content = inf.read()
return jsonize({"success": True, "file": base64encode(file_content)})
else:
logger.warning("[%s] File does not exist %s" % (taskid, target))
return jsonize({"success": False, "message": "File does not exist"})