After the storm, a restore..

This commit is contained in:
Bernardo Damele
2008-10-15 15:38:22 +00:00
commit 8e3eb45510
78 changed files with 21360 additions and 0 deletions

25
lib/parse/__init__.py Normal file
View File

@@ -0,0 +1,25 @@
#!/usr/bin/env python
"""
$Id: __init__.py 214 2008-07-14 14:17:06Z inquisb $
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
"""
pass

104
lib/parse/banner.py Normal file
View File

@@ -0,0 +1,104 @@
#!/usr/bin/env python
"""
$Id: banner.py 214 2008-07-14 14:17:06Z inquisb $
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
class bannerHandler(ContentHandler):
"""
This class defines methods to parse and extract information from
the given DBMS banner based upon the data in XML file
"""
def __init__(self, banner):
self.__banner = sanitizeStr(banner)
self.release = None
self.version = None
self.servicePack = None
self.__inVersion = False
self.__inServicePack = False
self.__release = None
self.__version = ""
self.__servicePack = ""
def startElement(self, name, attrs):
if name == "signatures":
self.__release = sanitizeStr(attrs.get("release"))
elif name == "version":
self.__inVersion = True
elif name == "servicepack":
self.__inServicePack = True
def characters(self, data):
if self.__inVersion:
self.__version += sanitizeStr(data)
elif self.__inServicePack:
self.__servicePack += sanitizeStr(data)
def endElement(self, name):
if name == "signature":
if re.search(" %s[\.\ ]+" % self.__version, self.__banner):
self.release = self.__release
self.version = self.__version
self.servicePack = self.__servicePack
self.__version = ""
self.__servicePack = ""
elif name == "version":
self.__inVersion = False
self.__version = self.__version.replace(" ", "")
elif name == "servicepack":
self.__inServicePack = False
self.__servicePack = self.__servicePack.replace(" ", "")
def bannerParser(banner, xmlfile):
"""
This function calls a class to extract information from the given
DBMS banner based upon the data in XML file
"""
checkFile(xmlfile)
banner = sanitizeStr(banner)
handler = bannerHandler(banner)
parse(xmlfile, handler)
return handler.release, handler.version, handler.servicePack

268
lib/parse/cmdline.py Normal file
View File

@@ -0,0 +1,268 @@
#!/usr/bin/env python
"""
$Id: cmdline.py 368 2008-09-30 00:09:59Z inquisb $
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
"""
from optparse import OptionError
from optparse import OptionGroup
from optparse import OptionParser
from lib.core.data import logger
from lib.core.settings import VERSION_STRING
def cmdLineParser():
"""
This function parses the command line parameters and arguments
"""
usage = "sqlmap.py [options] {-u <URL> | -g <google dork> | -c <config file>}"
parser = OptionParser(usage=usage, version=VERSION_STRING)
try:
# Request options
request = OptionGroup(parser, "Request", "These options have to "
"be specified to set the target url, HTTP "
"method, how to connect to the target url "
"or Google dorking results in general.")
request.add_option("-u", "--url", dest="url", help="Target url")
request.add_option("-g", dest="googleDork",
help="Process Google dork results as target urls")
request.add_option("-p", dest="testParameter",
help="Testable parameter(s)")
request.add_option("--method", dest="method", default="GET",
help="HTTP method, GET or POST (default: GET)")
request.add_option("--data", dest="data",
help="Data string to be sent through POST")
request.add_option("--cookie", dest="cookie",
help="HTTP Cookie header")
request.add_option("--referer", dest="referer",
help="HTTP Referer header")
request.add_option("--user-agent", dest="agent",
help="HTTP User-Agent header")
request.add_option("-a", dest="userAgentsFile",
help="Load a random HTTP User-Agent "
"header from file")
request.add_option("--auth-type", dest="aType",
help="HTTP Authentication type, value: "
"Basic or Digest")
request.add_option("--auth-cred", dest="aCred",
help="HTTP Authentication credentials, value: "
"name:password")
request.add_option("--proxy", dest="proxy",
help="Use a HTTP proxy to connect to the target url")
request.add_option("--threads", dest="threads", type="int",
help="Maximum number of concurrent HTTP "
"requests (default 1)")
# Injection options
injection = OptionGroup(parser, "Injection")
injection.add_option("--string", dest="string",
help="String to match in page when the "
"query is valid")
injection.add_option("--dbms", dest="dbms",
help="Force back-end DBMS to this value")
# Fingerprint options
fingerprint = OptionGroup(parser, "Fingerprint")
fingerprint.add_option("-f", "--fingerprint", dest="extensiveFp",
action="store_true",
help="Perform an extensive database fingerprint")
# Enumeration options
enumeration = OptionGroup(parser, "Enumeration", "These options can "
"be used to enumerate the back-end database "
"management system information, structure "
"and data contained in the tables. Moreover "
"you can run your own SQL SELECT queries.")
enumeration.add_option("-b", "--banner", dest="getBanner",
action="store_true", help="Retrieve DBMS banner")
enumeration.add_option("--current-user", dest="getCurrentUser",
action="store_true",
help="Retrieve DBMS current user")
enumeration.add_option("--current-db", dest="getCurrentDb",
action="store_true",
help="Retrieve DBMS current database")
enumeration.add_option("--users", dest="getUsers", action="store_true",
help="Enumerate DBMS users")
enumeration.add_option("--passwords", dest="getPasswordHashes",
action="store_true",
help="Enumerate DBMS users password hashes (opt: -U)")
enumeration.add_option("--privileges", dest="getPrivileges",
action="store_true",
help="Enumerate DBMS users privileges (opt: -U)")
enumeration.add_option("--dbs", dest="getDbs", action="store_true",
help="Enumerate DBMS databases")
enumeration.add_option("--tables", dest="getTables", action="store_true",
help="Enumerate DBMS database tables (opt: -D)")
enumeration.add_option("--columns", dest="getColumns", action="store_true",
help="Enumerate DBMS database table columns "
"(req: -T, -D)")
enumeration.add_option("--dump", dest="dumpTable", action="store_true",
help="Dump DBMS database table entries "
"(req: -T, -D opt: -C)")
enumeration.add_option("--dump-all", dest="dumpAll", action="store_true",
help="Dump all DBMS databases tables entries")
enumeration.add_option("-D", dest="db",
help="DBMS database to enumerate")
enumeration.add_option("-T", dest="tbl",
help="DBMS database table to enumerate")
enumeration.add_option("-C", dest="col",
help="DBMS database table column to enumerate")
enumeration.add_option("-U", dest="user",
help="DBMS user to enumerate")
enumeration.add_option("--exclude-sysdbs", dest="excludeSysDbs",
action="store_true",
help="Exclude DBMS system databases when "
"enumerating tables")
enumeration.add_option("--start", dest="limitStart", type="int",
help="First table entry to dump")
enumeration.add_option("--stop", dest="limitStop", type="int",
help="Last table entry to dump")
enumeration.add_option("--sql-query", dest="query",
help="SQL SELECT query to be executed")
enumeration.add_option("--sql-shell", dest="sqlShell",
action="store_true",
help="Prompt for an interactive SQL shell")
# File system options
filesystem = OptionGroup(parser, "File system access", "These options "
"can be used to access the back-end database "
"management system file system taking "
"advantage of native DBMS functions or "
"specific DBMS design weaknesses.")
filesystem.add_option("--read-file", dest="rFile",
help="Read a specific OS file content (only on MySQL)")
filesystem.add_option("--write-file", dest="wFile",
help="Write to a specific OS file (not yet available)")
# Takeover options
takeover = OptionGroup(parser, "Operating system access", "This "
"option can be used to access the back-end "
"database management system operating "
"system taking advantage of specific DBMS "
"design weaknesses.")
takeover.add_option("--os-shell", dest="osShell", action="store_true",
help="Prompt for an interactive OS shell "
"(only on PHP/MySQL environment with a "
"writable directory within the web "
"server document root for the moment)")
# Miscellaneous options
miscellaneous = OptionGroup(parser, "Miscellaneous")
miscellaneous.add_option("--union-test", dest="unionTest",
action="store_true",
help="Test for UNION SELECT (inband) SQL injection")
miscellaneous.add_option("--union-use", dest="unionUse",
action="store_true",
help="Use the UNION SELECT (inband) SQL injection "
"to retrieve the queries output. No "
"need to go blind")
miscellaneous.add_option("--eta", dest="eta", action="store_true",
help="Retrieve each query output length and "
"calculate the estimated time of arrival "
"in real time")
miscellaneous.add_option("-v", dest="verbose", type="int",
help="Verbosity level: 0-5 (default 0)")
miscellaneous.add_option("--update", dest="updateAll", action="store_true",
help="Update sqlmap to the latest stable version")
miscellaneous.add_option("-s", dest="sessionFile",
help="Save and resume all data retrieved "
"on a session file")
miscellaneous.add_option("-c", dest="configFile",
help="Load options from a configuration INI file")
miscellaneous.add_option("--save", dest="saveCmdline", action="store_true",
help="Save options on a configuration INI file")
miscellaneous.add_option("--batch", dest="batch", action="store_true",
help="Never ask for user input, use the default behaviour")
parser.add_option_group(request)
parser.add_option_group(injection)
parser.add_option_group(fingerprint)
parser.add_option_group(enumeration)
parser.add_option_group(filesystem)
parser.add_option_group(takeover)
parser.add_option_group(miscellaneous)
(args, _) = parser.parse_args()
if not args.url and not args.googleDork and not args.configFile and not args.updateAll:
errMsg = "missing a mandatory parameter ('-u', '-g', '-c' or '--update'), "
errMsg += "-h for help"
parser.error(errMsg)
return args
except (OptionError, TypeError), e:
parser.error(e)
debugMsg = "parsing command line"
logger.debug(debugMsg)

101
lib/parse/configfile.py Normal file
View File

@@ -0,0 +1,101 @@
#!/usr/bin/env python
"""
$Id: configfile.py 261 2008-07-21 11:33:49Z inquisb $
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
"""
from ConfigParser import NoSectionError
from ConfigParser import SafeConfigParser
from lib.core.common import checkFile
from lib.core.data import conf
from lib.core.data import logger
from lib.core.exception import sqlmapMissingMandatoryOptionException
from lib.core.optiondict import optDict
config = None
def configFileProxy(section, option, boolean=False, integer=False):
"""
Parse configuration file and save settings into the configuration
advanced dictionary.
"""
global config
if config.has_option(section, option):
if boolean:
value = config.getboolean(section, option)
elif integer:
value = config.getint(section, option)
else:
value = config.get(section, option)
if value:
conf[option] = value
else:
conf[option] = None
else:
debugMsg = "missing requested option '%s' (section " % option
debugMsg += "'%s') into the configuration file, " % section
debugMsg += "ignoring. Skipping to next."
logger.debug(debugMsg)
def configFileParser(configFile):
"""
Parse configuration file and save settings into the configuration
advanced dictionary.
"""
global config
debugMsg = "parsing configuration file"
logger.debug(debugMsg)
checkFile(configFile)
config = SafeConfigParser()
config.read(configFile)
if not config.has_section("Request"):
raise NoSectionError, "Request in the configuration file is mandatory"
if not config.has_option("Request", "url") and not config.has_option("Request", "googleDork"):
errMsg = "missing a mandatory option in the configuration "
errMsg += "file (url or googleDork)"
raise sqlmapMissingMandatoryOptionException, errMsg
for family, optionData in optDict.items():
for option, data in optionData.items():
boolean = False
integer = False
if data == "boolean":
boolean = True
elif data == "integer":
integer = True
configFileProxy(family, option, boolean, integer)

75
lib/parse/html.py Normal file
View File

@@ -0,0 +1,75 @@
#!/usr/bin/env python
"""
$Id: html.py 286 2008-07-25 23:09:48Z inquisb $
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
class htmlHandler(ContentHandler):
"""
This class defines methods to parse the input HTML page to
fingerprint the back-end database management system
"""
def __init__(self, page):
self.__dbms = None
self.__page = page
self.__regexp = None
self.__match = None
self.dbms = None
def startElement(self, name, attrs):
if name == "dbms":
self.__dbms = attrs.get("value")
if name == "error":
self.__regexp = attrs.get("regexp")
self.__match = re.search(self.__regexp, self.__page, re.I)
if self.__match:
self.dbms = self.__dbms
self.__match = None
def htmlParser(page, xmlfile):
"""
This function calls a class that parses the input HTML page to
fingerprint the back-end database management system
"""
checkFile(xmlfile)
page = sanitizeStr(page)
handler = htmlHandler(page)
parse(xmlfile, handler)
return handler.dbms

