add banner.py

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

Loading…
Cancel
Save