mirror of
				https://github.com/sqlmapproject/sqlmap.git
				synced 2025-11-04 18:07:46 +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):
 | 
				
			||||||
 | 
					        output = None
 | 
				
			||||||
 | 
					        if forceCheck is not True:
 | 
				
			||||||
            message = "do you want confirmation that the local file '%s' " % localFile
 | 
					            message = "do you want confirmation that the local file '%s' " % localFile
 | 
				
			||||||
            message += "has been successfully written on the back-end DBMS "
 | 
					            message += "has been successfully written on the back-end DBMS "
 | 
				
			||||||
            message += "file system (%s)? [Y/n] " % remoteFile
 | 
					            message += "file system (%s)? [Y/n] " % remoteFile
 | 
				
			||||||
            output = readInput(message, default="Y")
 | 
					            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