mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-02-16 19:40:37 +03:00
fixes #187
This commit is contained in:
parent
f3ff239e62
commit
d8a0e7eacb
|
@ -15,6 +15,7 @@ from lib.core.data import conf
|
||||||
from lib.core.data import logger
|
from lib.core.data import logger
|
||||||
from lib.core.enums import DBMS
|
from lib.core.enums import DBMS
|
||||||
from lib.core.enums import PAYLOAD
|
from lib.core.enums import PAYLOAD
|
||||||
|
from lib.core.exception import SqlmapFilePathException
|
||||||
from lib.core.exception import SqlmapUnsupportedFeatureException
|
from lib.core.exception import SqlmapUnsupportedFeatureException
|
||||||
from lib.core.shell import autoCompletion
|
from lib.core.shell import autoCompletion
|
||||||
from lib.request import inject
|
from lib.request import inject
|
||||||
|
@ -195,7 +196,11 @@ class Abstraction(Web, UDF, Xp_cmdshell):
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL):
|
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL):
|
||||||
self.udfInjectSys()
|
success = self.udfInjectSys()
|
||||||
|
|
||||||
|
if success is not True:
|
||||||
|
msg = "unable to mount the operating system takeover"
|
||||||
|
raise SqlmapFilePathException(msg)
|
||||||
elif Backend.isDbms(DBMS.MSSQL):
|
elif Backend.isDbms(DBMS.MSSQL):
|
||||||
if mandatory:
|
if mandatory:
|
||||||
self.xpCmdshellInit()
|
self.xpCmdshellInit()
|
||||||
|
|
|
@ -137,6 +137,8 @@ class UDF:
|
||||||
raise SqlmapUnsupportedFeatureException(errMsg)
|
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||||
|
|
||||||
def udfInjectCore(self, udfDict):
|
def udfInjectCore(self, udfDict):
|
||||||
|
written = False
|
||||||
|
|
||||||
for udf in udfDict.keys():
|
for udf in udfDict.keys():
|
||||||
if udf in self.createdUdf:
|
if udf in self.createdUdf:
|
||||||
continue
|
continue
|
||||||
|
@ -145,7 +147,22 @@ class UDF:
|
||||||
|
|
||||||
if len(self.udfToCreate) > 0:
|
if len(self.udfToCreate) > 0:
|
||||||
self.udfSetRemotePath()
|
self.udfSetRemotePath()
|
||||||
self.writeFile(self.udfLocalFile, self.udfRemoteFile, "binary")
|
written = self.writeFile(self.udfLocalFile, self.udfRemoteFile, "binary", forceCheck=True)
|
||||||
|
|
||||||
|
if written is not True:
|
||||||
|
errMsg = "there has been a problem uploading the shared library, "
|
||||||
|
errMsg += "it looks like the binary file has not been written "
|
||||||
|
errMsg += "on the database underlying file system"
|
||||||
|
logger.error(errMsg)
|
||||||
|
|
||||||
|
message = "do you want to proceed anyway? Beware that the "
|
||||||
|
message += "operating system takeover will fail [y/N] "
|
||||||
|
choice = readInput(message, default="N")
|
||||||
|
|
||||||
|
if choice and choice.lower() == "y":
|
||||||
|
written = True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
for udf, inpRet in udfDict.items():
|
for udf, inpRet in udfDict.items():
|
||||||
if udf in self.udfToCreate and udf not in self.createdUdf:
|
if udf in self.udfToCreate and udf not in self.createdUdf:
|
||||||
|
@ -158,10 +175,12 @@ class UDF:
|
||||||
|
|
||||||
self.udfCreateSupportTbl(supportTblType)
|
self.udfCreateSupportTbl(supportTblType)
|
||||||
|
|
||||||
|
return written
|
||||||
|
|
||||||
def udfInjectSys(self):
|
def udfInjectSys(self):
|
||||||
self.udfSetLocalPaths()
|
self.udfSetLocalPaths()
|
||||||
self.udfCheckNeeded()
|
self.udfCheckNeeded()
|
||||||
self.udfInjectCore(self.sysUdfs)
|
return self.udfInjectCore(self.sysUdfs)
|
||||||
|
|
||||||
def udfInjectCustom(self):
|
def udfInjectCustom(self):
|
||||||
if Backend.getIdentifiedDbms() not in (DBMS.MYSQL, DBMS.PGSQL):
|
if Backend.getIdentifiedDbms() not in (DBMS.MYSQL, DBMS.PGSQL):
|
||||||
|
@ -297,7 +316,11 @@ class UDF:
|
||||||
self.udfs[udfName]["return"] = retType
|
self.udfs[udfName]["return"] = retType
|
||||||
break
|
break
|
||||||
|
|
||||||
self.udfInjectCore(self.udfs)
|
success = self.udfInjectCore(self.udfs)
|
||||||
|
|
||||||
|
if success is False:
|
||||||
|
self.cleanup(udfDict=self.udfs)
|
||||||
|
return False
|
||||||
|
|
||||||
msg = "do you want to call your injected user-defined "
|
msg = "do you want to call your injected user-defined "
|
||||||
msg += "functions now? [Y/n/q] "
|
msg += "functions now? [Y/n/q] "
|
||||||
|
|
|
@ -326,7 +326,7 @@ class Filesystem(GenericFilesystem):
|
||||||
|
|
||||||
self.execCmd(complComm)
|
self.execCmd(complComm)
|
||||||
|
|
||||||
def stackedWriteFile(self, wFile, dFile, fileType):
|
def stackedWriteFile(self, wFile, dFile, fileType, forceCheck=False):
|
||||||
# NOTE: this is needed here because we use xp_cmdshell extended
|
# NOTE: this is needed here because we use xp_cmdshell extended
|
||||||
# procedure to write a file on the back-end Microsoft SQL Server
|
# procedure to write a file on the back-end Microsoft SQL Server
|
||||||
# file system
|
# file system
|
||||||
|
@ -341,9 +341,9 @@ class Filesystem(GenericFilesystem):
|
||||||
|
|
||||||
self._stackedWriteFileVbs(tmpPath, wFileContent, dFile, fileType)
|
self._stackedWriteFileVbs(tmpPath, wFileContent, dFile, fileType)
|
||||||
|
|
||||||
sameFile = self.askCheckWrittenFile(wFile, dFile)
|
written = self.askCheckWrittenFile(wFile, dFile)
|
||||||
|
|
||||||
if sameFile is False:
|
if written is False:
|
||||||
message = "do you want to try to upload the file with "
|
message = "do you want to try to upload the file with "
|
||||||
message += "another technique? [Y/n] "
|
message += "another technique? [Y/n] "
|
||||||
choice = readInput(message, default="Y")
|
choice = readInput(message, default="Y")
|
||||||
|
@ -351,4 +351,6 @@ class Filesystem(GenericFilesystem):
|
||||||
if not choice or choice.lower() == "y":
|
if not choice or choice.lower() == "y":
|
||||||
self._stackedWriteFileDebugExe(tmpPath, wFile, wFileContent, dFile, fileType)
|
self._stackedWriteFileDebugExe(tmpPath, wFile, wFileContent, dFile, fileType)
|
||||||
#self._stackedWriteFilePS(tmpPath, wFileContent, dFile, fileType)
|
#self._stackedWriteFilePS(tmpPath, wFileContent, dFile, fileType)
|
||||||
self.askCheckWrittenFile(wFile, dFile)
|
written = self.askCheckWrittenFile(wFile, dFile, forceCheck)
|
||||||
|
|
||||||
|
return written
|
||||||
|
|
|
@ -104,7 +104,7 @@ class Filesystem(GenericFilesystem):
|
||||||
warnMsg += "file as a leftover from UNION query"
|
warnMsg += "file as a leftover from UNION query"
|
||||||
singleTimeWarnMessage(warnMsg)
|
singleTimeWarnMessage(warnMsg)
|
||||||
|
|
||||||
def stackedWriteFile(self, wFile, dFile, fileType):
|
def stackedWriteFile(self, wFile, dFile, fileType, forceCheck=False):
|
||||||
debugMsg = "creating a support table to write the hexadecimal "
|
debugMsg = "creating a support table to write the hexadecimal "
|
||||||
debugMsg += "encoded file to"
|
debugMsg += "encoded file to"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
@ -131,4 +131,4 @@ class Filesystem(GenericFilesystem):
|
||||||
# Reference: http://dev.mysql.com/doc/refman/5.1/en/select.html
|
# Reference: http://dev.mysql.com/doc/refman/5.1/en/select.html
|
||||||
inject.goStacked("SELECT %s FROM %s INTO DUMPFILE '%s'" % (self.tblField, self.fileTblName, dFile), silent=True)
|
inject.goStacked("SELECT %s FROM %s INTO DUMPFILE '%s'" % (self.tblField, self.fileTblName, dFile), silent=True)
|
||||||
|
|
||||||
self.askCheckWrittenFile(wFile, dFile)
|
return self.askCheckWrittenFile(wFile, dFile, forceCheck)
|
||||||
|
|
|
@ -33,7 +33,7 @@ class Filesystem(GenericFilesystem):
|
||||||
errMsg += "query SQL injection technique"
|
errMsg += "query SQL injection technique"
|
||||||
raise SqlmapUnsupportedFeatureException(errMsg)
|
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||||
|
|
||||||
def stackedWriteFile(self, wFile, dFile, fileType):
|
def stackedWriteFile(self, wFile, dFile, fileType, forceCheck=False):
|
||||||
wFileSize = os.path.getsize(wFile)
|
wFileSize = os.path.getsize(wFile)
|
||||||
|
|
||||||
if wFileSize > 8192:
|
if wFileSize > 8192:
|
||||||
|
@ -110,6 +110,8 @@ class Filesystem(GenericFilesystem):
|
||||||
# (pg_largeobject 'data' field)
|
# (pg_largeobject 'data' field)
|
||||||
inject.goStacked("SELECT lo_export(%d, '%s')" % (self.oid, dFile), silent=True)
|
inject.goStacked("SELECT lo_export(%d, '%s')" % (self.oid, dFile), silent=True)
|
||||||
|
|
||||||
self.askCheckWrittenFile(wFile, dFile)
|
written = self.askCheckWrittenFile(wFile, dFile, forceCheck)
|
||||||
|
|
||||||
inject.goStacked("SELECT lo_unlink(%d)" % self.oid)
|
inject.goStacked("SELECT lo_unlink(%d)" % self.oid)
|
||||||
|
|
||||||
|
return written
|
||||||
|
|
|
@ -135,13 +135,17 @@ class Filesystem:
|
||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
def askCheckWrittenFile(self, localFile, remoteFile):
|
def askCheckWrittenFile(self, localFile, remoteFile, forceCheck=False):
|
||||||
message = "do you want confirmation that the local file '%s' " % localFile
|
output = None
|
||||||
message += "has been successfully written on the back-end DBMS "
|
if forceCheck is not True:
|
||||||
message += "file system (%s)? [Y/n] " % remoteFile
|
message = "do you want confirmation that the local file '%s' " % localFile
|
||||||
output = readInput(message, default="Y")
|
message += "has been successfully written on the back-end DBMS "
|
||||||
|
message += "file system (%s)? [Y/n] " % remoteFile
|
||||||
|
output = readInput(message, default="Y")
|
||||||
|
|
||||||
if not output or output in ("y", "Y"):
|
readInput("press ENTER to continue :)")
|
||||||
|
|
||||||
|
if forceCheck or (not output or output in ("y", "Y")):
|
||||||
return self._checkFileLength(localFile, remoteFile)
|
return self._checkFileLength(localFile, remoteFile)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
@ -249,7 +253,9 @@ class Filesystem:
|
||||||
|
|
||||||
return localFilePaths
|
return localFilePaths
|
||||||
|
|
||||||
def writeFile(self, localFile, remoteFile, fileType=None):
|
def writeFile(self, localFile, remoteFile, fileType=None, forceCheck=False):
|
||||||
|
written = False
|
||||||
|
|
||||||
self.checkDbmsOs()
|
self.checkDbmsOs()
|
||||||
|
|
||||||
if localFile.endswith('_'):
|
if localFile.endswith('_'):
|
||||||
|
@ -261,7 +267,7 @@ class Filesystem:
|
||||||
debugMsg += "stacked query SQL injection technique"
|
debugMsg += "stacked query SQL injection technique"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
self.stackedWriteFile(localFile, remoteFile, fileType)
|
written = self.stackedWriteFile(localFile, remoteFile, fileType, forceCheck)
|
||||||
self.cleanup(onlyFileTbl=True)
|
self.cleanup(onlyFileTbl=True)
|
||||||
elif isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) and Backend.isDbms(DBMS.MYSQL):
|
elif isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) and Backend.isDbms(DBMS.MYSQL):
|
||||||
debugMsg = "going to upload the %s file with " % fileType
|
debugMsg = "going to upload the %s file with " % fileType
|
||||||
|
@ -276,3 +282,5 @@ class Filesystem:
|
||||||
logger.error(errMsg)
|
logger.error(errMsg)
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
return written
|
||||||
|
|
Loading…
Reference in New Issue
Block a user