Minor layout adjustments, minor fixes and updated changelog

This commit is contained in:
Bernardo Damele 2008-11-17 00:00:54 +00:00
parent fa0507ab39
commit 654aecedfe
13 changed files with 133 additions and 58 deletions

View File

@ -4,8 +4,10 @@ sqlmap (0.6.3-1) stable; urgency=low
* Minor enhancement to support stacked queries which will be used * Minor enhancement to support stacked queries which will be used
sometimes by takeover functionality and time based blind SQL injection sometimes by takeover functionality and time based blind SQL injection
technique; technique;
* Minor enhancement to fingerprint the back-end DBMS operating system by
parsing the DBMS banner value when both -f and -b are provided;
* Minor enhancement to be able to specify the number of seconds to wait * Minor enhancement to be able to specify the number of seconds to wait
between each HTTP request; between each HTTP request providing option --delay #;
* Minor enhancement to be able to enumerate table columns and dump table * Minor enhancement to be able to enumerate table columns and dump table
entries, also when the database name is not provided, by using the entries, also when the database name is not provided, by using the
current database on MySQL and Microsoft SQL Server, the 'public' current database on MySQL and Microsoft SQL Server, the 'public'

View File

@ -67,7 +67,7 @@ def action():
raise sqlmapUnsupportedDBMSException, errMsg raise sqlmapUnsupportedDBMSException, errMsg
print "back-end DBMS:\t%s\n" % conf.dbmsHandler.getFingerprint() print "%s\n" % conf.dbmsHandler.getFingerprint()
# Techniques options # Techniques options
if conf.timeTest: if conf.timeTest:

View File

@ -453,6 +453,7 @@ def __setKnowledgeBaseAttributes():
kb.dbms = None kb.dbms = None
kb.dbmsDetected = False kb.dbmsDetected = False
kb.dbmsVersion = None kb.dbmsVersion = None
kb.headersFp = {}
kb.htmlFp = [] kb.htmlFp = []
kb.injParameter = None kb.injParameter = None
kb.injPlace = None kb.injPlace = None

57
lib/parse/headers.py Normal file
View File

@ -0,0 +1,57 @@
#!/usr/bin/env python
"""
$Id$
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
and Daniele Bellucci <daniele.bellucci@gmail.com>
sqlmap is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation version 2 of the License.
sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public License along
with sqlmap; if not, write to the Free Software Foundation, Inc., 51
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
"""
import re
from xml.sax import parse
from xml.sax.handler import ContentHandler
from lib.core.common import checkFile
from lib.core.common import sanitizeStr
from lib.core.data import kb
from lib.core.data import paths
from lib.parse.banner import BannerHandler
def headersParser(headers):
"""
This function calls a class that parses the input HTTP headers to
fingerprint the back-end database management system operating system
and web application technology
"""
topHeaders = {
"cookie",
"microsoftsharepointteamservices",
"server",
"servlet-engine",
"www-authenticate",
"x-aspnet-version",
"x-powered-by",
}
for header in headers:
if header in topHeaders:
pass

View File

@ -31,6 +31,8 @@ from xml.sax.handler import ContentHandler
from lib.core.common import checkFile from lib.core.common import checkFile
from lib.core.common import sanitizeStr from lib.core.common import sanitizeStr
from lib.core.data import kb
from lib.core.data import paths
class htmlHandler(ContentHandler): class htmlHandler(ContentHandler):
@ -61,15 +63,21 @@ class htmlHandler(ContentHandler):
self.__match = None self.__match = None
def htmlParser(page, xmlfile): def htmlParser(page, xmlfile=None):
""" """
This function calls a class that parses the input HTML page to This function calls a class that parses the input HTML page to
fingerprint the back-end database management system fingerprint the back-end database management system
""" """
if not xmlfile:
xmlfile = paths.ERRORS_XML
checkFile(xmlfile) checkFile(xmlfile)
page = sanitizeStr(page) page = sanitizeStr(page)
handler = htmlHandler(page) handler = htmlHandler(page)
parse(xmlfile, handler) parse(xmlfile, handler)
if handler.dbms and handler.dbms not in kb.htmlFp:
kb.htmlFp.append(handler.dbms)
return handler.dbms return handler.dbms

