源码阅读

yangzhisheng_branch
XU 2 months ago
parent 60938dff4c
commit 0dc81c2219

Binary file not shown.

@ -168,481 +168,453 @@ def main():
try: try:
# 应用脏补丁和解析交叉引用 # 应用脏补丁和解析交叉引用
dirtyPatches() dirtyPatches() # 应用一些临时的修复或补丁
resolveCrossReferences() resolveCrossReferences() # 解析并处理代码中的交叉引用
# 检查运行环境并设置程序路径 # 检查运行环境并设置程序路径
checkEnvironment() checkEnvironment() # 检查当前运行环境是否满足要求
setPaths(modulePath()) setPaths(modulePath()) # 设置程序的路径
banner() banner() # 显示程序的横幅信息
# 解析命令行参数并更新全局配置 # 解析命令行参数并更新全局配置
args = cmdLineParser() args = cmdLineParser() # 解析命令行参数
cmdLineOptions.update(args.__dict__ if hasattr(args, "__dict__") else args) cmdLineOptions.update(args.__dict__ if hasattr(args, "__dict__") else args) # 更新全局命令行选项
initOptions(cmdLineOptions) initOptions(cmdLineOptions) # 初始化全局配置选项
# 如果有管道输入,则设置批量模式 # 如果有管道输入,则设置批量模式
if checkPipedInput(): if checkPipedInput(): # 检查是否有管道输入
conf.batch = True conf.batch = True # 如果有管道输入则设置批量模式为True
# 如果配置了API设置API日志和重定向标准输出和错误 # 如果配置了API设置API日志和重定向标准输出和错误
if conf.get("api"): if conf.get("api"): # 检查是否配置了API
# 延迟导入(重量级导入) # 延迟导入(重量级导入)
from lib.utils.api import StdDbOut from lib.utils.api import StdDbOut # 导入StdDbOut类用于重定向标准输出和错误
from lib.utils.api import setRestAPILog from lib.utils.api import setRestAPILog # 导入setRestAPILog函数用于设置API日志
# 重定向标准输出和错误到IPC数据库 # 重定向标准输出和错误到IPC数据库
sys.stdout = StdDbOut(conf.taskid, messagetype="stdout") sys.stdout = StdDbOut(conf.taskid, messagetype="stdout") # 重定向标准输出到IPC数据库
sys.stderr = StdDbOut(conf.taskid, messagetype="stderr") sys.stderr = StdDbOut(conf.taskid, messagetype="stderr") # 重定向标准错误到IPC数据库
setRestAPILog() setRestAPILog() # 设置API日志
# 设置显示时间并显示法律声明和启动信息 # 设置显示时间并显示法律声明和启动信息
conf.showTime = True conf.showTime = True # 设置显示时间
dataToStdout("[!] legal disclaimer: %s\n\n" % LEGAL_DISCLAIMER, forceOutput=True) dataToStdout("[!] legal disclaimer: %s\n\n" % LEGAL_DISCLAIMER, forceOutput=True) # 显示法律声明
dataToStdout("[*] starting @ %s\n\n" % time.strftime("%X /%Y-%m-%d/"), forceOutput=True) dataToStdout("[*] starting @ %s\n\n" % time.strftime("%X /%Y-%m-%d/"), forceOutput=True) # 显示启动信息
# 初始化程序 # 初始化程序
init() init() # 调用初始化函数,完成程序的初始化工作
# 如果没有设置更新所有选项,则执行后续操作 # 如果没有设置更新所有选项,则执行后续操作
if not conf.updateAll: if not conf.updateAll: # 检查是否设置了更新所有选项
# 延迟导入(更快的启动) # 延迟导入(更快的启动)
if conf.smokeTest: if conf.smokeTest: # 检查是否设置了烟雾测试
# 运行烟雾测试 # 运行烟雾测试
from lib.core.testing import smokeTest from lib.core.testing import smokeTest # 导入烟雾测试函数
os._exitcode = 1 - (smokeTest() or 0) os._exitcode = 1 - (smokeTest() or 0) # 运行烟雾测试并设置退出码
elif conf.vulnTest: elif conf.vulnTest: # 检查是否设置了漏洞测试
# 运行漏洞测试 # 运行漏洞测试
from lib.core.testing import vulnTest from lib.core.testing import vulnTest # 导入漏洞测试函数
os._exitcode = 1 - (vulnTest() or 0) os._exitcode = 1 - (vulnTest() or 0) # 运行漏洞测试并设置退出码
else: else:
# 启动sqlmap控制器 # 启动sqlmap控制器
from lib.controller.controller import start from lib.controller.controller import start # 导入启动控制器函数
if conf.profile: if conf.profile: # 检查是否设置了性能分析
# 如果设置了性能分析,则进行性能分析 # 如果设置了性能分析,则进行性能分析
from lib.core.profiling import profile from lib.core.profiling import profile # 导入性能分析函数
globals()["start"] = start globals()["start"] = start # 将start函数添加到全局命名空间
profile() profile() # 运行性能分析
else: else:
try: try:
# 如果设置了爬取深度和批量文件,则开始爬取 # 如果设置了爬取深度和批量文件,则开始爬取
if conf.crawlDepth and conf.bulkFile: if conf.crawlDepth and conf.bulkFile: # 检查是否设置了爬取深度和批量文件
targets = getFileItems(conf.bulkFile) targets = getFileItems(conf.bulkFile) # 从批量文件中获取目标列表
for i in xrange(len(targets)): for i in xrange(len(targets)): # 遍历目标列表
target = None target = None # 初始化目标变量
try: try:
kb.targets = OrderedSet() kb.targets = OrderedSet() # 初始化目标集合
target = targets[i] target = targets[i] # 获取当前目标
if not re.search(r"(?i)\Ahttp[s]*://", target): if not re.search(r"(?i)\Ahttp[s]*://", target): # 检查目标是否包含协议
target = "http://%s" % target target = "http://%s" % target # 如果没有协议则添加默认的HTTP协议
infoMsg = "starting crawler for target URL '%s' (%d/%d)" % (target, i + 1, len(targets)) infoMsg = "starting crawler for target URL '%s' (%d/%d)" % (target, i + 1, len(targets)) # 生成日志信息
logger.info(infoMsg) logger.info(infoMsg) # 记录日志信息
crawl(target) crawl(target) # 开始爬取目标
except Exception as ex: except Exception as ex: # 捕获异常
if target and not isinstance(ex, SqlmapUserQuitException): if target and not isinstance(ex, SqlmapUserQuitException): # 检查异常类型
errMsg = "problem occurred while crawling '%s' ('%s')" % (target, getSafeExString(ex)) errMsg = "problem occurred while crawling '%s' ('%s')" % (target, getSafeExString(ex)) # 生成错误信息
logger.error(errMsg) logger.error(errMsg) # 记录错误信息
else: else:
raise raise # 重新抛出异常
else: else:
if kb.targets: if kb.targets: # 检查目标集合是否非空
start() start() # 启动控制器
else: else:
start() start() # 如果没有设置爬取深度和批量文件,则直接启动控制器
except Exception as ex: except Exception as ex: # 捕获异常
os._exitcode = 1 os._exitcode = 1 # 设置退出码为1
# 如果无法启动新线程,则记录错误信息并退出 # 如果无法启动新线程,则记录错误信息并退出
if "can't start new thread" in getSafeExString(ex): if "can't start new thread" in getSafeExString(ex): # 检查异常信息是否包含无法启动新线程
errMsg = "unable to start new threads. Please check OS (u)limits" errMsg = "unable to start new threads. Please check OS (u)limits" # 生成错误信息
logger.critical(errMsg) logger.critical(errMsg) # 记录严重错误信息
raise SystemExit raise SystemExit # 退出程序
else: else:
raise raise # 重新抛出异常
# 捕获并处理各种异常,记录错误信息并退出 # 捕获并处理各种异常,记录错误信息并退出
except SqlmapUserQuitException: except SqlmapUserQuitException: # 捕获用户主动退出的异常
if not conf.batch: if not conf.batch: # 检查是否处于批量模式
errMsg = "user quit" errMsg = "user quit" # 生成错误信息
logger.error(errMsg) logger.error(errMsg) # 记录错误信息
except (SqlmapSilentQuitException, bdb.BdbQuit): except (SqlmapSilentQuitException, bdb.BdbQuit): # 捕获静默退出或调试器退出的异常
pass pass # 不处理,直接跳过
except SqlmapShellQuitException: except SqlmapShellQuitException: # 捕获SQLMap Shell退出的异常
cmdLineOptions.sqlmapShell = False cmdLineOptions.sqlmapShell = False # 设置SQLMap Shell选项为False
except SqlmapBaseException as ex: except SqlmapBaseException as ex: # 捕获SQLMap基础异常
errMsg = getSafeExString(ex) errMsg = getSafeExString(ex) # 获取安全的异常信息
logger.critical(errMsg) logger.critical(errMsg) # 记录严重错误信息
os._exitcode = 1 os._exitcode = 1 # 设置退出码为1
raise SystemExit raise SystemExit # 退出程序
except KeyboardInterrupt: except KeyboardInterrupt: # 捕获键盘中断异常如Ctrl+C
try: try:
print() print() # 打印空行
except IOError: except IOError: # 捕获IO错误
pass pass # 不处理,直接跳过
except EOFError: except EOFError: # 捕获文件结束异常如Ctrl+D
print() print() # 打印空行
errMsg = "exit" errMsg = "exit" # 生成错误信息
logger.error(errMsg) logger.error(errMsg) # 记录错误信息
except SystemExit as ex: except SystemExit as ex: # 捕获系统退出异常
os._exitcode = ex.code or 0 os._exitcode = ex.code or 0 # 设置退出码为异常代码或0
except: except: # 捕获所有其他异常
print() print() # 打印空行
errMsg = unhandledExceptionMessage() errMsg = unhandledExceptionMessage() # 获取未处理异常的信息
excMsg = traceback.format_exc() excMsg = traceback.format_exc() # 获取异常的详细堆栈信息
valid = checkSums() valid = checkSums() # 检查校验和
os._exitcode = 255 os._exitcode = 255 # 设置退出码为255
# 如果异常信息中包含内存耗尽相关的消息,则记录内存耗尽错误并退出 # 如果异常信息中包含内存耗尽相关的消息,则记录内存耗尽错误并退出
if any(_ in excMsg for _ in ("MemoryError", "Cannot allocate memory")): if any(_ in excMsg for _ in ("MemoryError", "Cannot allocate memory")): # 检查异常信息是否包含内存耗尽
errMsg = "memory exhaustion detected" errMsg = "memory exhaustion detected" # 生成错误信息
logger.critical(errMsg) logger.critical(errMsg) # 记录严重错误信息
raise SystemExit raise SystemExit # 退出程序
# 如果异常信息中包含磁盘空间不足相关的消息,则记录磁盘空间错误并退出 # 如果异常信息中包含磁盘空间不足相关的消息,则记录磁盘空间错误并退出
elif any(_ in excMsg for _ in ("No space left", "Disk quota exceeded", "Disk full while accessing")): elif any(_ in excMsg for _ in ("No space left", "Disk quota exceeded", "Disk full while accessing")): # 检查异常信息是否包含磁盘空间不足
errMsg = "no space left on output device" errMsg = "no space left on output device" # 生成错误信息
logger.critical(errMsg) logger.critical(errMsg) # 记录严重错误信息
raise SystemExit raise SystemExit # 退出程序
# 如果异常信息中包含分页文件空间不足的消息,则记录分页文件空间错误并退出 # 如果异常信息中包含分页文件空间不足的消息,则记录分页文件空间错误并退出
elif any(_ in excMsg for _ in ("The paging file is too small",)): elif any(_ in excMsg for _ in ("The paging file is too small",)): # 检查异常信息是否包含分页文件空间不足
errMsg = "no space left for paging file" errMsg = "no space left for paging file" # 生成错误信息
logger.critical(errMsg) logger.critical(errMsg) # 记录严重错误信息
raise SystemExit raise SystemExit # 退出程序
# 如果异常信息中包含权限拒绝和Metasploit相关的消息则记录Metasploit权限错误并退出 # 如果异常信息中包含权限拒绝和Metasploit相关的消息则记录Metasploit权限错误并退出
elif all(_ in excMsg for _ in ("Access is denied", "subprocess", "metasploit")): elif all(_ in excMsg for _ in ("Access is denied", "subprocess", "metasploit")): # 检查异常信息是否包含Metasploit权限错误
errMsg = "permission error occurred while running Metasploit" errMsg = "permission error occurred while running Metasploit" # 生成错误信息
logger.critical(errMsg) logger.critical(errMsg) # 记录严重错误信息
raise SystemExit raise SystemExit # 退出程序
# 如果异常信息中包含权限拒绝和metasploit相关的消息则记录Metasploit权限错误并退出 # 如果异常信息中包含权限拒绝和metasploit相关的消息则记录Metasploit权限错误并退出
elif all(_ in excMsg for _ in ("Permission denied", "metasploit")): elif all(_ in excMsg for _ in ("Permission denied", "metasploit")): # 检查异常信息是否包含Metasploit权限错误
errMsg = "permission error occurred while using Metasploit" errMsg = "permission error occurred while using Metasploit" # 生成错误信息
logger.critical(errMsg) logger.critical(errMsg) # 记录严重错误信息
raise SystemExit raise SystemExit # 退出程序
# 如果异常信息中包含只读文件系统的消息,则记录只读文件系统错误并退出 # 如果异常信息中包含只读文件系统的消息,则记录只读文件系统错误并退出
elif "Read-only file system" in excMsg: elif "Read-only file system" in excMsg: # 检查异常信息是否包含只读文件系统
errMsg = "output device is mounted as read-only" errMsg = "output device is mounted as read-only" # 生成错误信息
logger.critical(errMsg) logger.critical(errMsg) # 记录严重错误信息
raise SystemExit raise SystemExit # 退出程序
# 如果异常信息中包含系统资源不足的消息,则记录资源耗尽错误并退出 # 如果异常信息中包含系统资源不足的消息,则记录资源耗尽错误并退出
elif "Insufficient system resources" in excMsg: elif "Insufficient system resources" in excMsg: # 检查异常信息是否包含系统资源不足
errMsg = "resource exhaustion detected" errMsg = "resource exhaustion detected" # 生成错误信息
logger.critical(errMsg) logger.critical(errMsg) # 记录严重错误信息
raise SystemExit raise SystemExit # 退出程序
# 如果异常信息中包含磁盘I/O错误的消息则记录I/O错误并退出 # 如果异常信息中包含磁盘I/O错误的消息则记录I/O错误并退出
elif "OperationalError: disk I/O error" in excMsg: elif "OperationalError: disk I/O error" in excMsg: # 检查异常信息是否包含磁盘I/O错误
errMsg = "I/O error on output device" errMsg = "I/O error on output device" # 生成错误信息
logger.critical(errMsg) logger.critical(errMsg) # 记录严重错误信息
raise SystemExit raise SystemExit # 退出程序
# 如果异常信息中包含URL违反BIDI规则的消息则记录无效URL错误并退出 # 如果异常信息中包含URL违反BIDI规则的消息则记录无效URL错误并退出
elif "Violation of BIDI" in excMsg: elif "Violation of BIDI" in excMsg: # 检查异常信息是否包含URL违反BIDI规则
errMsg = "invalid URL (violation of Bidi IDNA rule - RFC 5893)" errMsg = "invalid URL (violation of Bidi IDNA rule - RFC 5893)" # 生成错误信息
logger.critical(errMsg) logger.critical(errMsg) # 记录严重错误信息
raise SystemExit raise SystemExit # 退出程序
# 如果异常信息中包含无效IPv6 URL的消息则记录无效URL错误并退出 # 如果异常信息中包含无效IPv6 URL的消息则记录无效URL错误并退出
elif "Invalid IPv6 URL" in excMsg: elif "Invalid IPv6 URL" in excMsg: # 检查异常信息是否包含无效IPv6 URL
errMsg = "invalid URL ('%s')" % excMsg.strip().split('\n')[-1] errMsg = "invalid URL ('%s')" % excMsg.strip().split('\n')[-1] # 生成错误信息
logger.critical(errMsg) logger.critical(errMsg) # 记录严重错误信息
raise SystemExit raise SystemExit # 退出程序
# 如果异常信息中包含临时文件访问问题的消息,则记录临时文件访问错误并退出 # 如果异常信息中包含临时文件访问问题的消息,则记录临时文件访问错误并退出
elif "_mkstemp_inner" in excMsg: elif "_mkstemp_inner" in excMsg: # 检查异常信息是否包含临时文件访问问题
errMsg = "there has been a problem while accessing temporary files" errMsg = "there has been a problem while accessing temporary files" # 生成错误信息
logger.critical(errMsg) logger.critical(errMsg) # 记录严重错误信息
raise SystemExit raise SystemExit # 退出程序
# 如果异常信息中包含无法写入临时目录的消息,则记录临时目录写入错误并退出 # 如果异常信息中包含无法写入临时目录的消息,则记录临时目录写入错误并退出
elif any(_ in excMsg for _ in ("tempfile.mkdtemp", "tempfile.mkstemp", "tempfile.py")): elif any(_ in excMsg for _ in ("tempfile.mkdtemp", "tempfile.mkstemp", "tempfile.py")): # 检查异常信息是否包含临时目录写入问题
errMsg = "unable to write to the temporary directory '%s'. " % tempfile.gettempdir() errMsg = "unable to write to the temporary directory '%s'. " % tempfile.gettempdir() # 生成错误信息
errMsg += "Please make sure that your disk is not full and " errMsg += "Please make sure that your disk is not full and " # 添加提示信息
errMsg += "that you have sufficient write permissions to " errMsg += "that you have sufficient write permissions to " # 添加提示信息
errMsg += "create temporary files and/or directories" errMsg += "create temporary files and/or directories" # 添加提示信息
logger.critical(errMsg) logger.critical(errMsg) # 记录严重错误信息
raise SystemExit raise SystemExit # 退出程序
# 如果异常信息中包含权限拒绝的消息,则记录文件访问权限错误并退出 # 如果异常信息中包含权限拒绝的消息,则记录文件访问权限错误并退出
elif "Permission denied: '" in excMsg: elif "Permission denied: '" in excMsg: # 检查异常信息是否包含权限拒绝
match = re.search(r"Permission denied: '([^']*)", excMsg) match = re.search(r"Permission denied: '([^']*)", excMsg) # 提取被拒绝访问的文件路径
errMsg = "permission error occurred while accessing file '%s'" % match.group(1) errMsg = "permission error occurred while accessing file '%s'" % match.group(1) # 生成错误信息
logger.critical(errMsg) logger.critical(errMsg) # 记录严重错误信息
raise SystemExit raise SystemExit # 退出程序
# 如果异常信息中包含sqlalchemy包版本问题的消息则记录sqlalchemy版本错误并退出 # 如果异常信息中包含sqlalchemy包版本问题的消息则记录sqlalchemy版本错误并退出
elif all(_ in excMsg for _ in ("twophase", "sqlalchemy")): elif all(_ in excMsg for _ in ("twophase", "sqlalchemy")): # 检查异常信息是否包含sqlalchemy版本问题
errMsg = "please update the 'sqlalchemy' package (>= 1.1.11) " errMsg = "please update the 'sqlalchemy' package (>= 1.1.11) " # 生成错误信息
# 由于网络原因,无法解析提供的链接,可能是链接问题或网络问题,请检查链接的合法性并适当重试。 logger.critical(errMsg) # 记录严重错误信息
logger.critical(errMsg) raise SystemExit # 退出程序
raise SystemExit
# 如果异常信息中包含Python版本问题的消息则记录Python版本错误并退出 # 如果异常信息中包含Python版本问题的消息则记录Python版本错误并退出
elif "invalid maximum character passed to PyUnicode_New" in excMsg and re.search(r"\A3\.[34]", sys.version) is not None: elif "invalid maximum character passed to PyUnicode_New" in excMsg and re.search(r"\A3\.[34]", sys.version) is not None: # 检查异常信息是否包含Python版本问题
errMsg = "please upgrade the Python version (>= 3.5) " errMsg = "please upgrade the Python version (>= 3.5) " # 生成错误信息
# 由于网络原因,无法解析提供的链接,可能是链接问题或网络问题,请检查链接的合法性并适当重试。 logger.critical(errMsg) # 记录严重错误信息
logger.critical(errMsg) raise SystemExit # 退出程序
raise SystemExit
# 如果异常信息中包含PyMySQL包版本问题的消息则记录PyMySQL版本错误并退出 # 如果异常信息中包含PyMySQL包版本问题的消息则记录PyMySQL版本错误并退出
elif all(_ in excMsg for _ in ("scramble_caching_sha2", "TypeError")): elif all(_ in excMsg for _ in ("scramble_caching_sha2", "TypeError")): # 检查异常信息是否包含PyMySQL版本问题
errMsg = "please downgrade the 'PyMySQL' package (=< 0.8.1) " errMsg = "please downgrade the 'PyMySQL' package (=< 0.8.1) " # 生成错误信息
# 由于网络原因,无法解析提供的链接,可能是链接问题或网络问题,请检查链接的合法性并适当重试。 logger.critical(errMsg) # 记录严重错误信息
logger.critical(errMsg) raise SystemExit # 退出程序
raise SystemExit
# 如果异常信息中包含Python解 # 如果异常信息中包含Python解
# 假设excMsg是一个包含异常信息的字符串变量 # 假设excMsg是一个包含异常信息的字符串变量
# 检查excMsg是否包含"pymysql"和"configparser"这两个字符串 # 检查excMsg是否包含"pymysql"和"configparser"这两个字符串
elif all(_ in excMsg for _ in ("pymysql", "configparser")): elif all(_ in excMsg for _ in ("pymysql", "configparser")): # 检查异常信息是否包含pymysql和configparser
# 如果都包含,则设置错误信息为检测到'pymsql'的错误初始化使用了Python3的依赖 errMsg = "wrong initialization of 'pymsql' detected (using Python3 dependencies)" # 生成错误信息
errMsg = "wrong initialization of 'pymsql' detected (using Python3 dependencies)" logger.critical(errMsg) # 记录严重错误信息
# 使用logger记录这个严重错误 raise SystemExit # 退出程序
logger.critical(errMsg)
# 抛出SystemExit异常导致程序退出
raise SystemExit
# 检查excMsg是否包含"ntlm"、"socket.error, err"和"SyntaxError"这三个字符串 # 检查excMsg是否包含"ntlm"、"socket.error, err"和"SyntaxError"这三个字符串
elif all(_ in excMsg for _ in ("ntlm", "socket.error, err", "SyntaxError")): elif all(_ in excMsg for _ in ("ntlm", "socket.error, err", "SyntaxError")): # 检查异常信息是否包含ntlm、socket.error和SyntaxError
# 如果都包含,则设置错误信息为检测到'python-ntlm'的错误初始化使用了Python2的语法 errMsg = "wrong initialization of 'python-ntlm' detected (using Python2 syntax)" # 生成错误信息
errMsg = "wrong initialization of 'python-ntlm' detected (using Python2 syntax)" logger.critical(errMsg) # 记录严重错误信息
# 使用logger记录这个严重错误 raise SystemExit # 退出程序
logger.critical(errMsg)
# 抛出SystemExit异常导致程序退出
raise SystemExit
# 检查excMsg是否包含"drda"和"to_bytes"这两个字符串 # 检查excMsg是否包含"drda"和"to_bytes"这两个字符串
elif all(_ in excMsg for _ in ("drda", "to_bytes")): elif all(_ in excMsg for _ in ("drda", "to_bytes")): # 检查异常信息是否包含drda和to_bytes
# 如果都包含,则设置错误信息为检测到'drda'的错误初始化使用了Python3的语法 errMsg = "wrong initialization of 'drda' detected (using Python3 syntax)" # 生成错误信息
errMsg = "wrong initialization of 'drda' detected (using Python3 syntax)" logger.critical(errMsg) # 记录严重错误信息
# 使用logger记录这个严重错误 raise SystemExit # 退出程序
logger.critical(errMsg)
# 抛出SystemExit异常导致程序退出
raise SystemExit
# 检查excMsg是否包含特定的错误信息即'WebSocket'对象没有'status'属性 # 检查excMsg是否包含特定的错误信息即'WebSocket'对象没有'status'属性
elif "'WebSocket' object has no attribute 'status'" in excMsg: elif "'WebSocket' object has no attribute 'status'" in excMsg: # 检查异常信息是否包含WebSocket对象缺少status属性
# 如果包含则设置错误信息为检测到错误的websocket库 errMsg = "wrong websocket library detected" # 生成错误信息
errMsg = "wrong websocket library detected" errMsg += " (Reference: 'https://github.com/sqlmapproject/sqlmap/issues/4572#issuecomment-775041086')" # 添加参考链接
# 添加参考链接到错误信息中 logger.critical(errMsg) # 记录严重错误信息
errMsg += " (Reference: 'https://github.com/sqlmapproject/sqlmap/issues/4572#issuecomment-775041086')" raise SystemExit # 退出程序
# 使用logger记录这个严重错误
logger.critical(errMsg)
# 抛出SystemExit异常导致程序退出
raise SystemExit
# 检查excMsg是否包含特定的错误信息即初始化GUI界面时出现问题 # 检查excMsg是否包含特定的错误信息即初始化GUI界面时出现问题
elif all(_ in excMsg for _ in ("window = tkinter.Tk()",)): elif all(_ in excMsg for _ in ("window = tkinter.Tk()",)): # 检查异常信息是否包含GUI初始化问题
# 如果包含则设置错误信息为GUI界面初始化问题 errMsg = "there has been a problem in initialization of GUI interface " # 生成错误信息
errMsg = "there has been a problem in initialization of GUI interface " errMsg += "('%s')" % excMsg.strip().split('\n')[-1] # 添加具体错误信息
# 添加具体的错误信息到错误消息中 logger.critical(errMsg) # 记录严重错误信息
errMsg += "('%s')" % excMsg.strip().split('\n')[-1] raise SystemExit # 退出程序
# 使用logger记录这个严重错误
logger.critical(errMsg)
# 抛出SystemExit异常导致程序退出
raise SystemExit
# 检查excMsg是否包含特定的错误信息即使用了不同版本的sqlmap文件 # 检查excMsg是否包含特定的错误信息即使用了不同版本的sqlmap文件
elif any(_ in excMsg for _ in ("unable to access item 'liveTest'",)): elif any(_ in excMsg for _ in ("unable to access item 'liveTest'",)): # 检查异常信息是否包含不同版本sqlmap文件问题
# 如果包含则设置错误信息为检测到使用了不同版本的sqlmap文件 errMsg = "detected usage of files from different versions of sqlmap" # 生成错误信息
errMsg = "detected usage of files from different versions of sqlmap" logger.critical(errMsg) # 记录严重错误信息
# 使用logger记录这个严重错误 raise SystemExit # 退出程序
logger.critical(errMsg)
# 抛出SystemExit异常导致程序退出
raise SystemExit
# 检查errMsg是否包含特定的错误信息即版本号相关的错误 # 检查errMsg是否包含特定的错误信息即版本号相关的错误
elif any(_ in errMsg for _ in (": 9.9.9#",)): elif any(_ in errMsg for _ in (": 9.9.9#",)): # 检查错误信息是否包含特定版本号
# 如果包含,则设置错误信息为一个简单的文本 errMsg = "LOL xD" # 生成错误信息
errMsg = "LOL xD" logger.critical(errMsg) # 记录严重错误信息
# 使用logger记录这个严重错误 raise SystemExit # 退出程序
logger.critical(errMsg)
# 抛出SystemExit异常导致程序退出
raise SystemExit
# 检查是否设置了键盘中断的标记 # 检查是否设置了键盘中断的标记
elif kb.get("dumpKeyboardInterrupt"): elif kb.get("dumpKeyboardInterrupt"): # 检查是否设置了键盘中断标记
# 如果设置了则抛出SystemExit异常导致程序退出 raise SystemExit # 退出程序
raise SystemExit
# 检查excMsg是否包含特定的错误信息即"Broken pipe" # 检查excMsg是否包含特定的错误信息即"Broken pipe"
elif any(_ in excMsg for _ in ("Broken pipe",)): elif any(_ in excMsg for _ in ("Broken pipe",)): # 检查异常信息是否包含Broken pipe
# 如果包含则直接抛出SystemExit异常导致程序退出 raise SystemExit # 退出程序
raise SystemExit
# 检查valid变量是否为False # 检查valid变量是否为False
elif valid is False: elif valid is False: # 检查校验和是否无效
# 如果为False则设置错误信息为代码校验失败 errMsg = "code checksum failed (turning off automatic issue creation). " # 生成错误信息
errMsg = "code checksum failed (turning off automatic issue creation). " errMsg += "You should retrieve the latest development version from official GitHub " # 添加提示信息
errMsg += "You should retrieve the latest development version from official GitHub " errMsg += "repository at '%s'" % GIT_PAGE # 添加GitHub仓库链接
errMsg += "repository at '%s'" % GIT_PAGE logger.critical(errMsg) # 记录严重错误信息
# 使用logger记录这个严重错误 print() # 打印空行
logger.critical(errMsg) dataToStdout(excMsg) # 输出异常信息到标准输出
# 打印空行 raise SystemExit # 退出程序
print()
# 将错误信息输出到标准输出
dataToStdout(excMsg)
# 抛出SystemExit异常导致程序退出
raise SystemExit
# 检查errMsg和excMsg组合后是否包含特定的错误信息即文件路径或特定参数 # 检查errMsg和excMsg组合后是否包含特定的错误信息即文件路径或特定参数
elif any(_ in "%s\n%s" % (errMsg, excMsg) for _ in ("tamper/", "waf/", "--engagement-dojo")): elif any(_ in "%s\n%s" % (errMsg, excMsg) for _ in ("tamper/", "waf/", "--engagement-dojo")): # 检查错误信息是否包含特定路径或参数
# 如果包含则使用logger记录这个严重错误 logger.critical(errMsg) # 记录严重错误信息
logger.critical(errMsg) print() # 打印空行
# 打印空行 dataToStdout(excMsg) # 输出异常信息到标准输出
print() raise SystemExit # 退出程序
# 将错误信息输出到标准输出
dataToStdout(excMsg)
# 抛出SystemExit异常导致程序退出
raise SystemExit
# 检查错误信息中是否包含特定的错误关键词,如果包含,则认为是运行时环境错误,并提取错误信息的最后部分。 # 检查错误信息中是否包含特定的错误关键词,如果包含,则认为是运行时环境错误,并提取错误信息的最后部分。
elif any(_ in excMsg for _ in ("ImportError", "ModuleNotFoundError", "<frozen", "Can't find file for module", "SAXReaderNotAvailable", "<built-in function compile> returned NULL without setting an exception", "source code string cannot contain null bytes", "No module named", "tp_name field", "module 'sqlite3' has no attribute 'OperationalError'")): elif any(_ in excMsg for _ in ("ImportError", "ModuleNotFoundError", "<frozen", "Can't find file for module", "SAXReaderNotAvailable", "<built-in function compile> returned NULL without setting an exception", "source code string cannot contain null bytes", "No module named", "tp_name field", "module 'sqlite3' has no attribute 'OperationalError'")): # 检查异常信息是否包含运行时环境错误
errMsg = "invalid runtime environment ('%s')" % excMsg.split("Error: ")[-1].strip() errMsg = "invalid runtime environment ('%s')" % excMsg.split("Error: ")[-1].strip() # 生成错误信息
logger.critical(errMsg) logger.critical(errMsg) # 记录严重错误信息
raise SystemExit raise SystemExit # 退出程序
# 如果错误信息包含非ASCII字符编码错误则认为是运行时环境错误并提取错误信息的最后部分。 # 如果错误信息包含非ASCII字符编码错误则认为是运行时环境错误并提取错误信息的最后部分。
elif all(_ in excMsg for _ in ("SyntaxError: Non-ASCII character", ".py on line", "but no encoding declared")): elif all(_ in excMsg for _ in ("SyntaxError: Non-ASCII character", ".py on line", "but no encoding declared")): # 检查异常信息是否包含非ASCII字符编码错误
errMsg = "invalid runtime environment ('%s')" % excMsg.split("Error: ")[-1].strip() errMsg = "invalid runtime environment ('%s')" % excMsg.split("Error: ")[-1].strip() # 生成错误信息
logger.critical(errMsg) logger.critical(errMsg) # 记录严重错误信息
raise SystemExit raise SystemExit # 退出程序
# 如果错误信息包含文件不存在的错误,则认为是运行时环境错误,并提取错误信息的最后部分。 # 如果错误信息包含文件不存在的错误,则认为是运行时环境错误,并提取错误信息的最后部分。
elif all(_ in excMsg for _ in ("FileNotFoundError: [Errno 2] No such file or directory", "cwd = os.getcwd()")): elif all(_ in excMsg for _ in ("FileNotFoundError: [Errno 2] No such file or directory", "cwd = os.getcwd()")): # 检查异常信息是否包含文件不存在错误
errMsg = "invalid runtime environment ('%s')" % excMsg.split("Error: ")[-1].strip() errMsg = "invalid runtime environment ('%s')" % excMsg.split("Error: ")[-1].strip() # 生成错误信息
logger.critical(errMsg) logger.critical(errMsg) # 记录严重错误信息
raise SystemExit raise SystemExit # 退出程序
# 如果错误信息包含权限错误,则提示用户可能存在权限问题,并建议重新运行程序时禁用多进程。 # 如果错误信息包含权限错误,则提示用户可能存在权限问题,并建议重新运行程序时禁用多进程。
elif all(_ in excMsg for _ in ("PermissionError: [WinError 5]", "multiprocessing")): elif all(_ in excMsg for _ in ("PermissionError: [WinError 5]", "multiprocessing")): # 检查异常信息是否包含权限错误
errMsg = "there is a permission problem in running multiprocessing on this system. " errMsg = "there is a permission problem in running multiprocessing on this system. " # 生成错误信息
errMsg += "Please rerun with '--disable-multi'" errMsg += "Please rerun with '--disable-multi'" # 添加建议信息
logger.critical(errMsg) logger.critical(errMsg) # 记录严重错误信息
raise SystemExit raise SystemExit # 退出程序
# 如果错误信息包含文件不存在的错误则提示用户安装可能已损坏并建议从官方GitHub仓库获取最新开发版本。 # 如果错误信息包含文件不存在的错误则提示用户安装可能已损坏并建议从官方GitHub仓库获取最新开发版本。
elif all(_ in excMsg for _ in ("No such file", "_'")): elif all(_ in excMsg for _ in ("No such file", "_'")): # 检查异常信息是否包含文件不存在错误
errMsg = "corrupted installation detected ('%s'). " % excMsg.strip().split('\n')[-1] errMsg = "corrupted installation detected ('%s'). " % excMsg.strip().split('\n')[-1] # 生成错误信息
errMsg += "You should retrieve the latest development version from official GitHub " errMsg += "You should retrieve the latest development version from official GitHub " # 添加提示信息
errMsg += "repository at '%s'" % GIT_PAGE errMsg += "repository at '%s'" % GIT_PAGE # 添加GitHub仓库链接
logger.critical(errMsg) logger.critical(errMsg) # 记录严重错误信息
raise SystemExit raise SystemExit # 退出程序
# 如果错误信息包含尝试在生产环境中运行开发测试的错误,则输出相应的错误信息。 # 如果错误信息包含尝试在生产环境中运行开发测试的错误,则输出相应的错误信息。
elif all(_ in excMsg for _ in ("No such file", "sqlmap.conf", "Test")): elif all(_ in excMsg for _ in ("No such file", "sqlmap.conf", "Test")): # 检查异常信息是否包含在生产环境中运行开发测试的错误
errMsg = "you are trying to run (hidden) development tests inside the production environment" errMsg = "you are trying to run (hidden) development tests inside the production environment" # 生成错误信息
logger.critical(errMsg) logger.critical(errMsg) # 记录严重错误信息
raise SystemExit raise SystemExit # 退出程序
# 如果错误信息包含HTTP NTLM认证相关的兼容性问题则输出相应的错误信息并提供参考链接。 # 如果错误信息包含HTTP NTLM认证相关的兼容性问题则输出相应的错误信息并提供参考链接。
elif all(_ in excMsg for _ in ("HTTPNtlmAuthHandler", "'str' object has no attribute 'decode'")): elif all(_ in excMsg for _ in ("HTTPNtlmAuthHandler", "'str' object has no attribute 'decode'")): # 检查异常信息是否包含HTTP NTLM认证兼容性问题
errMsg = "package 'python-ntlm' has a known compatibility issue with the " errMsg = "package 'python-ntlm' has a known compatibility issue with the " # 生成错误信息
errMsg += "Python 3 (Reference: 'https://github.com/mullender/python-ntlm/pull/61&#39;)&#34; " errMsg += "Python 3 (Reference: 'https://github.com/mullender/python-ntlm/pull/61&#39;)&#34; " # 添加参考链接
logger.critical(errMsg) logger.critical(errMsg) # 记录严重错误信息
raise SystemExit raise SystemExit # 退出程序
# 如果错误信息包含字典对象属性错误,并且与枚举相关,则提示用户可能存在枚举问题,并建议重新运行程序时刷新会话。 # 如果错误信息包含字典对象属性错误,并且与枚举相关,则提示用户可能存在枚举问题,并建议重新运行程序时刷新会话。
elif "'DictObject' object has no attribute '" in excMsg and all(_ in errMsg for _ in ("(fingerprinted)", "(identified)")): elif "'DictObject' object has no attribute '" in excMsg and all(_ in errMsg for _ in ("(fingerprinted)", "(identified)")): # 检查异常信息是否包含字典对象属性错误
errMsg = "there has been a problem in enumeration. " errMsg = "there has been a problem in enumeration. " # 生成错误信息
errMsg += "Because of a considerable chance of false-positive case " errMsg += "Because of a considerable chance of false-positive case " # 添加提示信息
errMsg += "you are advised to rerun with switch '--flush-session'" errMsg += "you are advised to rerun with switch '--flush-session'" # 添加建议信息
logger.critical(errMsg) logger.critical(errMsg) # 记录严重错误信息
raise SystemExit raise SystemExit # 退出程序
# 如果错误信息包含数据库磁盘映像损坏的错误,则提示用户会话文件可能损坏,并建议刷新会话。 # 如果错误信息包含数据库磁盘映像损坏的错误,则提示用户会话文件可能损坏,并建议刷新会话。
elif "database disk image is malformed" in excMsg: elif "database disk image is malformed" in excMsg: # 检查异常信息是否包含数据库磁盘映像损坏
errMsg = "local session file seems to be malformed. Please rerun with '--flush-session'" errMsg = "local session file seems to be malformed. Please rerun with '--flush-session'" # 生成错误信息
logger.critical(errMsg) logger.critical(errMsg) # 记录严重错误信息
raise SystemExit raise SystemExit # 退出程序
# 如果错误信息包含模块属性错误,则认为是运行时环境错误,并提取错误信息的最后部分。 # 如果错误信息包含模块属性错误,则认为是运行时环境错误,并提取错误信息的最后部分。
elif "AttributeError: 'module' object has no attribute 'F_GETFD'" in excMsg: elif "AttributeError: 'module' object has no attribute 'F_GETFD'" in excMsg: # 检查异常信息是否包含模块属性错误
errMsg = "invalid runtime (\"%s\") " % excMsg.split("Error: ")[-1].strip() errMsg = "invalid runtime (\"%s\") " % excMsg.split("Error: ")[-1].strip() # 生成错误信息
errMsg += "(Reference: 'https://stackoverflow.com/a/38841364&#39; & 'https://bugs.python.org/issue24944#msg249231&#39;)&#34; " errMsg += "(Reference: 'https://stackoverflow.com/a/38841364&#39; & 'https://bugs.python.org/issue24944#msg249231&#39;)&#34; " # 添加参考链接
logger.critical(errMsg) logger.critical(errMsg) # 记录严重错误信息
raise SystemExit raise SystemExit # 退出程序
# 如果错误信息包含marshal数据错误则提示用户.pyc文件可能损坏并建议删除.pyc文件来解决问题。 # 如果错误信息包含marshal数据错误则提示用户.pyc文件可能损坏并建议删除.pyc文件来解决问题。
elif "bad marshal data (unknown type code)" in excMsg: elif "bad marshal data (unknown type code)" in excMsg: # 检查异常信息是否包含marshal数据错误
match = re.search(r"\s*(.+)\s+ValueError", excMsg) match = re.search(r"\s*(.+)\s+ValueError", excMsg) # 提取损坏的文件路径
errMsg = "one of your .pyc files are corrupted%s" % (" ('%s')" % match.group(1) if match else "") errMsg = "one of your .pyc files are corrupted%s" % (" ('%s')" % match.group(1) if match else "") # 生成错误信息
errMsg += ". Please delete .pyc files on your system to fix the problem" errMsg += ". Please delete .pyc files on your system to fix the problem" # 添加建议信息
logger.critical(errMsg) logger.critical(errMsg) # 记录严重错误信息
raise SystemExit raise SystemExit # 退出程序
for match in re.finditer(r'File "(.+?)", line', excMsg): # 遍历异常信息中的文件路径,并对其进行规范化处理
file_ = match.group(1) for match in re.finditer(r'File "(.+?)", line', excMsg): # 查找异常信息中的文件路径
file_ = match.group(1) # 提取文件路径
try: try:
file_ = os.path.relpath(file_, os.path.dirname(__file__)) file_ = os.path.relpath(file_, os.path.dirname(__file__)) # 将文件路径转换为相对路径
except ValueError: except ValueError: # 捕获路径转换错误
pass pass # 忽略错误
file_ = file_.replace("\\", '/') file_ = file_.replace("\\", '/') # 将路径中的反斜杠替换为正斜杠
if "../" in file_: if "../" in file_: # 检查路径中是否包含上级目录
file_ = re.sub(r"(\.\./)+", '/', file_) file_ = re.sub(r"(\.\./)+", '/', file_) # 替换上级目录为单斜杠
else: else:
file_ = file_.lstrip('/') file_ = file_.lstrip('/') # 去除路径开头的斜杠
file_ = re.sub(r"/{2,}", '/', file_) file_ = re.sub(r"/{2,}", '/', file_) # 将多个斜杠替换为单斜杠
excMsg = excMsg.replace(match.group(1), file_) excMsg = excMsg.replace(match.group(1), file_) # 更新异常信息中的文件路径
errMsg = maskSensitiveData(errMsg) # 对错误信息和异常信息进行敏感数据掩码处理
excMsg = maskSensitiveData(excMsg) errMsg = maskSensitiveData(errMsg) # 掩码处理错误信息中的敏感数据
excMsg = maskSensitiveData(excMsg) # 掩码处理异常信息中的敏感数据
if conf.get("api") or not valid: # 如果配置了API或校验和无效则记录错误信息和异常信息
logger.critical("%s\n%s" % (errMsg, excMsg)) if conf.get("api") or not valid: # 检查是否配置了API或校验和无效
logger.critical("%s\n%s" % (errMsg, excMsg)) # 记录严重错误信息和异常信息
else: else:
logger.critical(errMsg) logger.critical(errMsg) # 记录严重错误信息
dataToStdout("%s\n" % setColor(excMsg.strip(), level=logging.CRITICAL)) dataToStdout("%s\n" % setColor(excMsg.strip(), level=logging.CRITICAL)) # 输出带颜色的异常信息到标准输出
createGithubIssue(errMsg, excMsg) createGithubIssue(errMsg, excMsg) # 创建GitHub问题
finally: finally: # 无论是否发生异常,最终都会执行的代码块
kb.threadContinue = False kb.threadContinue = False # 设置线程继续标志为False
if (getDaysFromLastUpdate() or 0) > LAST_UPDATE_NAGGING_DAYS: # 如果距离上次更新的天数超过指定值,则提示用户版本过时
warnMsg = "your sqlmap version is outdated" if (getDaysFromLastUpdate() or 0) > LAST_UPDATE_NAGGING_DAYS: # 检查距离上次更新的天数
logger.warning(warnMsg) warnMsg = "your sqlmap version is outdated" # 生成警告信息
logger.warning(warnMsg) # 记录警告信息
if conf.get("showTime"): # 如果配置了显示时间,则输出结束时间
dataToStdout("\n[*] ending @ %s\n\n" % time.strftime("%X /%Y-%m-%d/"), forceOutput=True) if conf.get("showTime"): # 检查是否配置了显示时间
dataToStdout("\n[*] ending @ %s\n\n" % time.strftime("%X /%Y-%m-%d/"), forceOutput=True) # 输出结束时间
kb.threadException = True kb.threadException = True # 设置线程异常标志为True
if kb.get("tempDir"): # 如果存在临时目录,则清理临时文件
for prefix in (MKSTEMP_PREFIX.IPC, MKSTEMP_PREFIX.TESTING, MKSTEMP_PREFIX.COOKIE_JAR, MKSTEMP_PREFIX.BIG_ARRAY): if kb.get("tempDir"): # 检查是否存在临时目录
for filepath in glob.glob(os.path.join(kb.tempDir, "%s*" % prefix)): for prefix in (MKSTEMP_PREFIX.IPC, MKSTEMP_PREFIX.TESTING, MKSTEMP_PREFIX.COOKIE_JAR, MKSTEMP_PREFIX.BIG_ARRAY): # 遍历临时文件前缀
for filepath in glob.glob(os.path.join(kb.tempDir, "%s*" % prefix)): # 查找匹配的临时文件
try: try:
os.remove(filepath) os.remove(filepath) # 删除临时文件
except OSError: except OSError: # 捕获文件删除错误
pass pass # 忽略错误
if not filterNone(filepath for filepath in glob.glob(os.path.join(kb.tempDir, '*')) if not any(filepath.endswith(_) for _ in (".lock", ".exe", ".so", '_'))): # ignore junk files # 如果临时目录中没有其他文件,则删除临时目录
if not filterNone(filepath for filepath in glob.glob(os.path.join(kb.tempDir, '*')) if not any(filepath.endswith(_) for _ in (".lock", ".exe", ".so", '_'))): # 检查临时目录是否为空
try: try:
shutil.rmtree(kb.tempDir, ignore_errors=True) shutil.rmtree(kb.tempDir, ignore_errors=True) # 删除临时目录
except OSError: except OSError: # 捕获目录删除错误
pass pass # 忽略错误
if conf.get("hashDB"): if conf.get("hashDB"):
conf.hashDB.flush(True) conf.hashDB.flush(True)

Loading…
Cancel
Save