diff --git a/lib/controller/action.py b/lib/controller/action.py index 57bf2cd2c..a3cecf176 100644 --- a/lib/controller/action.py +++ b/lib/controller/action.py @@ -147,7 +147,7 @@ def action(): # File system options if conf.rFile: - conf.dumper.rFile(conf.rFile, conf.dbmsHandler.readFile(conf.rFile)) + conf.dumper.rFile(conf.dbmsHandler.readFile(conf.rFile)) if conf.wFile: conf.dbmsHandler.writeFile(conf.wFile, conf.dFile, conf.wFileType) diff --git a/lib/core/common.py b/lib/core/common.py index 56a838875..5037e9dcb 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -736,11 +736,11 @@ def dataToDumpFile(dumpFile, data): dumpFile.write(data) dumpFile.flush() -def dataToOutFile(data): +def dataToOutFile(filename, data): if not data: return "No data retrieved" - retVal = "%s%s%s" % (conf.filePath, os.sep, filePathToString(conf.rFile)) + retVal = "%s%s%s" % (conf.filePath, os.sep, filePathToString(filename)) with codecs.open(retVal, "wb") as f: f.write(data) diff --git a/lib/core/dump.py b/lib/core/dump.py index 72a1a0bb0..13eac6abd 100644 --- a/lib/core/dump.py +++ b/lib/core/dump.py @@ -19,6 +19,7 @@ from lib.core.common import isListLike from lib.core.common import normalizeUnicode from lib.core.common import openFile from lib.core.common import prioritySortColumns +from lib.core.common import randomInt from lib.core.common import safeCSValue from lib.core.common import unsafeSQLIdentificatorNaming from lib.core.data import conf @@ -34,6 +35,7 @@ from lib.core.settings import HTML_DUMP_CSS_STYLE from lib.core.settings import METADB_SUFFIX from lib.core.settings import TRIM_STDOUT_DUMP_SIZE from lib.core.settings import UNICODE_ENCODING +from thirdparty.magic import magic class Dump(object): """ @@ -476,6 +478,14 @@ class Dump(object): blank = " " * (maxlength - len(value)) self._write("| %s%s" % (value, blank), newline=False, console=console) + # TODO: this is related to issue #8, but it is not yet working + #mimetype = magic.from_buffer(value, mime=True) + + #if mimetype.startswith("application") or mimetype.startswith("image"): + # singleFP = open("%s%s%s" % (dumpDbPath, os.sep, "%s-%d.bin" % (column, randomInt(8))), "wb") + # singleFP.write(value.encode("utf8")) + # singleFP.close() + if conf.dumpFormat == DUMP_FORMAT.CSV: if field == fields: dataToDumpFile(dumpFP, "%s" % safeCSValue(value)) @@ -551,7 +561,7 @@ class Dump(object): def query(self, query, queryRes): self.string(query, queryRes) - def rFile(self, filePath, fileData): + def rFile(self, fileData): self.lister("files saved to", fileData, sort=False) def registerValue(self, registerData): diff --git a/lib/core/testing.py b/lib/core/testing.py index 7fc5c7b77..2b7895a72 100644 --- a/lib/core/testing.py +++ b/lib/core/testing.py @@ -228,15 +228,18 @@ def runCase(switches=None, parse=None): ifile = open(conf.dumper.getOutputFile(), "rb") content = ifile.read() ifile.close() + for item in parse: if item.startswith("r'") and item.endswith("'"): if not re.search(item[2:-1], content, re.DOTALL): retVal = False failedItem = item + break elif content.find(item) < 0: retVal = False failedItem = item + break cleanCase() diff --git a/plugins/generic/filesystem.py b/plugins/generic/filesystem.py index 98704220d..bd415e857 100644 --- a/plugins/generic/filesystem.py +++ b/plugins/generic/filesystem.py @@ -157,7 +157,7 @@ class Filesystem: if not output or output in ("y", "Y"): return self._checkFileLength(localFile, remoteFile, True) - return True + return None def nonStackedReadFile(self, remoteFile): errMsg = "'nonStackedReadFile' method must be defined " @@ -180,12 +180,12 @@ class Filesystem: raise SqlmapUndefinedMethod, errMsg def readFile(self, remoteFiles): - fileContent = None - remoteFilePaths = [] + localFilePaths = [] self.checkDbmsOs() for remoteFile in remoteFiles.split(","): + fileContent = None kb.fileReadMode = True if conf.direct or isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED): @@ -207,14 +207,12 @@ class Filesystem: errMsg += "system of the back-end %s server" % Backend.getDbms() logger.error(errMsg) - return None + fileContent = None kb.fileReadMode = False if fileContent in (None, "") and not Backend.isDbms(DBMS.PGSQL): self.cleanup(onlyFileTbl=True) - - return elif isListLike(fileContent): newFileContent = "" @@ -230,17 +228,23 @@ class Filesystem: fileContent = newFileContent - fileContent = decodeHexValue(fileContent) - remoteFilePath = dataToOutFile(fileContent) + if fileContent is not None: + fileContent = decodeHexValue(fileContent) + localFilePath = dataToOutFile(remoteFile, fileContent) - if not Backend.isDbms(DBMS.PGSQL): - self.cleanup(onlyFileTbl=True) + if not Backend.isDbms(DBMS.PGSQL): + self.cleanup(onlyFileTbl=True) - self.askCheckReadFile(remoteFilePath, remoteFile) + sameFile = self.askCheckReadFile(localFilePath, remoteFile) - remoteFilePaths.append(remoteFilePath) + if sameFile is True: + localFilePath += " (same file)" + elif sameFile is False: + localFilePath += " (size differs from remote file)" - return remoteFilePaths + localFilePaths.append(localFilePath) + + return localFilePaths def writeFile(self, localFile, remoteFile, fileType=None): self.checkDbmsOs()