Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions data/txt/sha256sums.txt
Original file line number Diff line number Diff line change
Expand Up @@ -167,32 +167,32 @@ d69e84f1648cdb907f5d2dd454f03874a4613752b07867510145d51d84b3c56f lib/controller
1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/controller/__init__.py
9e694e4864d865c5da745aaf9d35da885eff697a9a0f7b37c3e85d47b4378f64 lib/core/agent.py
b13462712ec5ac07541dba98631ddcda279d210b838f363d15ac97a1413b67a2 lib/core/bigarray.py
91a1257c761b560bf00c9b94a6838c6dcb7aef2a24c85eb8fd67a41b980c0d75 lib/core/common.py
03a144d63d7fdd2c0124f8b51e0af3e94455596153d11425d516bc13165f2962 lib/core/common.py
a6397b10de7ae7c56ed6b0fa3b3c58eb7a9dbede61bf93d786e73258175c981e lib/core/compat.py
a9997e97ebe88e0bf7efcf21e878bc5f62c72348e5aba18f64d6861390a4dcf2 lib/core/convert.py
c03dc585f89642cfd81b087ac2723e3e1bb3bfa8c60e6f5fe58ef3b0113ebfe6 lib/core/data.py
6acb645b1f285b21673c70824b03f6209acc5993b50e50da5ed2c713a30626f5 lib/core/datatype.py
70fb2528e580b22564899595b0dff6b1bc257c6a99d2022ce3996a3d04e68e4e lib/core/decorators.py
147823c37596bd6a56d677697781f34b8d1d1671d5a2518fbc9468d623c6d07d lib/core/defaults.py
2f44a1bfe6f18aafe64147b99e69aa93cf438c0e7befe59f4e2aee9065c8b7b6 lib/core/dicts.py
a033f92d136c707a25927c2383125ddb004d4283db62c004dcd67c3fc242bb1c lib/core/dump.py
ccd3b414727ef75f5d533f9518198b61322781f3ee53a86643763e029b2874c0 lib/core/dump.py
23e33f0b457e2a7114c9171ba9b42e1751b71ee3f384bba7fad39e4490adb803 lib/core/enums.py
5387168e5dfedd94ae22af7bb255f27d6baaca50b24179c6b98f4f325f5cc7b4 lib/core/exception.py
1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/core/__init__.py
914a13ee21fd610a6153a37cbe50830fcbd1324c7ebc1e7fc206d5e598b0f7ad lib/core/log.py
67ea32c993cbf23cdbd5170360c020ca33363b7c516ff3f8da4124ef7cb0254d lib/core/optiondict.py
226c01e46050ff48122df682f713565509a386e58d06cc43da59d028e0afc2fd lib/core/option.py
d197388e8e2aabe19f2529bfcac780e18e22a905d01319080d7afe4cb2b1c4c9 lib/core/option.py
789320dcb3f93137d3065080ee98429280bf10b20b66a1c08d3fcc1747b30d94 lib/core/patch.py
49c0fa7e3814dfda610d665ee02b12df299b28bc0b6773815b4395514ddf8dec lib/core/profiling.py
03db48f02c3d07a047ddb8fe33a757b6238867352d8ddda2a83e4fec09a98d04 lib/core/readlineng.py
48797d6c34dd9bb8a53f7f3794c85f4288d82a9a1d6be7fcf317d388cb20d4b3 lib/core/replication.py
0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py
888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py
9af9eabb33938e0c1fed05afa5699fab047b3cb0ab7c61fc2d471ee41df1d4dd lib/core/settings.py
6100d11481db84a8942f451b2292a6ff14ae34c0f1132df23ed90975da5a1180 lib/core/settings.py
cd5a66deee8963ba8e7e9af3dd36eb5e8127d4d68698811c29e789655f507f82 lib/core/shell.py
bcb5d8090d5e3e0ef2a586ba09ba80eef0c6d51feb0f611ed25299fbb254f725 lib/core/subprocessng.py
70ea3768f1b3062b22d20644df41c86238157ec80dd43da40545c620714273c6 lib/core/target.py
ddf8c5a3dbebd6cdf8b8ba4417e36652d1e040f025175cb6487f1aebc0208836 lib/core/testing.py
7f7d1c57917f6ccc98e2ef093e2fa4cb6424d904c772b61003d5a5a3482a848f lib/core/testing.py
b5b65f018d6ef4b1ceeebbc50d372e07d4733267c9f3f4b13062efd065e847b6 lib/core/threads.py
b9aacb840310173202f79c2ba125b0243003ee6b44c92eca50424f2bdfc83c02 lib/core/unescaper.py
10719f5ca450610ad28242017b2d8a77354ca357ffa26948c5f62d20cac29a8b lib/core/update.py
Expand Down Expand Up @@ -241,7 +241,7 @@ f552b6140d4069be6a44792a08f295da8adabc1c4bb6a5e100f222f87144ca9d lib/techniques
1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/union/__init__.py
30cae858e2a5a75b40854399f65ad074e6bb808d56d5ee66b94d4002dc6e101b lib/techniques/union/test.py
a8a795f29ec6fd66482926f04b054ed492a033982c3b7837c5d2ea32368acec0 lib/techniques/union/use.py
67dff80a17503b91c8ff93788ccc037b6695aa18b0793894b42488cbb21c4c83 lib/utils/api.py
f8c30ed8e79f93a6b5535e2d8977b9c10bdc10142418760213f8a2548bf199ad lib/utils/api.py
ea5e14f8c9d74b0fb17026b14e3fb70ee90e4046e51ab2c16652d86b3ca9b949 lib/utils/brute.py
da5bcbcda3f667582adf5db8c1b5d511b469ac61b55d387cec66de35720ed718 lib/utils/crawler.py
a94958be0ec3e9d28d8171813a6a90655a9ad7e6aa33c661e8d8ebbfcf208dbb lib/utils/deps.py
Expand Down
26 changes: 26 additions & 0 deletions lib/core/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import copy
import functools
import getpass
import hmac
import hashlib
import inspect
import io
Expand Down Expand Up @@ -5654,3 +5655,28 @@ def checkSums():
break

