add banner.py

pull/3/head
wang 2 months ago
parent 9f3934a717
commit 04a605452b

@ -5,31 +5,45 @@ Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
# ... 导入相关模块 ...
import re
from xml.sax.handler import ContentHandler
from lib.core.common import Backend
from lib.core.common import parseXmlFile
from lib.core.common import sanitizeStr
from lib.core.data import kb
from lib.core.data import paths
from lib.core.enums import DBMS
from lib.parse.handler import FingerprintHandler
class MSSQLBannerHandler(ContentHandler):
"""
该类用于解析和提取Microsoft SQL Server banner信息
基于XML文件中的数据进行匹配和处理
This class defines methods to parse and extract information from the
given Microsoft SQL Server banner based upon the data in XML file
"""
def __init__(self, banner, info):
ContentHandler.__init__(self)
# 初始化banner信息和状态标志
self._banner = sanitizeStr(banner or "") # 清理并存储banner字符串
self._inVersion = False # 是否正在处理版本信息的标志
self._inServicePack = False # 是否正在处理ServicePack信息的标志
self._release = None # 发布版本信息
self._version = "" # 版本号
self._versionAlt = None # 替代版本号格式
self._servicePack = "" # ServicePack版本
self._info = info # 存储解析结果的字典
# 初始化banner
self._banner = sanitizeStr(banner or "")
# 初始化是否在version标签中
self._inVersion = False
# 初始化是否在servicepack标签中
self._inServicePack = False
# 初始化release
self._release = None
# 初始化version
self._version = ""
# 初始化versionAlt
self._versionAlt = None
# 初始化servicePack
self._servicePack = ""
# 初始化info
self._info = info
def _feedInfo(self, key, value):
"""
将解析到的信息存入结果字典
"""
value = sanitizeStr(value)
if value in (None, "None"):
@ -38,83 +52,91 @@ class MSSQLBannerHandler(ContentHandler):
self._info[key] = value
def startElement(self, name, attrs):
"""
处理XML元素开始标签
"""
# 如果标签名为signatures则获取release属性
if name == "signatures":
self._release = sanitizeStr(attrs.get("release"))
# 如果标签名为version则设置_inVersion为True
elif name == "version":
self._inVersion = True
# 如果标签名为servicepack则设置_inServicePack为True
elif name == "servicepack":
self._inServicePack = True
def characters(self, content):
"""
处理XML元素的文本内容
"""
# 如果在version标签中则将content添加到_version中
if self._inVersion:
self._version += sanitizeStr(content)
# 如果在servicepack标签中则将content添加到_servicePack中
elif self._inServicePack:
self._servicePack += sanitizeStr(content)
def endElement(self, name):
"""
处理XML元素结束标签
"""
# 如果标签名为signature则进行匹配
if name == "signature":
# 检查banner中是否包含匹配的版本信息
for version in (self._version, self._versionAlt):
# 如果version不为空且banner不为空且banner中包含version则将release、version、servicePack添加到info中
if version and self._banner and re.search(r" %s[\.\ ]+" % re.escape(version), self._banner):
# 找到匹配后,保存相关信息
self._feedInfo("dbmsRelease", self._release)
self._feedInfo("dbmsVersion", self._version)
self._feedInfo("dbmsServicePack", self._servicePack)
break
# 重置临时变量
# 重置version、versionAlt、servicePack
self._version = ""
self._versionAlt = None
self._servicePack = ""
# 如果标签名为version则将_version中的空格去除并尝试匹配
elif name == "version":
self._inVersion = False
self._version = self._version.replace(" ", "")
# 处理特殊的版本号格式
# 尝试匹配
match = re.search(r"\A(?P<major>\d+)\.00\.(?P<build>\d+)\Z", self._version)
# 如果匹配成功则将versionAlt设置为"%s.0.%s.0" % (match.group('major'), match.group('build'))
self._versionAlt = "%s.0.%s.0" % (match.group('major'), match.group('build')) if match else None
# 如果标签名为servicepack则将_servicePack中的空格去除
elif name == "servicepack":
self._inServicePack = False
self._servicePack = self._servicePack.replace(" ", "")
def bannerParser(banner):
"""
根据不同的数据库类型调用相应的处理器来解析banner信息
This function calls a class to extract information from the given
DBMS banner based upon the data in XML file
"""
xmlfile = None
# 根据数据库类型选择对应的XML配置文件
# 如果数据库类型为MSSQL则设置xmlfile为paths.MSSQL_XML
if Backend.isDbms(DBMS.MSSQL):
xmlfile = paths.MSSQL_XML
# 如果数据库类型为MYSQL则设置xmlfile为paths.MYSQL_XML
elif Backend.isDbms(DBMS.MYSQL):
xmlfile = paths.MYSQL_XML
# 如果数据库类型为ORACLE则设置xmlfile为paths.ORACLE_XML
elif Backend.isDbms(DBMS.ORACLE):
xmlfile = paths.ORACLE_XML
# 如果数据库类型为PGSQL则设置xmlfile为paths.PGSQL_XML
elif Backend.isDbms(DBMS.PGSQL):
xmlfile = paths.PGSQL_XML
# 如果xmlfile为空则返回
if not xmlfile:
return
# 针对MSSQL使用专门的处理器其他数据库使用通用处理器
# 如果数据库类型为MSSQL则使用MSSQLBannerHandler解析xmlfile并使用FingerprintHandler解析paths.GENERIC_XML
if Backend.isDbms(DBMS.MSSQL):
handler = MSSQLBannerHandler(banner, kb.bannerFp)
parseXmlFile(xmlfile, handler)
handler = FingerprintHandler(banner, kb.bannerFp)
parseXmlFile(paths.GENERIC_XML, handler)
# 否则使用FingerprintHandler解析xmlfile和paths.GENERIC_XML
else:
handler = FingerprintHandler(banner, kb.bannerFp)
parseXmlFile(xmlfile, handler)
parseXmlFile(paths.GENERIC_XML, handler)
parseXmlFile(paths.GENERIC_XML, handler)

Loading…
Cancel
Save