mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2024-11-25 19:13:48 +03:00
minor refactoring, added possibility to compare the remote file and downloaded file (--file-read), prepping for #223
This commit is contained in:
parent
9a1eca20b5
commit
8d9aa2c384
|
@ -343,7 +343,7 @@ class Filesystem(GenericFilesystem):
|
||||||
|
|
||||||
self._stackedWriteFileVbs(tmpPath, wFileContent, dFile, fileType)
|
self._stackedWriteFileVbs(tmpPath, wFileContent, dFile, fileType)
|
||||||
|
|
||||||
sameFile = self.askCheckWrittenFile(wFile, dFile, fileType)
|
sameFile = self.askCheckWrittenFile(wFile, dFile)
|
||||||
|
|
||||||
if sameFile is False:
|
if sameFile is False:
|
||||||
message = "do you want to try to upload the file with "
|
message = "do you want to try to upload the file with "
|
||||||
|
@ -353,3 +353,4 @@ 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)
|
||||||
|
|
|
@ -100,7 +100,7 @@ class Filesystem(GenericFilesystem):
|
||||||
sqlQuery = "%s INTO DUMPFILE '%s'" % (fcEncodedStr, dFile)
|
sqlQuery = "%s INTO DUMPFILE '%s'" % (fcEncodedStr, dFile)
|
||||||
unionUse(sqlQuery, unpack=False)
|
unionUse(sqlQuery, unpack=False)
|
||||||
|
|
||||||
self.askCheckWrittenFile(wFile, dFile, fileType)
|
self.askCheckWrittenFile(wFile, dFile)
|
||||||
|
|
||||||
warnMsg = "expect junk characters inside the "
|
warnMsg = "expect junk characters inside the "
|
||||||
warnMsg += "file as a leftover from UNION query"
|
warnMsg += "file as a leftover from UNION query"
|
||||||
|
@ -133,4 +133,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, fileType)
|
self.askCheckWrittenFile(wFile, dFile)
|
||||||
|
|
|
@ -110,6 +110,6 @@ 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, fileType)
|
self.askCheckWrittenFile(wFile, dFile)
|
||||||
|
|
||||||
inject.goStacked("SELECT lo_unlink(%d)" % self.oid)
|
inject.goStacked("SELECT lo_unlink(%d)" % self.oid)
|
||||||
|
|
|
@ -36,40 +36,44 @@ class Filesystem:
|
||||||
self.fileTblName = "sqlmapfile"
|
self.fileTblName = "sqlmapfile"
|
||||||
self.tblField = "data"
|
self.tblField = "data"
|
||||||
|
|
||||||
def _checkWrittenFile(self, wFile, dFile, fileType):
|
def _checkFileLength(self, localFile, remoteFile, fileRead=False):
|
||||||
if Backend.isDbms(DBMS.MYSQL):
|
if Backend.isDbms(DBMS.MYSQL):
|
||||||
lengthQuery = "SELECT LENGTH(LOAD_FILE('%s'))" % dFile
|
lengthQuery = "SELECT LENGTH(LOAD_FILE('%s'))" % remoteFile
|
||||||
|
|
||||||
elif Backend.isDbms(DBMS.PGSQL):
|
elif Backend.isDbms(DBMS.PGSQL):
|
||||||
|
if fileRead:
|
||||||
|
lengthQuery = True
|
||||||
|
else:
|
||||||
lengthQuery = "SELECT LENGTH(data) FROM pg_largeobject WHERE loid=%d" % self.oid
|
lengthQuery = "SELECT LENGTH(data) FROM pg_largeobject WHERE loid=%d" % self.oid
|
||||||
|
|
||||||
elif Backend.isDbms(DBMS.MSSQL):
|
elif Backend.isDbms(DBMS.MSSQL):
|
||||||
self.createSupportTbl(self.fileTblName, self.tblField, "text")
|
self.createSupportTbl(self.fileTblName, self.tblField, "text")
|
||||||
|
|
||||||
# Reference: http://msdn.microsoft.com/en-us/library/ms188365.aspx
|
# Reference: http://msdn.microsoft.com/en-us/library/ms188365.aspx
|
||||||
inject.goStacked("BULK INSERT %s FROM '%s' WITH (CODEPAGE='RAW', FIELDTERMINATOR='%s', ROWTERMINATOR='%s')" % (self.fileTblName, dFile, randomStr(10), randomStr(10)))
|
inject.goStacked("BULK INSERT %s FROM '%s' WITH (CODEPAGE='RAW', FIELDTERMINATOR='%s', ROWTERMINATOR='%s')" % (self.fileTblName, remoteFile, randomStr(10), randomStr(10)))
|
||||||
|
|
||||||
lengthQuery = "SELECT DATALENGTH(%s) FROM %s" % (self.tblField, self.fileTblName)
|
lengthQuery = "SELECT DATALENGTH(%s) FROM %s" % (self.tblField, self.fileTblName)
|
||||||
|
|
||||||
wFileSize = os.path.getsize(wFile)
|
localFileSize = os.path.getsize(localFile)
|
||||||
|
|
||||||
logger.debug("checking if the %s file has been written" % fileType)
|
logger.debug("checking the length of the remote file %s" % remoteFile)
|
||||||
dFileSize = inject.getValue(lengthQuery, resumeValue=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)
|
remoteFileSize = inject.getValue(lengthQuery, resumeValue=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)
|
||||||
sameFile = None
|
sameFile = None
|
||||||
|
|
||||||
if isNumPosStrValue(dFileSize):
|
if isNumPosStrValue(remoteFileSize):
|
||||||
infoMsg = "the file has been successfully written and "
|
remoteFileSize = long(remoteFileSize)
|
||||||
infoMsg += "its size is %s bytes" % dFileSize
|
|
||||||
|
|
||||||
dFileSize = long(dFileSize)
|
|
||||||
|
|
||||||
if wFileSize == dFileSize:
|
|
||||||
sameFile = True
|
|
||||||
infoMsg += ", same size as the local file '%s'" % wFile
|
|
||||||
else:
|
|
||||||
sameFile = False
|
sameFile = False
|
||||||
|
|
||||||
|
if localFileSize == remoteFileSize:
|
||||||
|
sameFile = True
|
||||||
|
infoMsg = "the local file %s and the remote file " % localFile
|
||||||
|
infoMsg += "%s have the same size" % remoteFile
|
||||||
|
elif remoteFileSize > localFileSize:
|
||||||
|
infoMsg = "the remote file %s is larger than " % remoteFile
|
||||||
|
infoMsg += "the local file %s" % localFile
|
||||||
|
else:
|
||||||
infoMsg += ", but the size differs from the local "
|
infoMsg += ", but the size differs from the local "
|
||||||
infoMsg += "file '%s' (%d bytes)" % (wFile, wFileSize)
|
infoMsg += "file '%s' (%d bytes)" % (localFile, localFileSize)
|
||||||
|
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
else:
|
else:
|
||||||
|
@ -133,38 +137,49 @@ class Filesystem:
|
||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
def askCheckWrittenFile(self, wFile, dFile, fileType):
|
def askCheckWrittenFile(self, localFile, remoteFile):
|
||||||
message = "do you want confirmation that the file '%s' " % dFile
|
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? [Y/n] "
|
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"):
|
if not output or output in ("y", "Y"):
|
||||||
return self._checkWrittenFile(wFile, dFile, fileType)
|
return self._checkFileLength(localFile, remoteFile)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def nonStackedReadFile(self, rFile):
|
def askCheckReadFile(self, localFile, remoteFile):
|
||||||
|
message = "do you want confirmation that the remote file '%s' " % remoteFile
|
||||||
|
message += "has been successfully downloaded from the back-end "
|
||||||
|
message += "DBMS file system? [Y/n] "
|
||||||
|
output = readInput(message, default="Y")
|
||||||
|
|
||||||
|
if not output or output in ("y", "Y"):
|
||||||
|
return self._checkFileLength(localFile, remoteFile, True)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def nonStackedReadFile(self, remoteFile):
|
||||||
errMsg = "'nonStackedReadFile' method must be defined "
|
errMsg = "'nonStackedReadFile' method must be defined "
|
||||||
errMsg += "into the specific DBMS plugin"
|
errMsg += "into the specific DBMS plugin"
|
||||||
raise SqlmapUndefinedMethod, errMsg
|
raise SqlmapUndefinedMethod, errMsg
|
||||||
|
|
||||||
def stackedReadFile(self, rFile):
|
def stackedReadFile(self, remoteFile):
|
||||||
errMsg = "'stackedReadFile' method must be defined "
|
errMsg = "'stackedReadFile' method must be defined "
|
||||||
errMsg += "into the specific DBMS plugin"
|
errMsg += "into the specific DBMS plugin"
|
||||||
raise SqlmapUndefinedMethod, errMsg
|
raise SqlmapUndefinedMethod, errMsg
|
||||||
|
|
||||||
def unionWriteFile(self, wFile, dFile, fileType):
|
def unionWriteFile(self, localFile, remoteFile, fileType):
|
||||||
errMsg = "'unionWriteFile' method must be defined "
|
errMsg = "'unionWriteFile' method must be defined "
|
||||||
errMsg += "into the specific DBMS plugin"
|
errMsg += "into the specific DBMS plugin"
|
||||||
raise SqlmapUndefinedMethod, errMsg
|
raise SqlmapUndefinedMethod, errMsg
|
||||||
|
|
||||||
def stackedWriteFile(self, wFile, dFile, fileType):
|
def stackedWriteFile(self, localFile, remoteFile, fileType):
|
||||||
errMsg = "'stackedWriteFile' method must be defined "
|
errMsg = "'stackedWriteFile' method must be defined "
|
||||||
errMsg += "into the specific DBMS plugin"
|
errMsg += "into the specific DBMS plugin"
|
||||||
raise SqlmapUndefinedMethod, errMsg
|
raise SqlmapUndefinedMethod, errMsg
|
||||||
|
|
||||||
def readFile(self, rFile):
|
def readFile(self, remoteFile):
|
||||||
fileContent = None
|
fileContent = None
|
||||||
|
|
||||||
self.checkDbmsOs()
|
self.checkDbmsOs()
|
||||||
|
@ -177,13 +192,13 @@ class Filesystem:
|
||||||
debugMsg += "injection technique"
|
debugMsg += "injection technique"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
fileContent = self.stackedReadFile(rFile)
|
fileContent = self.stackedReadFile(remoteFile)
|
||||||
elif Backend.isDbms(DBMS.MYSQL):
|
elif Backend.isDbms(DBMS.MYSQL):
|
||||||
debugMsg = "going to read the file with a non-stacked query "
|
debugMsg = "going to read the file with a non-stacked query "
|
||||||
debugMsg += "SQL injection technique"
|
debugMsg += "SQL injection technique"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
fileContent = self.nonStackedReadFile(rFile)
|
fileContent = self.nonStackedReadFile(remoteFile)
|
||||||
else:
|
else:
|
||||||
errMsg = "none of the SQL injection techniques detected can "
|
errMsg = "none of the SQL injection techniques detected can "
|
||||||
errMsg += "be used to read files from the underlying file "
|
errMsg += "be used to read files from the underlying file "
|
||||||
|
@ -214,14 +229,16 @@ class Filesystem:
|
||||||
fileContent = newFileContent
|
fileContent = newFileContent
|
||||||
|
|
||||||
fileContent = decodeHexValue(fileContent)
|
fileContent = decodeHexValue(fileContent)
|
||||||
rFilePath = dataToOutFile(fileContent)
|
remoteFilePath = dataToOutFile(fileContent)
|
||||||
|
|
||||||
if not Backend.isDbms(DBMS.PGSQL):
|
if not Backend.isDbms(DBMS.PGSQL):
|
||||||
self.cleanup(onlyFileTbl=True)
|
self.cleanup(onlyFileTbl=True)
|
||||||
|
|
||||||
return rFilePath
|
self.askCheckReadFile(remoteFilePath, remoteFile)
|
||||||
|
|
||||||
def writeFile(self, wFile, dFile, fileType=None):
|
return remoteFilePath
|
||||||
|
|
||||||
|
def writeFile(self, localFile, remoteFile, fileType=None):
|
||||||
self.checkDbmsOs()
|
self.checkDbmsOs()
|
||||||
|
|
||||||
if conf.direct or isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED):
|
if conf.direct or isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED):
|
||||||
|
@ -230,14 +247,14 @@ class Filesystem:
|
||||||
debugMsg += "stacked query SQL injection technique"
|
debugMsg += "stacked query SQL injection technique"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
self.stackedWriteFile(wFile, dFile, fileType)
|
self.stackedWriteFile(localFile, remoteFile, fileType)
|
||||||
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
|
||||||
debugMsg += "UNION query SQL injection technique"
|
debugMsg += "UNION query SQL injection technique"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
self.unionWriteFile(wFile, dFile, fileType)
|
self.unionWriteFile(localFile, remoteFile, fileType)
|
||||||
else:
|
else:
|
||||||
errMsg = "none of the SQL injection techniques detected can "
|
errMsg = "none of the SQL injection techniques detected can "
|
||||||
errMsg += "be used to write files to the underlying file "
|
errMsg += "be used to write files to the underlying file "
|
||||||
|
|
Loading…
Reference in New Issue
Block a user