203
lib/parse/queriesfile.py Normal file
View File

@@ -0,0 +1,203 @@
#!/usr/bin/env python
"""
$Id: queriesfile.py 343 2008-08-30 01:12:18Z inquisb $
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
"""
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 logger
from lib.core.data import queries
from lib.core.data import paths
from lib.core.datatype import advancedDict
class queriesHandler(ContentHandler):
"""
This class defines methods to parse the default DBMS queries
from an XML file
"""
def __init__(self):
self.__dbms = ''
self.__queries = advancedDict()
def startElement(self, name, attrs):
if name == "dbms":
data = sanitizeStr(attrs.get("value"))
self.__dbms = data
elif name == "cast":
data = sanitizeStr(attrs.get("query"))
self.__queries.cast = data
elif name == "length":
data = sanitizeStr(attrs.get("query"))
self.__queries.length = data
elif name == "isnull":
data = sanitizeStr(attrs.get("query"))
self.__queries.isnull = data
elif name == "delimiter":
data = sanitizeStr(attrs.get("query"))
self.__queries.delimiter = data
elif name == "limit":
data = sanitizeStr(attrs.get("query"))
self.__queries.limit = data
elif name == "limitregexp":
data = sanitizeStr(attrs.get("query"))
self.__queries.limitregexp = data
elif name == "limitgroupstart":
data = sanitizeStr(attrs.get("query"))
self.__queries.limitgroupstart = data
elif name == "limitgroupstop":
data = sanitizeStr(attrs.get("query"))
self.__queries.limitgroupstop = data
elif name == "limitstring":
data = sanitizeStr(attrs.get("query"))
self.__queries.limitstring = data
elif name == "order":
data = sanitizeStr(attrs.get("query"))
self.__queries.order = data
elif name == "count":
data = sanitizeStr(attrs.get("query"))
self.__queries.count = data
elif name == "substring":
data = sanitizeStr(attrs.get("query"))
self.__queries.substring = data
elif name == "inference":
data = sanitizeStr(attrs.get("query"))
self.__queries.inference = data
elif name == "banner":
data = sanitizeStr(attrs.get("query"))
self.__queries.banner = data
elif name == "current_user":
data = sanitizeStr(attrs.get("query"))
self.__queries.currentUser = data
elif name == "current_db":
data = sanitizeStr(attrs.get("query"))
self.__queries.currentDb = data
elif name == "inband":
self.__inband = sanitizeStr(attrs.get("query"))
self.__inband2 = sanitizeStr(attrs.get("query2"))
self.__condition = sanitizeStr(attrs.get("condition"))
self.__condition2 = sanitizeStr(attrs.get("condition2"))
elif name == "blind":
self.__blind = sanitizeStr(attrs.get("query"))
self.__blind2 = sanitizeStr(attrs.get("query2"))
self.__count = sanitizeStr(attrs.get("count"))
self.__count2 = sanitizeStr(attrs.get("count2"))
def endElement(self, name):
if name == "dbms":
queries[self.__dbms] = self.__queries
self.__queries = advancedDict()
elif name == "users":
self.__users = {}
self.__users["inband"] = { "query": self.__inband, "query2": self.__inband2 }
self.__users["blind"] = { "query": self.__blind, "query2": self.__blind2,
"count": self.__count, "count2": self.__count2 }
self.__queries.users = self.__users
elif name == "passwords":
self.__passwords = {}
self.__passwords["inband"] = { "query": self.__inband, "query2": self.__inband2, "condition": self.__condition }
self.__passwords["blind"] = { "query": self.__blind, "query2": self.__blind2,
"count": self.__count, "count2": self.__count2 }
self.__queries.passwords = self.__passwords
elif name == "privileges":
self.__privileges = {}
self.__privileges["inband"] = { "query": self.__inband, "query2": self.__inband2, "condition": self.__condition, "condition2": self.__condition2 }
self.__privileges["blind"] = { "query": self.__blind, "query2": self.__blind2,
"count": self.__count, "count2": self.__count2 }
self.__queries.privileges = self.__privileges
elif name == "dbs":
self.__dbs = {}
self.__dbs["inband"] = { "query": self.__inband, "query2": self.__inband2 }
self.__dbs["blind"] = { "query": self.__blind, "query2": self.__blind2,
"count": self.__count, "count2": self.__count2 }
self.__queries.dbs = self.__dbs
elif name == "tables":
self.__tables = {}
self.__tables["inband"] = { "query": self.__inband, "condition": self.__condition }
self.__tables["blind"] = { "query": self.__blind, "count": self.__count }
self.__queries.tables = self.__tables
elif name == "columns":
self.__columns = {}
self.__columns["inband"] = { "query": self.__inband }
self.__columns["blind"] = { "query": self.__blind, "query2": self.__blind2, "count": self.__count }
self.__queries.columns = self.__columns
elif name == "dump_table":
self.__dumpTable = {}
self.__dumpTable["inband"] = { "query": self.__inband }
self.__dumpTable["blind"] = { "query": self.__blind, "count": self.__count }
self.__queries.dumpTable = self.__dumpTable
def queriesParser():
"""
This function calls a class to parse the default DBMS queries
from an XML file
"""
debugMsg = "parsing XML queries file"
logger.debug(debugMsg)
xmlfile = paths.QUERIES_XML
checkFile(xmlfile)
handler = queriesHandler()
parse(xmlfile, handler)