|
|
#!/usr/bin/env python
|
|
|
|
|
|
"""
|
|
|
Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
|
|
|
See the file 'LICENSE' for copying permission
|
|
|
"""
|
|
|
|
|
|
import sys # 导入sys模块,用于处理与Python解释器相关的操作
|
|
|
|
|
|
sys.dont_write_bytecode = True # 设置不生成.pyc字节码文件,以减少磁盘空间占用和加载时间
|
|
|
|
|
|
__import__("lib.utils.versioncheck") # 动态导入lib.utils.versioncheck模块,通常用于检查版本兼容性
|
|
|
|
|
|
import logging # 导入logging模块,用于记录日志信息
|
|
|
import os # 导入os模块,用于与操作系统进行交互
|
|
|
import warnings # 导入warnings模块,用于处理警告信息
|
|
|
|
|
|
warnings.filterwarnings(action="ignore", category=UserWarning) # 忽略所有UserWarning类别的警告
|
|
|
warnings.filterwarnings(action="ignore", category=DeprecationWarning) # 忽略所有DeprecationWarning类别的警告
|
|
|
|
|
|
try:
|
|
|
from optparse import OptionGroup # 从optparse模块导入OptionGroup类,用于处理命令行选项组
|
|
|
from optparse import OptionParser as ArgumentParser # 从optparse模块导入OptionParser类,并将其重命名为ArgumentParser
|
|
|
|
|
|
ArgumentParser.add_argument = ArgumentParser.add_option # 将ArgumentParser的add_option方法重命名为add_argument,以兼容argparse的API
|
|
|
|
|
|
def _add_argument(self, *args, **kwargs): # 定义一个辅助函数_add_argument,用于将add_argument方法映射到add_option方法
|
|
|
return self.add_option(*args, **kwargs)
|
|
|
|
|
|
OptionGroup.add_argument = _add_argument # 将OptionGroup的add_argument方法映射到_add_argument函数
|
|
|
|
|
|
except ImportError: # 如果导入optparse模块失败(例如在Python 3中),则执行以下代码
|
|
|
from argparse import ArgumentParser # 从argparse模块导入ArgumentParser类,用于处理命令行参数
|
|
|
|
|
|
finally: # 无论try块中的代码是否成功执行,finally块中的代码都会执行
|
|
|
def get_actions(instance): # 定义一个函数get_actions,用于获取命令行解析器实例中的选项列表
|
|
|
for attr in ("option_list", "_group_actions", "_actions"): # 遍历可能的属性名称
|
|
|
if hasattr(instance, attr): # 如果实例具有该属性
|
|
|
return getattr(instance, attr) # 返回该属性的值
|
|
|
|
|
|
def get_groups(parser): # 定义一个函数get_groups,用于获取命令行解析器中的选项组
|
|
|
return getattr(parser, "option_groups", None) or getattr(parser, "_action_groups") # 返回解析器中的选项组,如果不存在则返回None
|
|
|
|
|
|
def get_all_options(parser): # 定义一个函数get_all_options,用于获取命令行解析器中的所有选项
|
|
|
retVal = set() # 创建一个空集合,用于存储所有选项
|
|
|
|
|
|
for option in get_actions(parser): # 遍历解析器中的选项
|
|
|
if hasattr(option, "option_strings"): # 如果选项具有option_strings属性
|
|
|
retVal.update(option.option_strings) # 将选项字符串添加到集合中
|
|
|
else: # 否则
|
|
|
retVal.update(option._long_opts) # 将长选项添加到集合中
|
|
|
retVal.update(option._short_opts) # 将短选项添加到集合中
|
|
|
|
|
|
for group in get_groups(parser): # 遍历解析器中的选项组
|
|
|
for option in get_actions(group): # 遍历选项组中的选项
|
|
|
if hasattr(option, "option_strings"): # 如果选项具有option_strings属性
|
|
|
retVal.update(option.option_strings) # 将选项字符串添加到集合中
|
|
|
else: # 否则
|
|
|
retVal.update(option._long_opts) # 将长选项添加到集合中
|
|
|
retVal.update(option._short_opts) # 将短选项添加到集合中
|
|
|
|
|
|
return retVal # 返回包含所有选项的集合
|
|
|
|
|
|
|
|
|
from lib.core.common import getUnicode # 从lib.core.common模块导入getUnicode函数,用于将字符串转换为Unicode格式
|
|
|
from lib.core.common import setPaths # 从lib.core.common模块导入setPaths函数,用于设置文件路径
|
|
|
from lib.core.data import logger # 从lib.core.data模块导入logger对象,用于记录日志信息
|
|
|
from lib.core.patch import dirtyPatches # 从lib.core.patch模块导入dirtyPatches函数,用于应用临时补丁
|
|
|
from lib.core.patch import resolveCrossReferences # 从lib.core.patch模块导入resolveCrossReferences函数,用于解决交叉引用问题
|
|
|
from lib.core.settings import RESTAPI_DEFAULT_ADAPTER # 从lib.core.settings模块导入RESTAPI_DEFAULT_ADAPTER常量,表示默认的服务器适配器
|
|
|
from lib.core.settings import RESTAPI_DEFAULT_ADDRESS # 从lib.core.settings模块导入RESTAPI_DEFAULT_ADDRESS常量,表示默认的服务器地址
|
|
|
from lib.core.settings import RESTAPI_DEFAULT_PORT # 从lib.core.settings模块导入RESTAPI_DEFAULT_PORT常量,表示默认的服务器端口
|
|
|
from lib.core.settings import UNICODE_ENCODING # 从lib.core.settings模块导入UNICODE_ENCODING常量,表示默认的Unicode编码
|
|
|
from lib.utils.api import client # 从lib.utils.api模块导入client函数,用于启动REST-JSON API客户端
|
|
|
from lib.utils.api import server # 从lib.utils.api模块导入server函数,用于启动REST-JSON API服务器
|
|
|
|
|
|
try:
|
|
|
from sqlmap import modulePath # 从sqlmap模块导入modulePath函数,用于获取模块路径
|
|
|
except ImportError: # 如果导入失败(例如sqlmap模块不存在),则执行以下代码
|
|
|
def modulePath(): # 定义一个函数modulePath,用于获取当前模块的路径
|
|
|
return getUnicode(os.path.dirname(os.path.realpath(__file__)), encoding=sys.getfilesystemencoding() or UNICODE_ENCODING) # 返回当前文件的目录路径,并将其转换为Unicode格式
|
|
|
|
|
|
def main(): # 定义main函数,作为REST-JSON API的入口函数
|
|
|
"""
|
|
|
REST-JSON API main function
|
|
|
"""
|
|
|
|
|
|
dirtyPatches() # 应用临时补丁
|
|
|
resolveCrossReferences() # 解决交叉引用问题
|
|
|
|
|
|
# Set default logging level to debug
|
|
|
logger.setLevel(logging.DEBUG) # 设置日志记录级别为DEBUG,以便记录详细信息
|
|
|
|
|
|
# Initialize paths
|
|
|
setPaths(modulePath()) # 初始化文件路径,使用modulePath函数获取当前模块路径
|
|
|
|
|
|
# Parse command line options
|
|
|
apiparser = ArgumentParser() # 创建一个ArgumentParser对象,用于解析命令行参数
|
|
|
apiparser.add_argument("-s", "--server", help="Run as a REST-JSON API server", action="store_true") # 添加一个命令行选项,用于启动服务器
|
|
|
apiparser.add_argument("-c", "--client", help="Run as a REST-JSON API client", action="store_true") # 添加一个命令行选项,用于启动客户端
|
|
|
apiparser.add_argument("-H", "--host", help="Host of the REST-JSON API server (default \"%s\")" % RESTAPI_DEFAULT_ADDRESS, default=RESTAPI_DEFAULT_ADDRESS) # 添加一个命令行选项,用于指定服务器主机地址,默认值为RESTAPI_DEFAULT_ADDRESS
|
|
|
apiparser.add_argument("-p", "--port", help="Port of the REST-JSON API server (default %d)" % RESTAPI_DEFAULT_PORT, default=RESTAPI_DEFAULT_PORT, type=int) # 添加一个命令行选项,用于指定服务器端口,默认值为RESTAPI_DEFAULT_PORT
|
|
|
apiparser.add_argument("--adapter", help="Server (bottle) adapter to use (default \"%s\")" % RESTAPI_DEFAULT_ADAPTER, default=RESTAPI_DEFAULT_ADAPTER) # 添加一个命令行选项,用于指定服务器适配器,默认值为RESTAPI_DEFAULT_ADAPTER
|
|
|
apiparser.add_argument("--database", help="Set IPC database filepath (optional)") # 添加一个命令行选项,用于指定IPC数据库文件路径(可选)
|
|
|
apiparser.add_argument("--username", help="Basic authentication username (optional)") # 添加一个命令行选项,用于指定基本认证的用户名(可选)
|
|
|
apiparser.add_argument("--password", help="Basic authentication password (optional)") # 添加一个命令行选项,用于指定基本认证的密码(可选)
|
|
|
(args, _) = apiparser.parse_known_args() if hasattr(apiparser, "parse_known_args") else apiparser.parse_args() # 解析命令行参数,如果支持parse_known_args方法则使用它,否则使用parse_args方法
|
|
|
|
|
|
# Start the client or the server
|
|
|
if args.server: # 如果命令行参数中指定了启动服务器
|
|
|
server(args.host, args.port, adapter=args.adapter, username=args.username, password=args.password, database=args.database) # 调用server函数启动服务器
|
|
|
elif args.client: # 如果命令行参数中指定了启动客户端
|
|
|
client(args.host, args.port, username=args.username, password=args.password) # 调用client函数启动客户端
|
|
|
else: # 如果未指定启动服务器或客户端
|
|
|
apiparser.print_help() # 打印命令行帮助信息
|
|
|
|
|
|
if __name__ == "__main__": # 如果当前脚本作为主程序运行
|
|
|
main() # 调用main函数
|