return retVal

def safeCompareStrings(a, b):
"""
Constant-time string comparison to prevent timing attacks.
>>> safeCompareStrings("test", "test")
True
>>> safeCompareStrings("test", None)
False
>>> safeCompareStrings("test1", "test2")
False
"""
if a is None or b is None:
return a == b

if hasattr(hmac, "compare_digest"):
return hmac.compare_digest(a, b)

# Fallback for Python < 2.7.7 and < 3.3
if len(a) != len(b):
return False

result = 0
for x, y in zip(a, b):
result |= ord(x) ^ ord(y)
return result == 0
27 changes: 13 additions & 14 deletions lib/core/dump.py
Original file line number Diff line number Diff line change
Expand Up @@ -410,14 +410,17 @@ def dbTableValues(self, tableValues):
db = "All"
table = tableValues["__infos__"]["table"]

safeDb = re.sub(r"[^\w]", UNSAFE_DUMP_FILEPATH_REPLACEMENT, unsafeSQLIdentificatorNaming(db))
safeTable = re.sub(r"[^\w]", UNSAFE_DUMP_FILEPATH_REPLACEMENT, unsafeSQLIdentificatorNaming(table))

if conf.api:
self._write(tableValues, content_type=CONTENT_TYPE.DUMP_TABLE)

try:
dumpDbPath = os.path.join(conf.dumpPath, unsafeSQLIdentificatorNaming(db))
dumpDbPath = os.path.join(conf.dumpPath, safeDb)
except UnicodeError:
try:
dumpDbPath = os.path.join(conf.dumpPath, normalizeUnicode(unsafeSQLIdentificatorNaming(db)))
dumpDbPath = os.path.join(conf.dumpPath, normalizeUnicode(safeDb))
except (UnicodeError, OSError):
tempDir = tempfile.mkdtemp(prefix="sqlmapdb")
warnMsg = "currently unable to use regular dump directory. "
Expand All @@ -427,16 +430,14 @@ def dbTableValues(self, tableValues):
dumpDbPath = tempDir

if conf.dumpFormat == DUMP_FORMAT.SQLITE:
replication = Replication(os.path.join(conf.dumpPath, "%s.sqlite3" % unsafeSQLIdentificatorNaming(db)))
replication = Replication(os.path.join(conf.dumpPath, "%s.sqlite3" % safeDb))
elif conf.dumpFormat in (DUMP_FORMAT.CSV, DUMP_FORMAT.HTML):
if not os.path.isdir(dumpDbPath):
try:
os.makedirs(dumpDbPath)
except:
warnFile = True

_ = re.sub(r"[^\w]", UNSAFE_DUMP_FILEPATH_REPLACEMENT, unsafeSQLIdentificatorNaming(db))
dumpDbPath = os.path.join(conf.dumpPath, "%s-%s" % (_, hashlib.md5(getBytes(db)).hexdigest()[:8]))
dumpDbPath = os.path.join(conf.dumpPath, "%s-%s" % (safeDb, hashlib.md5(getBytes(db)).hexdigest()[:8]))

if not os.path.isdir(dumpDbPath):
try:
Expand All @@ -450,21 +451,19 @@ def dbTableValues(self, tableValues):

dumpDbPath = tempDir

dumpFileName = conf.dumpFile or os.path.join(dumpDbPath, re.sub(r'[\\/]', UNSAFE_DUMP_FILEPATH_REPLACEMENT, "%s.%s" % (unsafeSQLIdentificatorNaming(table), conf.dumpFormat.lower())))
dumpFileName = conf.dumpFile or os.path.join(dumpDbPath, "%s.%s" % (safeTable, conf.dumpFormat.lower()))

