mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2024-11-22 09:36:35 +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)
|
||||
|
||||
sameFile = self.askCheckWrittenFile(wFile, dFile, fileType)
|
||||
sameFile = self.askCheckWrittenFile(wFile, dFile)
|
||||
|
||||
if sameFile is False:
|
||||
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":
|
||||
self._stackedWriteFileDebugExe(tmpPath, wFile, 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)
|
||||
unionUse(sqlQuery, unpack=False)
|
||||
|
||||
self.askCheckWrittenFile(wFile, dFile, fileType)
|
||||
self.askCheckWrittenFile(wFile, dFile)
|
||||
|
||||
warnMsg = "expect junk characters inside the "
|
||||
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
|
||||
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)
|
||||
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)
|
||||
|
|
|
@ -36,40 +36,44 @@ class Filesystem:
|
|||
self.fileTblName = "sqlmapfile"
|
||||
self.tblField = "data"
|
||||
|
||||
def _checkWrittenFile(self, wFile, dFile, fileType):
|
||||
def _checkFileLength(self, localFile, remoteFile, fileRead=False):
|
||||
if Backend.isDbms(DBMS.MYSQL):
|
||||
lengthQuery = "SELECT LENGTH(LOAD_FILE('%s'))" % dFile
|
||||
lengthQuery = "SELECT LENGTH(LOAD_FILE('%s'))" % remoteFile
|
||||
|
||||
elif Backend.isDbms(DBMS.PGSQL):
|
||||
if fileRead:
|
||||
lengthQuery = True
|
||||
else:
|
||||
lengthQuery = "SELECT LENGTH(data) FROM pg_largeobject WHERE loid=%d" % self.oid
|
||||
|
||||
elif Backend.isDbms(DBMS.MSSQL):
|
||||
self.createSupportTbl(self.fileTblName, self.tblField, "text")
|
||||
|
||||
# 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)
|
||||
|
||||
wFileSize = os.path.getsize(wFile)
|
||||
localFileSize = os.path.getsize(localFile)
|
||||
|
||||
logger.debug("checking if the %s file has been written" % fileType)
|
||||
dFileSize = inject.getValue(lengthQuery, resumeValue=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)
|
||||
logger.debug("checking the length of the remote file %s" % remoteFile)
|
||||
remoteFileSize = inject.getValue(lengthQuery, resumeValue=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)
|
||||
sameFile = None
|
||||
|
||||
if isNumPosStrValue(dFileSize):
|
||||
infoMsg = "the file has been successfully written and "
|
||||
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:
|
||||
if isNumPosStrValue(remoteFileSize):
|
||||
remoteFileSize = long(remoteFileSize)
|
||||
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 += "file '%s' (%d bytes)" % (wFile, wFileSize)
|
||||
infoMsg += "file '%s' (%d bytes)" % (localFile, localFileSize)
|
||||
|
||||
logger.info(infoMsg)
|
||||
else:
|
||||
|
@ -133,38 +137,49 @@ class Filesystem:
|
|||
|
||||
return retVal
|
||||
|
||||
def askCheckWrittenFile(self, wFile, dFile, fileType):
|
||||
message = "do you want confirmation that the file '%s' " % dFile
|
||||
def askCheckWrittenFile(self, localFile, remoteFile):
|
||||
message = "do you want confirmation that the local file '%s' " % localFile
|
||||
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")
|
||||
|
||||
if not output or output in ("y", "Y"):
|
||||
return self._checkWrittenFile(wFile, dFile, fileType)
|
||||
return self._checkFileLength(localFile, remoteFile)
|
||||
|
||||
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 += "into the specific DBMS plugin"
|
||||
raise SqlmapUndefinedMethod, errMsg
|
||||
|
||||
def stackedReadFile(self, rFile):
|
||||
def stackedReadFile(self, remoteFile):
|
||||
errMsg = "'stackedReadFile' method must be defined "
|
||||
errMsg += "into the specific DBMS plugin"
|
||||
raise SqlmapUndefinedMethod, errMsg
|
||||
|
||||
def unionWriteFile(self, wFile, dFile, fileType):
|
||||
def unionWriteFile(self, localFile, remoteFile, fileType):
|
||||
errMsg = "'unionWriteFile' method must be defined "
|
||||
errMsg += "into the specific DBMS plugin"
|
||||
raise SqlmapUndefinedMethod, errMsg
|
||||
|
||||
def stackedWriteFile(self, wFile, dFile, fileType):
|
||||
def stackedWriteFile(self, localFile, remoteFile, fileType):
|
||||
errMsg = "'stackedWriteFile' method must be defined "
|
||||
errMsg += "into the specific DBMS plugin"
|
||||
raise SqlmapUndefinedMethod, errMsg
|
||||
|
||||
def readFile(self, rFile):
|
||||
def readFile(self, remoteFile):
|
||||
fileContent = None
|
||||
|
||||
self.checkDbmsOs()
|
||||
|
@ -177,13 +192,13 @@ class Filesystem:
|
|||
debugMsg += "injection technique"
|
||||
logger.debug(debugMsg)
|
||||
|
||||
fileContent = self.stackedReadFile(rFile)
|
||||
fileContent = self.stackedReadFile(remoteFile)
|
||||
elif Backend.isDbms(DBMS.MYSQL):
|
||||
debugMsg = "going to read the file with a non-stacked query "
|
||||
debugMsg += "SQL injection technique"
|
||||
logger.debug(debugMsg)
|
||||
|
||||
fileContent = self.nonStackedReadFile(rFile)
|
||||
fileContent = self.nonStackedReadFile(remoteFile)
|
||||
else:
|
||||
errMsg = "none of the SQL injection techniques detected can "
|
||||
errMsg += "be used to read files from the underlying file "
|
||||
|
@ -214,14 +229,16 @@ class Filesystem:
|
|||
fileContent = newFileContent
|
||||
|
||||
fileContent = decodeHexValue(fileContent)
|
||||
rFilePath = dataToOutFile(fileContent)
|
||||
remoteFilePath = dataToOutFile(fileContent)
|
||||
|
||||
if not Backend.isDbms(DBMS.PGSQL):
|
||||
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()
|
||||
|
||||
if conf.direct or isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED):
|
||||
|
@ -230,14 +247,14 @@ class Filesystem:
|
|||
debugMsg += "stacked query SQL injection technique"
|
||||
logger.debug(debugMsg)
|
||||
|
||||
self.stackedWriteFile(wFile, dFile, fileType)
|
||||
self.stackedWriteFile(localFile, remoteFile, fileType)
|
||||
self.cleanup(onlyFileTbl=True)
|
||||
elif isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) and Backend.isDbms(DBMS.MYSQL):
|
||||
debugMsg = "going to upload the %s file with " % fileType
|
||||
debugMsg += "UNION query SQL injection technique"
|
||||
logger.debug(debugMsg)
|
||||
|
||||
self.unionWriteFile(wFile, dFile, fileType)
|
||||
self.unionWriteFile(localFile, remoteFile, fileType)
|
||||
else:
|
||||
errMsg = "none of the SQL injection techniques detected can "
|
||||
errMsg += "be used to write files to the underlying file "
|
||||
|
|
Loading…
Reference in New Issue
Block a user