View File

@ -29,6 +29,7 @@ import re
from lib.core.data import conf from lib.core.data import conf
from lib.core.data import kb from lib.core.data import kb
from lib.core.data import paths from lib.core.data import paths
from lib.parse.headers import headersParser
from lib.parse.html import htmlParser from lib.parse.html import htmlParser
@ -51,7 +52,7 @@ def forgeHeaders(cookie, ua):
return headers return headers
def parsePage(page): def parseResponse(page, headers):
""" """
@param page: the page to parse to feed the knowledge base htmlFp @param page: the page to parse to feed the knowledge base htmlFp
(back-end DBMS fingerprint based upon DBMS error messages return (back-end DBMS fingerprint based upon DBMS error messages return
@ -63,13 +64,11 @@ def parsePage(page):
like for DBMS error messages (ERRORS_XML), see above. like for DBMS error messages (ERRORS_XML), see above.
""" """
if not page: if headers:
return headersParser(headers)
htmlParsed = htmlParser(page, paths.ERRORS_XML) if page:
htmlParser(page)
if htmlParsed and htmlParsed not in kb.htmlFp:
kb.htmlFp.append(htmlParsed)
# Detect injectable page absolute system path # Detect injectable page absolute system path
# NOTE: this regular expression works if the remote web application # NOTE: this regular expression works if the remote web application

View File

@ -39,7 +39,7 @@ from lib.core.data import kb
from lib.core.data import logger from lib.core.data import logger
from lib.core.exception import sqlmapConnectionException from lib.core.exception import sqlmapConnectionException
from lib.request.basic import forgeHeaders from lib.request.basic import forgeHeaders
from lib.request.basic import parsePage from lib.request.basic import parseResponse
@ -196,7 +196,7 @@ class Connect:
else: else:
raise sqlmapConnectionException, warnMsg raise sqlmapConnectionException, warnMsg
parsePage(page) parseResponse(page, responseHeaders)
responseMsg += "(%s - %d):\n" % (status, code) responseMsg += "(%s - %d):\n" % (status, code)
if conf.verbose <= 4: if conf.verbose <= 4:

View File

@ -124,14 +124,16 @@ class MSSQLServerMap(Fingerprint, Enumeration, Filesystem, Takeover):
def getFingerprint(self): def getFingerprint(self):
value = "back-end DBMS: "
actVer = formatDBMSfp() actVer = formatDBMSfp()
if not conf.extensiveFp: if not conf.extensiveFp:
return actVer value += actVer
return value
blank = " " * 16 blank = " " * 15
formatInfo = None formatInfo = None
value = "active fingerprint: %s" % actVer value += "active fingerprint: %s" % actVer
if self.banner: if self.banner:
info = bannerParser(self.banner) info = bannerParser(self.banner)
@ -148,10 +150,10 @@ class MSSQLServerMap(Fingerprint, Enumeration, Filesystem, Takeover):
value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer) value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer)
#passiveFuzzing() #passiveFuzzing()
htmlParsed = getHtmlErrorFp() htmlErrorFp = getHtmlErrorFp()
if htmlParsed: if htmlErrorFp:
value += "\n%shtml error message fingerprint: %s" % (blank, htmlParsed) value += "\n%shtml error message fingerprint: %s" % (blank, htmlErrorFp)
if formatInfo: if formatInfo:
value += "\n%s" % formatInfo value += "\n%s" % formatInfo

View File

