You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
sqlmap/src/sqlmap-master/lib/parse/banner.py

143 lines
5.2 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#!/usr/bin/env python
"""
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):
"""
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 "")
# 初始化是否在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"):
return
self._info[key] = value
def startElement(self, name, attrs):
# 如果标签名为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):
# 如果在version标签中则将content添加到_version中
if self._inVersion:
self._version += sanitizeStr(content)
# 如果在servicepack标签中则将content添加到_servicePack中
elif self._inServicePack:
self._servicePack += sanitizeStr(content)
def endElement(self, name):
# 如果标签名为signature则进行匹配
if name == "signature":
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):
"""
This function calls a class to extract information from the given
DBMS banner based upon the data in XML file
"""
xmlfile = None
# 如果数据库类型为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则使用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)