if not checkFile(dumpFileName, False):
try:
openFile(dumpFileName, "w+").close()
except SqlmapSystemException:
raise
except:
warnFile = True

_ = re.sub(r"[^\w]", UNSAFE_DUMP_FILEPATH_REPLACEMENT, normalizeUnicode(unsafeSQLIdentificatorNaming(table)))
if len(_) < len(table) or IS_WIN and table.upper() in WINDOWS_RESERVED_NAMES:
_ = re.sub(r"[^\w]", UNSAFE_DUMP_FILEPATH_REPLACEMENT, unsafeSQLIdentificatorNaming(table))
dumpFileName = os.path.join(dumpDbPath, "%s-%s.%s" % (_, hashlib.md5(getBytes(table)).hexdigest()[:8], conf.dumpFormat.lower()))
if IS_WIN and safeTable.upper() in WINDOWS_RESERVED_NAMES:
dumpFileName = os.path.join(dumpDbPath, "%s-%s.%s" % (safeTable, hashlib.md5(getBytes(table)).hexdigest()[:8], conf.dumpFormat.lower()))
else:
dumpFileName = os.path.join(dumpDbPath, "%s.%s" % (_, conf.dumpFormat.lower()))
dumpFileName = os.path.join(dumpDbPath, "%s.%s" % (safeTable, conf.dumpFormat.lower()))
else:
appendToFile = any((conf.limitStart, conf.limitStop))

Expand Down Expand Up @@ -548,7 +547,7 @@ def dbTableValues(self, tableValues):
dataToDumpFile(dumpFP, "<!DOCTYPE html>\n<html>\n<head>\n")
dataToDumpFile(dumpFP, "<meta http-equiv=\"Content-type\" content=\"text/html;charset=%s\">\n" % UNICODE_ENCODING)
dataToDumpFile(dumpFP, "<meta name=\"generator\" content=\"%s\" />\n" % VERSION_STRING)
dataToDumpFile(dumpFP, "<title>%s</title>\n" % ("%s%s" % ("%s." % db if METADB_SUFFIX not in db else "", table)))
dataToDumpFile(dumpFP, "<title>%s</title>\n" % ("%s%s" % ("%s." % db if METADB_SUFFIX not in db else "", table)).replace("<", ""))
dataToDumpFile(dumpFP, HTML_DUMP_CSS_STYLE)
dataToDumpFile(dumpFP, "\n</head>\n<body>\n<table>\n<thead>\n<tr>\n")

Expand Down
7 changes: 7 additions & 0 deletions lib/core/option.py
Original file line number Diff line number Diff line change
Expand Up @@ -2678,6 +2678,13 @@ def _basicOptionValidation():
errMsg += "'SQLMAP_UNSAFE_ALERT=1' to be explicitly set"
raise SqlmapSystemException(errMsg)

if conf.evalCode and os.environ.get("SQLMAP_UNSAFE_EVAL") != '1':
errMsg = "for security reasons, to prevent execution of potentially malicious "
errMsg += "Python code via configuration files or copy-paste attacks, "
errMsg += "the '--eval' option requires the environment variable "
errMsg += "'SQLMAP_UNSAFE_EVAL=1' to be explicitly set"
raise SqlmapSystemException(errMsg)

if conf.chunked and not any((conf.data, conf.requestFile, conf.forms)):
errMsg = "switch '--chunked' requires usage of (POST) options/switches '--data', '-r' or '--forms'"
raise SqlmapSyntaxException(errMsg)
Expand Down
4 changes: 2 additions & 2 deletions lib/core/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from thirdparty import six

# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
VERSION = "1.10.4.4"
VERSION = "1.10.4.11"
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)
Expand Down Expand Up @@ -847,7 +847,7 @@
RESTAPI_DEFAULT_PORT = 8775

# Unsupported options by REST-JSON API server
RESTAPI_UNSUPPORTED_OPTIONS = ("sqlShell", "wizard")
RESTAPI_UNSUPPORTED_OPTIONS = ("sqlShell", "wizard", "evalCode", "alert")

# Use "Supplementary Private Use Area-A"
INVALID_UNICODE_PRIVATE_AREA = False
Expand Down
2 changes: 2 additions & 0 deletions lib/core/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,8 @@ def _thread():
os.close(handle)
cmd = cmd.replace("<tmpfile>", tmp)

os.environ["SQLMAP_UNSAFE_EVAL"] = '1'

output = shellExec(cmd)

if not all((check in output if not check.startswith('~') else check[1:] not in output) for check in checks) or "unhandled exception" in output:
Expand Down
2 changes: 1 addition & 1 deletion lib/utils/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ def setRestAPILog():

# Generic functions
def is_admin(token):
return DataStore.admin_token == token
return safeCompareStrings(DataStore.admin_token, token)

@hook('before_request')
def check_authentication():
Expand Down