mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-12-07 13:11:29 +00:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7584a67422 | ||
|
|
2358219631 | ||
|
|
cc245a0d05 | ||
|
|
10f8b7d0e2 | ||
|
|
4b2baa32c3 | ||
|
|
935afc6217 | ||
|
|
07b94ce703 | ||
|
|
77567da54e | ||
|
|
8b3425ccdf | ||
|
|
87cd5906f9 | ||
|
|
8fc166197d | ||
|
|
7bf9e3e7b4 | ||
|
|
282eea3743 |
@@ -166,7 +166,7 @@ f9c96cd3fe99578bed9d49a8bdf8d76836d320a7c48c56eb0469f48b36775c35 lib/controller
|
||||
99d0e94dd5fe60137abf48bfa051129fb251f5c40f0f7a270c89fbcb07323730 lib/controller/__init__.py
|
||||
826c33f1105be4c0985e1bbe1d75bdb009c17815ad6552fc8d9bf39090d3c40f lib/core/agent.py
|
||||
c2966ee914b98ba55c0e12b8f76e678245d08ff9b30f63c4456721ec3eff3918 lib/core/bigarray.py
|
||||
9e3c165eee6fbe2bc02f5e7301bca6633ff60894a5a8ec5b3622db2747bd5705 lib/core/common.py
|
||||
d4d550f55b9eb8c3a812e19f46319fb299b3d9549df54d5d14fc615aeaa38b0e lib/core/common.py
|
||||
5c26b0f308266bc3a9679ef837439e38d1dc7a69eac6bd3422280f49aaf114d2 lib/core/compat.py
|
||||
b60c96780cad4a257f91a0611b08cfcc52f242908c5d5ab2bf9034ef07869602 lib/core/convert.py
|
||||
5e381515873e71c395c77df00bf1dd8c4592afc6210a2f75cbc20daf384e539f lib/core/data.py
|
||||
@@ -181,18 +181,18 @@ e8f6f1df8814b7b03c3eba22901837555083f66c99ee93b943911de785736bfa lib/core/dicts
|
||||
99d0e94dd5fe60137abf48bfa051129fb251f5c40f0f7a270c89fbcb07323730 lib/core/__init__.py
|
||||
fce3fd4b161ec1c6e9d5bf1dca5bc4083e07d616ed2c14b798e96b60ec67c2b2 lib/core/log.py
|
||||
4caebf27d203673b8ad32394937397319f606c4e1f1e1a2a221402d39c644b40 lib/core/optiondict.py
|
||||
1171119f6289ab981e5912e73801fe1862c7c012bc1da577df5c6497f348a85e lib/core/option.py
|
||||
c727cf637840aa5c0970c45d27bb5b0d077751aee10a5cd467caf92a54a211f4 lib/core/option.py
|
||||
d2d81ee7520b55571923461a2bdfaa68dda74a89846761338408ab0acf08d3a5 lib/core/patch.py
|
||||
bf77f9fc4296f239687297aee1fd6113b34f855965a6f690b52e26bd348cb353 lib/core/profiling.py
|
||||
4ccce0d53f467166d4084c9ef53a07f54cc352e75f785454a31c8a820511a84e lib/core/readlineng.py
|
||||
4eff81c639a72b261c8ba1c876a01246e718e6626e8e77ae9cc6298b20a39355 lib/core/replication.py
|
||||
bbd1dcda835934728efc6d68686e9b0da72b09b3ee38f3c0ab78e8c18b0ba726 lib/core/revision.py
|
||||
eed6b0a21b3e69c5583133346b0639dc89937bd588887968ee85f8389d7c3c96 lib/core/session.py
|
||||
d21819319315ee0e2b686639f6ca426b5172d0105315a42b3d3f1a98d1f2e8ad lib/core/settings.py
|
||||
85fbc4937c4770c8ff41ebfff13abfcdbc1fda52fab8ce05568b3f6309bd4b35 lib/core/settings.py
|
||||
2bec97d8a950f7b884e31dfe9410467f00d24f21b35672b95f8d68ed59685fd4 lib/core/shell.py
|
||||
e90a359b37a55c446c60e70ccd533f87276714d0b09e34f69b0740fd729ddbf8 lib/core/subprocessng.py
|
||||
54f7c70b4c7a9931f7ff3c1c12030180bde38e35a306d5e343ad6052919974cd lib/core/target.py
|
||||
970b1c3e59481f11dd185bdde52f697f7d8dfc3152d24e3d336ec3fab59a857c lib/core/testing.py
|
||||
6d6a89be3746f07644b96c2c212745515fa43eab4d1bd0aecf1476249b1c7f07 lib/core/testing.py
|
||||
8cb7424aa9d42d028a6780250effe4e719d9bb35558057f8ebe9e32408a6b80f lib/core/threads.py
|
||||
ff39235aee7e33498c66132d17e6e86e7b8a29754e3fdecd880ca8356b17f791 lib/core/unescaper.py
|
||||
2984e4973868f586aa932f00da684bf31718c0331817c9f8721acd71fd661f89 lib/core/update.py
|
||||
@@ -240,9 +240,9 @@ f948fefb0fa67da8cf037f7abbcdbb740148babda9ad8a58fab1693456834817 lib/techniques
|
||||
99d0e94dd5fe60137abf48bfa051129fb251f5c40f0f7a270c89fbcb07323730 lib/techniques/__init__.py
|
||||
99d0e94dd5fe60137abf48bfa051129fb251f5c40f0f7a270c89fbcb07323730 lib/techniques/union/__init__.py
|
||||
700cc5e8cae85bd86674d0cb6c97093fde2c52a480cc1e40ae0010fffd649395 lib/techniques/union/test.py
|
||||
4252a1829e60bb9a69e3927bf68a320976b8ef637804b7032d7497699f2e89e7 lib/techniques/union/use.py
|
||||
74ecbeff52a6fba83fc2c93612afd8befdbdc0c25566d31e5d20fbbc5b895054 lib/techniques/union/use.py
|
||||
6b3f83a85c576830783a64e943a58e90b1f25e9e24cd51ae12b1d706796124e9 lib/utils/api.py
|
||||
1d4d1e49a0897746d4ad64316d4d777f4804c4c11e349e9eb3844130183d4887 lib/utils/brute.py
|
||||
e00740b9a4c997152fa8b00d3f0abf45ae15e23c33a92966eaa658fde83c586f lib/utils/brute.py
|
||||
c0a4765aa80c5d9b7ef1abe93401a78dd45b2766a1f4ff6286287dc6188294de lib/utils/crawler.py
|
||||
3f97e327c548d8b5d74fda96a2a0d1b2933b289b9ec2351b06c91cefdd38629d lib/utils/deps.py
|
||||
e81393f0d077578e6dcd3db2887e93ac2bfbdef2ce87686e83236a36112ca7d3 lib/utils/getch.py
|
||||
@@ -460,7 +460,7 @@ acc41465f146d2611fca5a84bd8896bc0ccd2b032b8938357aea3e5b173a5a10 plugins/dbms/v
|
||||
3c163c8135e2ab8ed17b0000862a1b2d7cf2ec1e7d96d349ec644651cdecad49 plugins/dbms/virtuoso/syntax.py
|
||||
7ac6006e0fc6da229c37fbce39a1406022e5fcc4cac5209814fa20818b8c031a plugins/dbms/virtuoso/takeover.py
|
||||
e6dfaab13d9f98ccffdc70dd46800ca2d61519731d10a267bc82f9fb82cd504d plugins/generic/connector.py
|
||||
664be8bb4157452f2e40c4f98a359e26b559d7ef4f4148564cb8533b5ebf7d54 plugins/generic/custom.py
|
||||
ef413f95c1846d37750beae90ed3e3b3a1288cfa9595c9c6f7890252a4ee3166 plugins/generic/custom.py
|
||||
3d118a7ddb1604a9f86826118cfbae4ab0b83f6e9bef9c6d1c7e77d3da6acf67 plugins/generic/databases.py
|
||||
96924a13d7bf0ed8056dc70f10593e9253750a3d83e9a9c9656c3d1527eda344 plugins/generic/entries.py
|
||||
a734d74599761cd1cf7d49c88deeb121ea57d80c2f0447e361a4e3a737154c0e plugins/generic/enumeration.py
|
||||
@@ -476,7 +476,7 @@ fff84edc86b7d22dc01148fb10bb43d51cb9638dff21436fb94555db2a664766 plugins/generi
|
||||
5a473c60853f54f1a4b14d79b8237f659278fe8a6b42e935ed573bf22b6d5b2c README.md
|
||||
78aafd53980096364f0c995c6283931bff505aed88fed1e7906fb06ee60e9c5b sqlmapapi.py
|
||||
168309215af7dd5b0b71070e1770e72f1cbb29a3d8025143fb8aa0b88cd56b62 sqlmapapi.yaml
|
||||
5e172e315524845fe091aa0b7b29303c92ac8f67594c6d50f026d627e415b7ed sqlmap.conf
|
||||
005b240c187586fbdb7bab247398cad881efec26b6d6a46229a635411f5f207e sqlmap.conf
|
||||
3a18b78b1aaf7236a35169db20eb21ca7d7fb907cd38dd34650f1da81c010cd6 sqlmap.py
|
||||
adda508966db26c30b11390d6483c1fa25b092942a29730e739e1e50c403a21f tamper/0eunion.py
|
||||
d38fe5ab97b401810612eae049325aa990c55143504b25cc9924810917511dee tamper/apostrophemask.py
|
||||
|
||||
@@ -3716,10 +3716,12 @@ def joinValue(value, delimiter=','):
|
||||
'1,2'
|
||||
>>> joinValue('1')
|
||||
'1'
|
||||
>>> joinValue(['1', None])
|
||||
'1,None'
|
||||
"""
|
||||
|
||||
if isListLike(value):
|
||||
retVal = delimiter.join(value)
|
||||
retVal = delimiter.join(getText(_ if _ is not None else "None") for _ in value)
|
||||
else:
|
||||
retVal = value
|
||||
|
||||
|
||||
@@ -435,7 +435,7 @@ def _setStdinPipeTargets():
|
||||
def next(self):
|
||||
try:
|
||||
line = next(conf.stdinPipe)
|
||||
except (IOError, OSError, TypeError):
|
||||
except (IOError, OSError, TypeError, UnicodeDecodeError):
|
||||
line = None
|
||||
|
||||
if line:
|
||||
@@ -812,6 +812,7 @@ def _setTamperingFunctions():
|
||||
raise SqlmapSyntaxException("cannot import tamper module '%s' (%s)" % (getUnicode(filename[:-3]), getSafeExString(ex)))
|
||||
|
||||
priority = PRIORITY.NORMAL if not hasattr(module, "__priority__") else module.__priority__
|
||||
priority = priority if priority is not None else PRIORITY.LOWEST
|
||||
|
||||
for name, function in inspect.getmembers(module, inspect.isfunction):
|
||||
if name == "tamper" and (hasattr(inspect, "signature") and all(_ in inspect.signature(function).parameters for _ in ("payload", "kwargs")) or inspect.getargspec(function).args and inspect.getargspec(function).keywords == "kwargs"):
|
||||
|
||||
@@ -19,7 +19,7 @@ from lib.core.enums import OS
|
||||
from thirdparty import six
|
||||
|
||||
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
|
||||
VERSION = "1.8.11.0"
|
||||
VERSION = "1.8.12.0"
|
||||
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)
|
||||
@@ -60,6 +60,9 @@ LIVE_COOKIES_TIMEOUT = 120
|
||||
LOWER_RATIO_BOUND = 0.02
|
||||
UPPER_RATIO_BOUND = 0.98
|
||||
|
||||
# For filling in case of dumb push updates
|
||||
DUMMY_JUNK = "Gu8ohxi9"
|
||||
|
||||
# Markers for special cases when parameter values contain html encoded characters
|
||||
PARAMETER_AMP_MARKER = "__AMP__"
|
||||
PARAMETER_SEMICOLON_MARKER = "__SEMICOLON__"
|
||||
@@ -907,9 +910,6 @@ KB_CHARS_BOUNDARY_CHAR = 'q'
|
||||
# Letters of lower frequency used in kb.chars
|
||||
KB_CHARS_LOW_FREQUENCY_ALPHABET = "zqxjkvbp"
|
||||
|
||||
# For filling in case of dumb push updates
|
||||
DUMMY_JUNK = "Ataiphi2"
|
||||
|
||||
# Printable bytes
|
||||
PRINTABLE_BYTES = set(bytes(string.printable, "ascii") if six.PY3 else string.printable)
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ def vulnTest():
|
||||
("-u \"<url>&echo=foobar*\" --flush-session", ("might be vulnerable to cross-site scripting",)),
|
||||
("-u \"<url>&query=*\" --flush-session --technique=Q --banner", ("Title: SQLite inline queries", "banner: '3.")),
|
||||
("-d \"<direct>\" --flush-session --dump -T users --dump-format=SQLITE --binary-fields=name --where \"id=3\"", ("7775", "179ad45c6ce2cb97cf1029e212046e81 (testpass)", "dumped to SQLITE database")),
|
||||
("-d \"<direct>\" --flush-session --banner --schema --sql-query=\"UPDATE users SET name='foobar' WHERE id=5; SELECT * FROM users; SELECT 987654321\"", ("banner: '3.", "INTEGER", "TEXT", "id", "name", "surname", "5, foobar, nameisnull", "'987654321'",)),
|
||||
("-d \"<direct>\" --flush-session --banner --schema --sql-query=\"UPDATE users SET name='foobar' WHERE id=5; SELECT * FROM users; SELECT 987654321\"", ("banner: '3.", "INTEGER", "TEXT", "id", "name", "surname", "5,foobar,nameisnull", "'987654321'",)),
|
||||
("--purge -v 3", ("~ERROR", "~CRITICAL", "deleting the whole directory tree")),
|
||||
)
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ from lib.core.common import singleTimeWarnMessage
|
||||
from lib.core.common import unArrayizeValue
|
||||
from lib.core.common import wasLastResponseDBMSError
|
||||
from lib.core.compat import xrange
|
||||
from lib.core.convert import decodeBase64
|
||||
from lib.core.convert import getUnicode
|
||||
from lib.core.convert import htmlUnescape
|
||||
from lib.core.data import conf
|
||||
@@ -126,6 +127,9 @@ def _oneShotUnionUse(expression, unpack=True, limited=False):
|
||||
try:
|
||||
retVal = ""
|
||||
for row in json.loads(output):
|
||||
# NOTE: for cases with automatic MySQL Base64 encoding of JSON array values, like: ["base64:type15:MQ=="]
|
||||
for match in re.finditer(r"base64:type\d+:([^ ]+)", row):
|
||||
row = row.replace(match.group(0), decodeBase64(match.group(1), binary=False))
|
||||
retVal += "%s%s%s" % (kb.chars.start, row, kb.chars.stop)
|
||||
except:
|
||||
retVal = None
|
||||
@@ -254,10 +258,10 @@ def unionUse(expression, unpack=True, dump=False):
|
||||
|
||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ORACLE, DBMS.PGSQL, DBMS.MSSQL, DBMS.SQLITE) and expressionFields and not any((conf.binaryFields, conf.limitStart, conf.limitStop, conf.forcePartial, conf.disableJson)):
|
||||
match = re.search(r"SELECT\s*(.+?)\bFROM", expression, re.I)
|
||||
if match and not (Backend.isDbms(DBMS.ORACLE) and FROM_DUMMY_TABLE[DBMS.ORACLE] in expression) and not re.search(r"\b(MIN|MAX|COUNT)\(", expression):
|
||||
if match and not (Backend.isDbms(DBMS.ORACLE) and FROM_DUMMY_TABLE[DBMS.ORACLE] in expression) and not re.search(r"\b(MIN|MAX|COUNT|EXISTS)\(", expression):
|
||||
kb.jsonAggMode = True
|
||||
if Backend.isDbms(DBMS.MYSQL):
|
||||
query = expression.replace(expressionFields, "CONCAT('%s',JSON_ARRAYAGG(CONCAT_WS('%s',%s)),'%s')" % (kb.chars.start, kb.chars.delimiter, expressionFields, kb.chars.stop), 1)
|
||||
query = expression.replace(expressionFields, "CONCAT('%s',JSON_ARRAYAGG(CONCAT_WS('%s',%s)),'%s')" % (kb.chars.start, kb.chars.delimiter, ','.join(agent.nullAndCastField(field) for field in expressionFieldsList), kb.chars.stop), 1)
|
||||
elif Backend.isDbms(DBMS.ORACLE):
|
||||
query = expression.replace(expressionFields, "'%s'||JSON_ARRAYAGG(%s)||'%s'" % (kb.chars.start, ("||'%s'||" % kb.chars.delimiter).join(expressionFieldsList), kb.chars.stop), 1)
|
||||
elif Backend.isDbms(DBMS.SQLITE):
|
||||
|
||||
@@ -228,93 +228,95 @@ def columnExists(columnFile, regex=None):
|
||||
columns.extend(_addPageTextWords())
|
||||
columns = filterListValue(columns, regex)
|
||||
|
||||
table = safeSQLIdentificatorNaming(conf.tbl, True)
|
||||
for table in conf.tbl.split(','):
|
||||
table = safeSQLIdentificatorNaming(table, True)
|
||||
|
||||
if conf.db and METADB_SUFFIX not in conf.db and Backend.getIdentifiedDbms() not in (DBMS.SQLITE, DBMS.ACCESS, DBMS.FIREBIRD):
|
||||
table = "%s.%s" % (safeSQLIdentificatorNaming(conf.db), table)
|
||||
if conf.db and METADB_SUFFIX not in conf.db and Backend.getIdentifiedDbms() not in (DBMS.SQLITE, DBMS.ACCESS, DBMS.FIREBIRD):
|
||||
table = "%s.%s" % (safeSQLIdentificatorNaming(conf.db), table)
|
||||
|
||||
kb.threadContinue = True
|
||||
kb.bruteMode = True
|
||||
kb.threadContinue = True
|
||||
kb.bruteMode = True
|
||||
|
||||
threadData = getCurrentThreadData()
|
||||
threadData.shared.count = 0
|
||||
threadData.shared.limit = len(columns)
|
||||
threadData.shared.files = []
|
||||
|
||||
def columnExistsThread():
|
||||
threadData = getCurrentThreadData()
|
||||
threadData.shared.count = 0
|
||||
threadData.shared.limit = len(columns)
|
||||
threadData.shared.files = []
|
||||
|
||||
while kb.threadContinue:
|
||||
kb.locks.count.acquire()
|
||||
if threadData.shared.count < threadData.shared.limit:
|
||||
column = safeSQLIdentificatorNaming(columns[threadData.shared.count])
|
||||
threadData.shared.count += 1
|
||||
kb.locks.count.release()
|
||||
else:
|
||||
kb.locks.count.release()
|
||||
break
|
||||
def columnExistsThread():
|
||||
threadData = getCurrentThreadData()
|
||||
|
||||
if Backend.isDbms(DBMS.MCKOI):
|
||||
result = inject.checkBooleanExpression(safeStringFormat("0<(SELECT COUNT(%s) FROM %s)", (column, table)))
|
||||
else:
|
||||
result = inject.checkBooleanExpression(safeStringFormat(BRUTE_COLUMN_EXISTS_TEMPLATE, (column, table)))
|
||||
while kb.threadContinue:
|
||||
kb.locks.count.acquire()
|
||||
|
||||
kb.locks.io.acquire()
|
||||
if threadData.shared.count < threadData.shared.limit:
|
||||
column = safeSQLIdentificatorNaming(columns[threadData.shared.count])
|
||||
threadData.shared.count += 1
|
||||
kb.locks.count.release()
|
||||
else:
|
||||
kb.locks.count.release()
|
||||
break
|
||||
|
||||
if result:
|
||||
threadData.shared.files.append(column)
|
||||
if Backend.isDbms(DBMS.MCKOI):
|
||||
result = inject.checkBooleanExpression(safeStringFormat("0<(SELECT COUNT(%s) FROM %s)", (column, table)))
|
||||
else:
|
||||
result = inject.checkBooleanExpression(safeStringFormat(BRUTE_COLUMN_EXISTS_TEMPLATE, (column, table)))
|
||||
|
||||
if conf.verbose in (1, 2) and not conf.api:
|
||||
clearConsoleLine(True)
|
||||
infoMsg = "[%s] [INFO] retrieved: %s\n" % (time.strftime("%X"), unsafeSQLIdentificatorNaming(column))
|
||||
dataToStdout(infoMsg, True)
|
||||
kb.locks.io.acquire()
|
||||
|
||||
if conf.verbose in (1, 2):
|
||||
status = "%d/%d items (%d%%)" % (threadData.shared.count, threadData.shared.limit, round(100.0 * threadData.shared.count / threadData.shared.limit))
|
||||
dataToStdout("\r[%s] [INFO] tried %s" % (time.strftime("%X"), status), True)
|
||||
if result:
|
||||
threadData.shared.files.append(column)
|
||||
|
||||
kb.locks.io.release()
|
||||
if conf.verbose in (1, 2) and not conf.api:
|
||||
clearConsoleLine(True)
|
||||
infoMsg = "[%s] [INFO] retrieved: %s\n" % (time.strftime("%X"), unsafeSQLIdentificatorNaming(column))
|
||||
dataToStdout(infoMsg, True)
|
||||
|
||||
try:
|
||||
runThreads(conf.threads, columnExistsThread, threadChoice=True)
|
||||
except KeyboardInterrupt:
|
||||
warnMsg = "user aborted during column existence "
|
||||
warnMsg += "check. sqlmap will display partial output"
|
||||
logger.warning(warnMsg)
|
||||
finally:
|
||||
kb.bruteMode = False
|
||||
if conf.verbose in (1, 2):
|
||||
status = "%d/%d items (%d%%)" % (threadData.shared.count, threadData.shared.limit, round(100.0 * threadData.shared.count / threadData.shared.limit))
|
||||
dataToStdout("\r[%s] [INFO] tried %s" % (time.strftime("%X"), status), True)
|
||||
|
||||
clearConsoleLine(True)
|
||||
dataToStdout("\n")
|
||||
kb.locks.io.release()
|
||||
|
||||
if not threadData.shared.files:
|
||||
warnMsg = "no column(s) found"
|
||||
logger.warning(warnMsg)
|
||||
else:
|
||||
columns = {}
|
||||
try:
|
||||
runThreads(conf.threads, columnExistsThread, threadChoice=True)
|
||||
except KeyboardInterrupt:
|
||||
warnMsg = "user aborted during column existence "
|
||||
warnMsg += "check. sqlmap will display partial output"
|
||||
logger.warning(warnMsg)
|
||||
finally:
|
||||
kb.bruteMode = False
|
||||
|
||||
for column in threadData.shared.files:
|
||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL,):
|
||||
result = not inject.checkBooleanExpression("%s" % safeStringFormat("EXISTS(SELECT %s FROM %s WHERE %s REGEXP '[^0-9]')", (column, table, column)))
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.SQLITE,):
|
||||
result = inject.checkBooleanExpression("%s" % safeStringFormat("EXISTS(SELECT %s FROM %s WHERE %s NOT GLOB '*[^0-9]*')", (column, table, column)))
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.MCKOI,):
|
||||
result = inject.checkBooleanExpression("%s" % safeStringFormat("0=(SELECT MAX(%s)-MAX(%s) FROM %s)", (column, column, table)))
|
||||
else:
|
||||
result = inject.checkBooleanExpression("%s" % safeStringFormat("EXISTS(SELECT %s FROM %s WHERE ROUND(%s)=ROUND(%s))", (column, table, column, column)))
|
||||
clearConsoleLine(True)
|
||||
dataToStdout("\n")
|
||||
|
||||
if result:
|
||||
columns[column] = "numeric"
|
||||
else:
|
||||
columns[column] = "non-numeric"
|
||||
if not threadData.shared.files:
|
||||
warnMsg = "no column(s) found"
|
||||
logger.warning(warnMsg)
|
||||
else:
|
||||
columns = {}
|
||||
|
||||
kb.data.cachedColumns[conf.db] = {conf.tbl: columns}
|
||||
for column in threadData.shared.files:
|
||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL,):
|
||||
result = not inject.checkBooleanExpression("%s" % safeStringFormat("EXISTS(SELECT %s FROM %s WHERE %s REGEXP '[^0-9]')", (column, table, column)))
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.SQLITE,):
|
||||
result = inject.checkBooleanExpression("%s" % safeStringFormat("EXISTS(SELECT %s FROM %s WHERE %s NOT GLOB '*[^0-9]*')", (column, table, column)))
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.MCKOI,):
|
||||
result = inject.checkBooleanExpression("%s" % safeStringFormat("0=(SELECT MAX(%s)-MAX(%s) FROM %s)", (column, column, table)))
|
||||
else:
|
||||
result = inject.checkBooleanExpression("%s" % safeStringFormat("EXISTS(SELECT %s FROM %s WHERE ROUND(%s)=ROUND(%s))", (column, table, column, column)))
|
||||
|
||||
for _ in ((conf.db, conf.tbl, item[0], item[1]) for item in columns.items()):
|
||||
if _ not in kb.brute.columns:
|
||||
kb.brute.columns.append(_)
|
||||
if result:
|
||||
columns[column] = "numeric"
|
||||
else:
|
||||
columns[column] = "non-numeric"
|
||||
|
||||
hashDBWrite(HASHDB_KEYS.KB_BRUTE_COLUMNS, kb.brute.columns, True)
|
||||
kb.data.cachedColumns[conf.db] = {table: columns}
|
||||
|
||||
for _ in ((conf.db, table, item[0], item[1]) for item in columns.items()):
|
||||
if _ not in kb.brute.columns:
|
||||
kb.brute.columns.append(_)
|
||||
|
||||
hashDBWrite(HASHDB_KEYS.KB_BRUTE_COLUMNS, kb.brute.columns, True)
|
||||
|
||||
return kb.data.cachedColumns
|
||||
|
||||
|
||||
@@ -13,7 +13,10 @@ import sys
|
||||
from lib.core.common import Backend
|
||||
from lib.core.common import dataToStdout
|
||||
from lib.core.common import getSQLSnippet
|
||||
from lib.core.common import isListLike
|
||||
from lib.core.common import isStackingAvailable
|
||||
from lib.core.common import joinValue
|
||||
from lib.core.compat import xrange
|
||||
from lib.core.convert import getUnicode
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import logger
|
||||
@@ -41,6 +44,7 @@ class Custom(object):
|
||||
sqlType = None
|
||||
query = query.rstrip(';')
|
||||
|
||||
|
||||
try:
|
||||
for sqlTitle, sqlStatements in SQL_STATEMENTS.items():
|
||||
for sqlStatement in sqlStatements:
|
||||
@@ -61,6 +65,11 @@ class Custom(object):
|
||||
|
||||
output = inject.getValue(query, fromUser=True)
|
||||
|
||||
if sqlType and "SELECT" in sqlType and isListLike(output):
|
||||
for i in xrange(len(output)):
|
||||
if isListLike(output[i]):
|
||||
output[i] = joinValue(output[i])
|
||||
|
||||
return output
|
||||
elif not isStackingAvailable() and not conf.direct:
|
||||
warnMsg = "execution of non-query SQL statements is only "
|
||||
|
||||
@@ -27,8 +27,8 @@ requestFile =
|
||||
|
||||
# Rather than providing a target URL, let Google return target
|
||||
# hosts as result of your Google dork expression. For a list of Google
|
||||
# dorks see Johnny Long Google Hacking Database at
|
||||
# http://johnny.ihackstuff.com/ghdb.php.
|
||||
# dorks see Google Hacking Database at
|
||||
# https://www.exploit-db.com/google-hacking-database
|
||||
# Example: +ext:php +inurl:"&id=" +intext:"powered by "
|
||||
googleDork =
|
||||
|
||||
|
||||
Reference in New Issue
Block a user