@ -182,15 +182,17 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Takeover):
def getFingerprint(self): def getFingerprint(self):
value = "back-end DBMS: "
actVer = formatDBMSfp() actVer = formatDBMSfp()
if not conf.extensiveFp: if not conf.extensiveFp:
return actVer value += actVer
return value
comVer = self.__commentCheck() comVer = self.__commentCheck()
blank = " " * 16 blank = " " * 15
formatInfo = None formatInfo = None
value = "active fingerprint: %s" % actVer value += "active fingerprint: %s" % actVer
if comVer: if comVer:
comVer = formatDBMSfp([comVer]) comVer = formatDBMSfp([comVer])
@ -207,10 +209,10 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Takeover):
value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer) value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer)
#passiveFuzzing() #passiveFuzzing()
htmlParsed = getHtmlErrorFp() htmlErrorFp = getHtmlErrorFp()
if htmlParsed: if htmlErrorFp:
value += "\n%shtml error message fingerprint: %s" % (blank, htmlParsed) value += "\n%shtml error message fingerprint: %s" % (blank, htmlErrorFp)
if formatInfo: if formatInfo:
value += "\n%s" % formatInfo value += "\n%s" % formatInfo

View File

@ -118,14 +118,16 @@ class OracleMap(Fingerprint, Enumeration, Filesystem, Takeover):
def getFingerprint(self): def getFingerprint(self):
value = "back-end DBMS: "
if not conf.extensiveFp: if not conf.extensiveFp:
return "Oracle" value += "Oracle"
return value
actVer = formatDBMSfp() actVer = formatDBMSfp()
blank = " " * 15
blank = " " * 16
formatInfo = None formatInfo = None
value = "active fingerprint: %s" % actVer value += "active fingerprint: %s" % actVer
if self.banner: if self.banner:
info = bannerParser(self.banner) info = bannerParser(self.banner)
@ -136,10 +138,10 @@ class OracleMap(Fingerprint, Enumeration, Filesystem, Takeover):
value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer) value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer)
#passiveFuzzing() #passiveFuzzing()
htmlParsed = getHtmlErrorFp() htmlErrorFp = getHtmlErrorFp()
if htmlParsed: if htmlErrorFp:
value += "\n%shtml error message fingerprint: %s" % (blank, htmlParsed) value += "\n%shtml error message fingerprint: %s" % (blank, htmlErrorFp)
if formatInfo: if formatInfo:
value += "\n%s" % formatInfo value += "\n%s" % formatInfo

View File

@ -118,14 +118,16 @@ class PostgreSQLMap(Fingerprint, Enumeration, Filesystem, Takeover):
def getFingerprint(self): def getFingerprint(self):
value = "back-end DBMS: "
if not conf.extensiveFp: if not conf.extensiveFp:
return "PostgreSQL" value += "PostgreSQL"
return value
actVer = formatDBMSfp() actVer = formatDBMSfp()
blank = " " * 15
blank = " " * 16
formatInfo = None formatInfo = None
value = "active fingerprint: %s" % actVer value += "active fingerprint: %s" % actVer
if self.banner: if self.banner:
info = bannerParser(self.banner) info = bannerParser(self.banner)
@ -136,10 +138,10 @@ class PostgreSQLMap(Fingerprint, Enumeration, Filesystem, Takeover):
value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer) value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer)
#passiveFuzzing() #passiveFuzzing()
htmlParsed = getHtmlErrorFp() htmlErrorFp = getHtmlErrorFp()
if htmlParsed: if htmlErrorFp:
value += "\n%shtml error message fingerprint: %s" % (blank, htmlParsed) value += "\n%shtml error message fingerprint: %s" % (blank, htmlErrorFp)
if formatInfo: if formatInfo:
value += "\n%s" % formatInfo value += "\n%s" % formatInfo

View File

@ -2,7 +2,7 @@
<root> <root>
<!-- Windows --> <!-- Windows -->
<regexp value="(Windows|Win32)"> <regexp value="(Microsoft|Windows|Win32)">
<info type="Windows"/> <info type="Windows"/>
</regexp> </regexp>