diff --git a/lib/core/settings.py b/lib/core/settings.py index bca1cb83f..fed08b686 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.9.31" +VERSION = "1.10.9.32" TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable" TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34} VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE) diff --git a/lib/core/target.py b/lib/core/target.py index c39364b03..f61cd56ea 100644 --- a/lib/core/target.py +++ b/lib/core/target.py @@ -666,8 +666,12 @@ def _createFilesDir(): if not any((conf.fileRead, conf.commonFiles, conf.xxe)): return - # Note: normalize the hostname consistently with conf.outputPath / conf.dumpPath (see _createDumpDir) - conf.filePath = paths.SQLMAP_FILES_PATH % normalizeUnicode(getUnicode(conf.hostname)) + # Note: normalize the hostname consistently with conf.outputPath / conf.dumpPath (see _createDumpDir). + # safeStringFormat() (not raw '%') because SQLMAP_FILES_PATH embeds SQLMAP_OUTPUT_PATH, which comes + # straight from --output-dir - a literal '%' anywhere in that user-supplied path (e.g. an unexpanded + # '$(date +%Y%m%d)' on a shell that doesn't support command substitution) would otherwise make the + # '%' operator try to parse it as a format directive and crash + conf.filePath = safeStringFormat(paths.SQLMAP_FILES_PATH, normalizeUnicode(getUnicode(conf.hostname))) if not os.path.isdir(conf.filePath): try: diff --git a/tests/test_target_parsing.py b/tests/test_target_parsing.py index da43993ca..7a3c778da 100644 --- a/tests/test_target_parsing.py +++ b/tests/test_target_parsing.py @@ -483,6 +483,18 @@ class TestCreateDirs(_TargetTestBase): self.assertTrue(os.path.isdir(conf.filePath)) self.assertIn("example.com", conf.filePath) + def test_files_dir_survives_percent_in_output_dir(self): + # --output-dir carries a literal '%' straight into SQLMAP_FILES_PATH (e.g. an unexpanded + # '$(date +%Y%m%d)' on a shell without command substitution, as in #6133) - the '%' operator + # would try to parse '%Y' as a format directive and crash; safeStringFormat() must not + self._outdir("f_out_%Y%m%d_%H%M%S") + conf.hostname = "example.com" + conf.fileRead = "/etc/passwd" + conf.commonFiles = None + _createFilesDir() + self.assertTrue(os.path.isdir(conf.filePath)) + self.assertIn("example.com", conf.filePath) + def test_target_dir_and_target_txt(self): self._outdir("t_out") conf.hostname = "example.com"