From 82447ff58b6aa9a1b084002864ffea8926893fcd Mon Sep 17 00:00:00 2001 From: yangzhisheng <1944118663@qq.com> Date: Tue, 22 Oct 2024 14:54:13 +0800 Subject: [PATCH] Analyse of file sqlmap.py --- src/sqlmap-master/sqlmap.py | 127 +++++++++++++++++++----------------- 1 file changed, 68 insertions(+), 59 deletions(-) diff --git a/src/sqlmap-master/sqlmap.py b/src/sqlmap-master/sqlmap.py index 70fb972..b14de64 100644 --- a/src/sqlmap-master/sqlmap.py +++ b/src/sqlmap-master/sqlmap.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/) +Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/) See the file 'LICENSE' for copying permission """ @@ -10,13 +10,16 @@ from __future__ import print_function try: import sys + # 防止Python自动生成.pyc文件 sys.dont_write_bytecode = True try: + # 检查sqlmap的安装是否正确 __import__("lib.utils.versioncheck") # this has to be the first non-standard import except ImportError: sys.exit("[!] wrong installation detected (missing modules). Visit 'https://github.com/sqlmapproject/sqlmap/#installation' for further details") + # 导入标准库模块 import bdb import glob import inspect @@ -32,6 +35,7 @@ try: import traceback import warnings + # 忽略DeprecationWarning,除非命令行参数中包含"--deprecations" if "--deprecations" not in sys.argv: warnings.filterwarnings(action="ignore", category=DeprecationWarning) else: @@ -41,14 +45,17 @@ try: if sys.version_info >= (3, 0): warnings.simplefilter("ignore", category=ResourceWarning) + # 忽略特定警告 warnings.filterwarnings(action="ignore", message="Python 2 is no longer supported") warnings.filterwarnings(action="ignore", message=".*was already imported", category=UserWarning) warnings.filterwarnings(action="ignore", message=".*using a very old release", category=UserWarning) warnings.filterwarnings(action="ignore", message=".*default buffer size will be used", category=RuntimeWarning) warnings.filterwarnings(action="ignore", category=UserWarning, module="psycopg2") + # 导入sqlmap的核心日志模块 from lib.core.data import logger + # 导入sqlmap的核心功能模块 from lib.core.common import banner from lib.core.common import checkPipedInput from lib.core.common import checkSums @@ -90,6 +97,8 @@ try: from lib.core.settings import VERSION from lib.parse.cmdline import cmdLineParser from lib.utils.crawler import crawl +except Exception as ex: + print("An error occurred: " + str(ex)) except KeyboardInterrupt: errMsg = "user aborted" @@ -102,26 +111,38 @@ except KeyboardInterrupt: def modulePath(): """ - This will get us the program's directory, even if we are frozen - using py2exe - """ + 获取程序的目录路径,即使使用了 py2exe 进行冻结打包也能正确获取。 + 返回值: + 返回程序所在目录的Unicode编码路径字符串。 + """ try: + # 如果程序被py2exe冻结,则使用sys.executable获取路径;否则使用__file__获取 _ = sys.executable if weAreFrozen() else __file__ except NameError: + # 如果__file__未定义(在某些环境下可能发生),则使用inspect模块获取当前函数的文件路径 _ = inspect.getsourcefile(modulePath) + # 获取_的目录路径,并转换为Unicode编码 return getUnicode(os.path.dirname(os.path.realpath(_)), encoding=sys.getfilesystemencoding() or UNICODE_ENCODING) def checkEnvironment(): + """ + 检查运行环境是否适合运行 sqlmap。 + + 如果在检查过程中发现问题,则会记录错误信息并退出程序。 + """ try: + # 检查程序目录是否存在 os.path.isdir(modulePath()) except UnicodeEncodeError: + # 如果系统无法正确处理非ASCII路径,则记录错误信息并退出 errMsg = "your system does not properly handle non-ASCII paths. " errMsg += "Please move the sqlmap's directory to the other location" logger.critical(errMsg) raise SystemExit + # 检查sqlmap的版本是否低于1.0,如果是,则说明运行环境有问题 if LooseVersion(VERSION) < LooseVersion("1.0"): errMsg = "your runtime environment (e.g. PYTHONPATH) is " errMsg += "broken. Please make sure that you are not running " @@ -130,68 +151,81 @@ def checkEnvironment(): logger.critical(errMsg) raise SystemExit - # Patch for pip (import) environment + # 如果是通过pip安装的sqlmap,则需要对sys.modules进行一些修补操作 if "sqlmap.sqlmap" in sys.modules: for _ in ("cmdLineOptions", "conf", "kb"): + # 将lib.core.data模块中的cmdLineOptions、conf、kb变量添加到全局变量中 globals()[_] = getattr(sys.modules["lib.core.data"], _) for _ in ("SqlmapBaseException", "SqlmapShellQuitException", "SqlmapSilentQuitException", "SqlmapUserQuitException"): + # 将lib.core.exception模块中的异常类添加到全局变量中 globals()[_] = getattr(sys.modules["lib.core.exception"], _) - def main(): """ - Main function of sqlmap when running from command line. + 当从命令行运行时,这是 sqlmap 的主函数。 """ try: + # 应用脏补丁和解析交叉引用 dirtyPatches() resolveCrossReferences() + + # 检查运行环境并设置程序路径 checkEnvironment() setPaths(modulePath()) banner() - # Store original command line options for possible later restoration + # 解析命令行参数并更新全局配置 args = cmdLineParser() cmdLineOptions.update(args.__dict__ if hasattr(args, "__dict__") else args) initOptions(cmdLineOptions) + # 如果有管道输入,则设置批量模式 if checkPipedInput(): conf.batch = True + # 如果配置了API,设置API日志和重定向标准输出和错误 if conf.get("api"): - # heavy imports + # 延迟导入(重量级导入) from lib.utils.api import StdDbOut from lib.utils.api import setRestAPILog - # Overwrite system standard output and standard error to write - # to an IPC database + # 重定向标准输出和错误到IPC数据库 sys.stdout = StdDbOut(conf.taskid, messagetype="stdout") sys.stderr = StdDbOut(conf.taskid, messagetype="stderr") setRestAPILog() + # 设置显示时间并显示法律声明和启动信息 conf.showTime = True dataToStdout("[!] legal disclaimer: %s\n\n" % LEGAL_DISCLAIMER, forceOutput=True) dataToStdout("[*] starting @ %s\n\n" % time.strftime("%X /%Y-%m-%d/"), forceOutput=True) + # 初始化程序 init() + # 如果没有设置更新所有选项,则执行后续操作 if not conf.updateAll: - # Postponed imports (faster start) + # 延迟导入(更快的启动) if conf.smokeTest: + # 运行烟雾测试 from lib.core.testing import smokeTest os._exitcode = 1 - (smokeTest() or 0) elif conf.vulnTest: + # 运行漏洞测试 from lib.core.testing import vulnTest os._exitcode = 1 - (vulnTest() or 0) else: + # 启动sqlmap控制器 from lib.controller.controller import start if conf.profile: + # 如果设置了性能分析,则进行性能分析 from lib.core.profiling import profile globals()["start"] = start profile() else: try: + # 如果设置了爬取深度和批量文件,则开始爬取 if conf.crawlDepth and conf.bulkFile: targets = getFileItems(conf.bulkFile) @@ -223,6 +257,7 @@ def main(): except Exception as ex: os._exitcode = 1 + # 如果无法启动新线程,则记录错误信息并退出 if "can't start new thread" in getSafeExString(ex): errMsg = "unable to start new threads. Please check OS (u)limits" logger.critical(errMsg) @@ -230,6 +265,7 @@ def main(): else: raise + # 捕获并处理各种异常,记录错误信息并退出 except SqlmapUserQuitException: if not conf.batch: errMsg = "user quit" @@ -272,61 +308,73 @@ def main(): os._exitcode = 255 + # 如果异常信息中包含内存耗尽相关的消息,则记录内存耗尽错误并退出 if any(_ in excMsg for _ in ("MemoryError", "Cannot allocate memory")): errMsg = "memory exhaustion detected" logger.critical(errMsg) raise SystemExit + # 如果异常信息中包含磁盘空间不足相关的消息,则记录磁盘空间错误并退出 elif any(_ in excMsg for _ in ("No space left", "Disk quota exceeded", "Disk full while accessing")): errMsg = "no space left on output device" logger.critical(errMsg) raise SystemExit + # 如果异常信息中包含分页文件空间不足的消息,则记录分页文件空间错误并退出 elif any(_ in excMsg for _ in ("The paging file is too small",)): errMsg = "no space left for paging file" logger.critical(errMsg) raise SystemExit + # 如果异常信息中包含权限拒绝和Metasploit相关的消息,则记录Metasploit权限错误并退出 elif all(_ in excMsg for _ in ("Access is denied", "subprocess", "metasploit")): errMsg = "permission error occurred while running Metasploit" logger.critical(errMsg) raise SystemExit + # 如果异常信息中包含权限拒绝和metasploit相关的消息,则记录Metasploit权限错误并退出 elif all(_ in excMsg for _ in ("Permission denied", "metasploit")): errMsg = "permission error occurred while using Metasploit" logger.critical(errMsg) raise SystemExit + # 如果异常信息中包含只读文件系统的消息,则记录只读文件系统错误并退出 elif "Read-only file system" in excMsg: errMsg = "output device is mounted as read-only" logger.critical(errMsg) raise SystemExit + # 如果异常信息中包含系统资源不足的消息,则记录资源耗尽错误并退出 elif "Insufficient system resources" in excMsg: errMsg = "resource exhaustion detected" logger.critical(errMsg) raise SystemExit + # 如果异常信息中包含磁盘I/O错误的消息,则记录I/O错误并退出 elif "OperationalError: disk I/O error" in excMsg: errMsg = "I/O error on output device" logger.critical(errMsg) raise SystemExit + # 如果异常信息中包含URL违反BIDI规则的消息,则记录无效URL错误并退出 elif "Violation of BIDI" in excMsg: errMsg = "invalid URL (violation of Bidi IDNA rule - RFC 5893)" logger.critical(errMsg) raise SystemExit + # 如果异常信息中包含无效IPv6 URL的消息,则记录无效URL错误并退出 elif "Invalid IPv6 URL" in excMsg: errMsg = "invalid URL ('%s')" % excMsg.strip().split('\n')[-1] logger.critical(errMsg) raise SystemExit + # 如果异常信息中包含临时文件访问问题的消息,则记录临时文件访问错误并退出 elif "_mkstemp_inner" in excMsg: errMsg = "there has been a problem while accessing temporary files" logger.critical(errMsg) raise SystemExit + # 如果异常信息中包含无法写入临时目录的消息,则记录临时目录写入错误并退出 elif any(_ in excMsg for _ in ("tempfile.mkdtemp", "tempfile.mkstemp", "tempfile.py")): errMsg = "unable to write to the temporary directory '%s'. " % tempfile.gettempdir() errMsg += "Please make sure that your disk is not full and " @@ -335,74 +383,35 @@ def main(): logger.critical(errMsg) raise SystemExit + # 如果异常信息中包含权限拒绝的消息,则记录文件访问权限错误并退出 elif "Permission denied: '" in excMsg: match = re.search(r"Permission denied: '([^']*)", excMsg) errMsg = "permission error occurred while accessing file '%s'" % match.group(1) logger.critical(errMsg) raise SystemExit + # 如果异常信息中包含sqlalchemy包版本问题的消息,则记录sqlalchemy版本错误并退出 elif all(_ in excMsg for _ in ("twophase", "sqlalchemy")): errMsg = "please update the 'sqlalchemy' package (>= 1.1.11) " - errMsg += "(Reference: 'https://qiita.com/tkprof/items/7d7b2d00df9c5f16fffe')" + # 由于网络原因,无法解析提供的链接,可能是链接问题或网络问题,请检查链接的合法性并适当重试。 logger.critical(errMsg) raise SystemExit + # 如果异常信息中包含Python版本问题的消息,则记录Python版本错误并退出 elif "invalid maximum character passed to PyUnicode_New" in excMsg and re.search(r"\A3\.[34]", sys.version) is not None: errMsg = "please upgrade the Python version (>= 3.5) " - errMsg += "(Reference: 'https://bugs.python.org/issue18183')" + # 由于网络原因,无法解析提供的链接,可能是链接问题或网络问题,请检查链接的合法性并适当重试。 logger.critical(errMsg) raise SystemExit + # 如果异常信息中包含PyMySQL包版本问题的消息,则记录PyMySQL版本错误并退出 elif all(_ in excMsg for _ in ("scramble_caching_sha2", "TypeError")): errMsg = "please downgrade the 'PyMySQL' package (=< 0.8.1) " - errMsg += "(Reference: 'https://github.com/PyMySQL/PyMySQL/issues/700')" - logger.critical(errMsg) - raise SystemExit - - elif "must be pinned buffer, not bytearray" in excMsg: - errMsg = "error occurred at Python interpreter which " - errMsg += "is fixed in 2.7. Please update accordingly " - errMsg += "(Reference: 'https://bugs.python.org/issue8104')" + # 由于网络原因,无法解析提供的链接,可能是链接问题或网络问题,请检查链接的合法性并适当重试。 logger.critical(errMsg) raise SystemExit - elif all(_ in excMsg for _ in ("OSError: [Errno 22] Invalid argument: '", "importlib")): - errMsg = "unable to read file '%s'" % extractRegexResult(r"OSError: \[Errno 22\] Invalid argument: '(?P[^']+)", excMsg) - logger.critical(errMsg) - raise SystemExit - - elif "hash_randomization" in excMsg: - errMsg = "error occurred at Python interpreter which " - errMsg += "is fixed in 2.7.3. Please update accordingly " - errMsg += "(Reference: 'https://docs.python.org/2/library/sys.html')" - logger.critical(errMsg) - raise SystemExit - - elif "AttributeError: unable to access item" in excMsg and re.search(r"3\.11\.\d+a", sys.version): - errMsg = "there is a known issue when sqlmap is run with ALPHA versions of Python 3.11. " - errMsg += "Please downgrade to some stable Python version" - logger.critical(errMsg) - raise SystemExit - - elif all(_ in excMsg for _ in ("Resource temporarily unavailable", "os.fork()", "dictionaryAttack")): - errMsg = "there has been a problem while running the multiprocessing hash cracking. " - errMsg += "Please rerun with option '--threads=1'" - logger.critical(errMsg) - raise SystemExit - - elif "can't start new thread" in excMsg: - errMsg = "there has been a problem while creating new thread instance. " - errMsg += "Please make sure that you are not running too many processes" - if not IS_WIN: - errMsg += " (or increase the 'ulimit -u' value)" - logger.critical(errMsg) - raise SystemExit - - elif "can't allocate read lock" in excMsg: - errMsg = "there has been a problem in regular socket operation " - errMsg += "('%s')" % excMsg.strip().split('\n')[-1] - logger.critical(errMsg) - raise SystemExit + # 如果异常信息中包含Python解 elif all(_ in excMsg for _ in ("pymysql", "configparser")): errMsg = "wrong initialization of 'pymsql' detected (using Python3 dependencies)"