Compare commits

...
25 Commits
Author SHA1 Message Date
Miroslav Stampar 3c93872d53 Update related to the #4182 2020-05-02 13:59:06 +02:00
Miroslav Stampar 881d767df8 Fixes #4181 2020-04-30 16:20:57 +02:00
Miroslav Stampar 1156b53eee Patch for #4178 2020-04-29 14:36:11 +02:00
Miroslav Stampar 5cacf20eb5 Speeding up the post-processing of large dumps 2020-04-27 14:23:47 +02:00
Miroslav Stampar 1825390951 Feeding the OCD 2020-04-26 15:35:34 +02:00
Miroslav Stampar 7815f88027 Patch for #4171 2020-04-26 15:34:27 +02:00
Miroslav Stampar f63a92a272 Another minor patch related to the #4167 2020-04-21 01:26:28 +02:00
Miroslav Stampar e3b3dea46c Patch related to the #4167 2020-04-21 01:21:50 +02:00
Miroslav Stampar 55595edce2 Fixes #4165 2020-04-17 19:29:36 +02:00
Miroslav Stampar aaa0c5c6a8 Minor update 2020-04-15 23:32:15 +02:00
Miroslav Stampar 57bb710ae6 Bug fix (CTF and stuff) 2020-04-08 22:40:23 +02:00
Miroslav Stampar ce9285381d Fixes #4158 2020-04-07 02:07:54 +02:00
Miroslav Stampar dad4879200 Couple of trivial refactorings 2020-04-03 00:16:38 +02:00
Miroslav Stampar 2cba4e2d78 Minor update 2020-03-26 14:58:58 +01:00
Miroslav Stampar 8ec165d688 Fixes #4144 2020-03-19 11:25:12 +01:00
Miroslav Stampar 492fbae7c5 Fixes #4143 2020-03-18 10:17:58 +01:00
Miroslav Stampar a8d81a7962 Fixes #4141 2020-03-17 11:10:52 +01:00
Miroslav Stampar fcb2a6e111 Patch related to the #4137 2020-03-16 17:31:37 +01:00
Miroslav Stampar 2e7333d7c8 Fixes #4133 2020-03-16 16:56:00 +01:00
Miroslav Stampar 5fd2598da0 Fixes #4136 2020-03-12 22:36:12 +01:00
Miroslav Stampar 111201978c Fixes #4131 2020-03-09 10:44:11 +01:00
Miroslav Stampar 41bdb93655 Fixes #4132 2020-03-09 10:30:24 +01:00
Miroslav Stampar 6cd0b1120f Minor update 2020-03-06 12:26:31 +01:00
Miroslav Stampar 97ccf4ca66 Minor patch 2020-03-06 12:21:26 +01:00
Miroslav Stampar 8cc516dc5f Bug fix (wrong coloring in some cases) 2020-03-05 14:02:27 +01:00
23 changed files with 160 additions and 78 deletions
-2
View File
@@ -1534,7 +1534,6 @@
<substring query="SUBSTR((%s),%d,%d)"/>
<concatenate query="%s||%s"/>
<case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/>
<hex/>
<inference query="SUBSTR((%s),%d,1)>'%c'"/>
<banner/>
<current_user/>
@@ -1577,7 +1576,6 @@
<substring query="SUBSTRING((%s) FROM %d FOR %d)"/>
<concatenate query="%s||%s"/>
<case query="SELECT (CASE WHEN (%s) THEN '1' ELSE '0' END)"/>
<hex/>
<inference query="SUBSTRING((%s) FROM %d FOR 1)>'%c'"/>
<banner/>
<current_user query="CURRENT_USER"/>
+2
View File
@@ -54,6 +54,8 @@ def action():
conf.dumper.singleString(conf.dbmsHandler.getFingerprint())
kb.fingerprinted = True
# Enumeration options
if conf.getBanner:
conf.dumper.banner(conf.dbmsHandler.getBanner())
+15 -5
View File
@@ -110,6 +110,7 @@ class Agent(object):
paramDict = conf.paramDict[place]
origValue = getUnicode(paramDict[parameter])
newValue = getUnicode(newValue) if newValue else newValue
base64Encoding = re.sub(r" \(.+", "", parameter) in conf.base64Parameter
if place == PLACE.URI or BOUNDED_INJECTION_MARKER in origValue:
paramString = origValue
@@ -173,7 +174,10 @@ class Agent(object):
newValue = self.cleanupPayload(newValue, origValue)
if re.sub(r" \(.+", "", parameter) in conf.base64Parameter:
if base64Encoding:
_newValue = newValue
_origValue = origValue
# TODO: support for POST_HINT
newValue = encodeBase64(newValue, binary=False, encoding=conf.encoding or UNICODE_ENCODING)
origValue = encodeBase64(origValue, binary=False, encoding=conf.encoding or UNICODE_ENCODING)
@@ -194,7 +198,13 @@ class Agent(object):
retVal = retVal.replace(kb.customInjectionMark, "").replace(REPLACEMENT_MARKER, kb.customInjectionMark)
elif BOUNDED_INJECTION_MARKER in paramDict[parameter]:
retVal = paramString.replace("%s%s" % (origValue, BOUNDED_INJECTION_MARKER), self.addPayloadDelimiters(newValue))
if base64Encoding:
retVal = paramString.replace("%s%s" % (_origValue, BOUNDED_INJECTION_MARKER), _newValue)
match = re.search(r"(%s)=([^&]*)" % re.sub(r" \(.+", "", parameter), retVal)
if match:
retVal = retVal.replace(match.group(0), "%s=%s" % (match.group(1), encodeBase64(match.group(2), binary=False, encoding=conf.encoding or UNICODE_ENCODING)))
else:
retVal = paramString.replace("%s%s" % (origValue, BOUNDED_INJECTION_MARKER), self.addPayloadDelimiters(newValue))
elif place in (PLACE.USER_AGENT, PLACE.REFERER, PLACE.HOST):
retVal = paramString.replace(origValue, self.addPayloadDelimiters(newValue))
else:
@@ -535,7 +545,7 @@ class Agent(object):
"""
prefixRegex = r"(?:\s+(?:FIRST|SKIP|LIMIT(?: \d+)?)\s+\d+)*"
fieldsSelectTop = re.search(r"\ASELECT\s+TOP\s+([\d]|\([^)]+\))+\s+(.+?)\s+FROM", query, re.I)
fieldsSelectTop = re.search(r"\ASELECT\s+TOP(\s+[\d]|\s*\([^)]+\))\s+(.+?)\s+FROM", query, re.I)
fieldsSelectRownum = re.search(r"\ASELECT\s+([^()]+?),\s*ROWNUM AS LIMIT FROM", query, re.I)
fieldsSelectDistinct = re.search(r"\ASELECT%s\s+DISTINCT\((.+?)\)\s+FROM" % prefixRegex, query, re.I)
fieldsSelectCase = re.search(r"\ASELECT%s\s+(\(CASE WHEN\s+.+\s+END\))" % prefixRegex, query, re.I)
@@ -683,8 +693,8 @@ class Agent(object):
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'+" % kb.chars.start, 1)
concatenatedQuery += "+'%s'" % kb.chars.stop
elif fieldsSelectTop:
topNum = re.search(r"\ASELECT\s+TOP\s+([\d]+)\s+", concatenatedQuery, re.I).group(1)
concatenatedQuery = concatenatedQuery.replace("SELECT TOP %s " % topNum, "TOP %s '%s'+" % (topNum, kb.chars.start), 1)
topNum = re.search(r"\ASELECT\s+TOP(\s+[\d]|\s*\([^)]+\))\s+", concatenatedQuery, re.I).group(1)
concatenatedQuery = concatenatedQuery.replace("SELECT TOP%s " % topNum, "TOP%s '%s'+" % (topNum, kb.chars.start), 1)
concatenatedQuery = concatenatedQuery.replace(" FROM ", "+'%s' FROM " % kb.chars.stop, 1)
elif fieldsSelectCase:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'+" % kb.chars.start, 1)
+49 -28
View File
@@ -935,27 +935,39 @@ def setColor(message, color=None, bold=False, level=None, istty=None):
>>> setColor("Hello World", color="red", istty=True)
'\\x1b[31mHello World\\x1b[0m'
>>> setColor("[INFO] Hello World", istty=True)
'[\\x1b[32mINFO\\x1b[0m] Hello World'
>>> setColor("[INFO] Hello [CRITICAL] World", istty=True)
'[INFO] Hello [CRITICAL] World'
"""
retVal = message
level = level or extractRegexResult(r"\[(?P<result>%s)\]" % '|'.join(_[0] for _ in getPublicTypeMembers(LOGGING_LEVELS)), message)
if message and (IS_TTY or istty) and not conf.get("disableColoring"): # colorizing handler
if bold or color:
retVal = colored(message, color=color, on_color=None, attrs=("bold",) if bold else None)
elif level:
try:
level = getattr(logging, level, None)
except:
level = None
retVal = LOGGER_HANDLER.colorize(message, level)
else:
match = re.search(r"\(([^)]*)\s*fork\)", message)
if match:
retVal = retVal.replace(match.group(1), colored(match.group(1), color="lightgrey"))
if message:
if (IS_TTY or istty) and not conf.get("disableColoring"): # colorizing handler
if level is None:
levels = re.findall(r"\[(?P<result>%s)\]" % '|'.join(_[0] for _ in getPublicTypeMembers(LOGGING_LEVELS)), message)
for match in re.finditer(r"[^\w]'([^\n']+)'", message): # single-quoted (Note: watch-out for the banner)
retVal = retVal.replace(match.group(1), colored(match.group(1), color="lightgrey"))
if len(levels) == 1:
level = levels[0]
if bold or color:
retVal = colored(message, color=color, on_color=None, attrs=("bold",) if bold else None)
elif level:
try:
level = getattr(logging, level, None)
except:
level = None
retVal = LOGGER_HANDLER.colorize(message, level)
else:
match = re.search(r"\(([^)]*)\s*fork\)", message)
if match:
retVal = retVal.replace(match.group(1), colored(match.group(1), color="lightgrey"))
for match in re.finditer(r"([^\w])'([^\n']+)'", message): # single-quoted (Note: watch-out for the banner)
retVal = retVal.replace(match.group(0), "%s'%s'" % (match.group(1), colored(match.group(2), color="lightgrey")))
message = message.strip()
return retVal
@@ -974,11 +986,17 @@ def clearColors(message):
return retVal
def dataToStdout(data, forceOutput=False, bold=False, content_type=None, status=CONTENT_STATUS.IN_PROGRESS):
def dataToStdout(data, forceOutput=False, bold=False, contentType=None, status=CONTENT_STATUS.IN_PROGRESS, coloring=True):
"""
Writes text to the stdout (console) stream
"""
if not IS_TTY and isinstance(data, six.string_types) and data.startswith("\r"):
if re.search(r"\(\d+%\)", data):
data = ""
else:
data = "\n%s" % data.strip("\r")
if not kb.get("threadException"):
if forceOutput or not (getCurrentThreadData().disableStdOut or kb.get("wizardMode")):
multiThreadMode = isMultiThreadMode()
@@ -987,9 +1005,9 @@ def dataToStdout(data, forceOutput=False, bold=False, content_type=None, status=
try:
if conf.get("api"):
sys.stdout.write(stdoutEncode(clearColors(data)), status, content_type)
sys.stdout.write(stdoutEncode(clearColors(data)), status, contentType)
else:
sys.stdout.write(stdoutEncode(setColor(data, bold=bold)))
sys.stdout.write(stdoutEncode(setColor(data, bold=bold) if coloring else clearColors(data)))
sys.stdout.flush()
except IOError:
@@ -1204,9 +1222,9 @@ def randomStr(length=4, lowercase=False, alphabet=None, seed=None):
"""
if seed is not None:
_ = getCurrentThreadData().random
_.seed(seed)
choice = _.choice
_random = getCurrentThreadData().random
_random.seed(seed)
choice = _random.choice
else:
choice = random.choice
@@ -1238,10 +1256,12 @@ def getHeader(headers, key):
"""
retVal = None
for _ in (headers or {}):
if _.upper() == key.upper():
retVal = headers[_]
for header in (headers or {}):
if header.upper() == key.upper():
retVal = headers[header]
break
return retVal
def checkPipedInput():
@@ -1422,6 +1442,7 @@ def setPaths(rootPath):
checkFile(path)
if IS_WIN:
# Reference: https://pureinfotech.com/list-environment-variables-windows-10/
if os.getenv("LOCALAPPDATA"):
paths.SQLMAP_HOME_PATH = os.path.expandvars("%LOCALAPPDATA%\\sqlmap")
elif os.getenv("USERPROFILE"):
@@ -1435,7 +1456,7 @@ def setPaths(rootPath):
paths.SQLMAP_DUMP_PATH = os.path.join(paths.SQLMAP_OUTPUT_PATH, "%s", "dump")
paths.SQLMAP_FILES_PATH = os.path.join(paths.SQLMAP_OUTPUT_PATH, "%s", "files")
# history files
# History files
paths.SQLMAP_HISTORY_PATH = getUnicode(os.path.join(paths.SQLMAP_HOME_PATH, "history"), encoding=sys.getfilesystemencoding() or UNICODE_ENCODING)
paths.API_SHELL_HISTORY = os.path.join(paths.SQLMAP_HISTORY_PATH, "api.hst")
paths.OS_SHELL_HISTORY = os.path.join(paths.SQLMAP_HISTORY_PATH, "os.hst")
@@ -1592,7 +1613,7 @@ def parseTargetUrl():
originalUrl = conf.url
if re.search(r"\[.+\]", conf.url) and not socket.has_ipv6:
errMsg = "IPv6 addressing is not supported "
errMsg = "IPv6 communication is not supported "
errMsg += "on this platform"
raise SqlmapGenericException(errMsg)
@@ -1649,7 +1670,7 @@ def parseTargetUrl():
conf.port = 80
if conf.port < 1 or conf.port > 65535:
errMsg = "invalid target URL's port (%d)" % conf.port
errMsg = "invalid target URL port (%d)" % conf.port
raise SqlmapSyntaxException(errMsg)
conf.url = getUnicode("%s://%s:%d%s" % (conf.scheme, ("[%s]" % conf.hostname) if conf.ipv6 else conf.hostname, conf.port, conf.path))
+1 -1
View File
@@ -95,7 +95,7 @@ def htmlUnescape(value):
try:
retVal = re.sub(r"&#x([^ ;]+);", lambda match: _unichr(int(match.group(1), 16)), retVal)
except ValueError:
except (ValueError, OverflowError):
pass
return retVal
+1 -1
View File
@@ -72,7 +72,7 @@ class Dump(object):
text = "%s%s" % (data, "\n" if newline else " ")
if conf.api:
dataToStdout(data, content_type=content_type, status=CONTENT_STATUS.COMPLETE)
dataToStdout(data, contentType=content_type, status=CONTENT_STATUS.COMPLETE)
elif console:
dataToStdout(text)
+13 -7
View File
@@ -371,7 +371,7 @@ def _doSearch():
for link in links:
link = urldecode(link)
if re.search(r"(.*?)\?(.+)", link):
if re.search(r"(.*?)\?(.+)", link) or conf.forms:
kb.targets.add((link, conf.method, conf.data, conf.cookie, None))
elif re.search(URI_INJECTABLE_REGEX, link, re.I):
if kb.data.onlyGETs is None and conf.data is None and not conf.googleDork:
@@ -387,14 +387,18 @@ def _doSearch():
if kb.targets:
infoMsg = "found %d results for your " % len(links)
infoMsg += "search dork expression, "
infoMsg += "search dork expression"
if len(links) == len(kb.targets):
infoMsg += "all "
else:
infoMsg += "%d " % len(kb.targets)
if not conf.forms:
infoMsg += ", "
if len(links) == len(kb.targets):
infoMsg += "all "
else:
infoMsg += "%d " % len(kb.targets)
infoMsg += "of them are testable targets"
infoMsg += "of them are testable targets"
logger.info(infoMsg)
break
@@ -1867,6 +1871,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.cache.content = {}
kb.cache.encoding = {}
kb.cache.alphaBoundaries = None
kb.cache.hashRegex = None
kb.cache.intBoundaries = None
kb.cache.parsedDbms = {}
kb.cache.regex = {}
@@ -1916,6 +1921,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.errorIsNone = True
kb.falsePositives = []
kb.fileReadMode = False
kb.fingerprinted = False
kb.followSitemapRecursion = None
kb.forcedDbms = None
kb.forcePartialUnion = False
+1
View File
@@ -201,6 +201,7 @@ optDict = {
"trafficFile": "string",
"answers": "string",
"batch": "boolean",
"base64Parameter": "string",
"binaryFields": "string",
"charset": "string",
"checkInternet": "boolean",
+1 -1
View File
@@ -52,7 +52,7 @@ def dirtyPatches():
_http_client.HTTPConnection.__send_output = _http_client.HTTPConnection._send_output
def _send_output(self, *args, **kwargs):
if conf.chunked and "encode_chunked" in kwargs:
if conf.get("chunked") and "encode_chunked" in kwargs:
kwargs["encode_chunked"] = False
self.__send_output(*args, **kwargs)
+13 -2
View File
@@ -18,7 +18,7 @@ from lib.core.enums import OS
from thirdparty.six import unichr as _unichr
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
VERSION = "1.4.3.0"
VERSION = "1.4.5.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)
@@ -917,7 +917,18 @@ for key, value in os.environ.items():
if key.upper().startswith("%s_" % SQLMAP_ENVIRONMENT_PREFIX):
_ = key[len(SQLMAP_ENVIRONMENT_PREFIX) + 1:].upper()
if _ in globals():
globals()[_] = value
original = globals()[_]
if isinstance(original, int):
try:
globals()[_] = int(value)
except ValueError:
pass
elif isinstance(original, bool):
globals()[_] = value.lower() in ('1', 'true')
elif isinstance(original, (list, tuple)):
globals()[_] = [__.strip() for __ in _.split(',')]
else:
globals()[_] = value
# Installing "reversible" unicode (decoding) error handler
def _reversible(ex):
+3 -4
View File
@@ -18,7 +18,6 @@ import threading
import time
from extra.vulnserver import vulnserver
from lib.core.common import clearColors
from lib.core.common import clearConsoleLine
from lib.core.common import dataToStdout
from lib.core.common import randomInt
@@ -132,7 +131,7 @@ def vulnTest():
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:
dataToStdout("---\n\n$ %s\n" % cmd)
dataToStdout("%s---\n" % clearColors(output))
dataToStdout("%s---\n" % output, coloring=False)
retVal = False
count += 1
@@ -233,7 +232,7 @@ def bedTest():
if check not in output:
print(cmd, check)
dataToStdout("---\n\n$ %s\n" % cmd)
dataToStdout("%s---\n" % clearColors(output))
dataToStdout("%s---\n" % output, coloring=False)
retVal = False
count += 1
@@ -297,7 +296,7 @@ def fuzzTest():
if "Traceback" in output:
dataToStdout("---\n\n$ %s\n" % cmd)
dataToStdout("%s---\n" % clearColors(output))
dataToStdout("%s---\n" % output, coloring=False)
handle, config = tempfile.mkstemp(prefix="sqlmapcrash", suffix=".conf")
os.close(handle)
+1 -1
View File
@@ -101,7 +101,7 @@ def exceptionHandledFunction(threadFunction, silent=False):
except Exception as ex:
from lib.core.common import getSafeExString
if not silent and kb.get("threadContinue") and not isinstance(ex, SqlmapUserQuitException):
if not silent and kb.get("threadContinue") and not kb.get("multipleCtrlC") and not isinstance(ex, SqlmapUserQuitException):
errMsg = getSafeExString(ex) if isinstance(ex, SqlmapBaseException) else "%s: %s" % (type(ex).__name__, getSafeExString(ex))
logger.error("thread %s: '%s'" % (threading.currentThread().getName(), errMsg))
+6 -3
View File
@@ -616,6 +616,9 @@ def cmdLineParser(argv=None):
general.add_argument("--answers", dest="answers",
help="Set predefined answers (e.g. \"quit=N,follow=N\")")
general.add_argument("--base64", dest="base64Parameter",
help="Parameter(s) containing Base64 encoded data")
general.add_argument("--batch", dest="batch", action="store_true",
help="Never ask for user input, use the default behavior")
@@ -746,9 +749,6 @@ def cmdLineParser(argv=None):
help="Simple wizard interface for beginner users")
# Hidden and/or experimental options
parser.add_argument("--base64", dest="base64Parameter",
help=SUPPRESS) # "Parameter(s) containing Base64 encoded values"
parser.add_argument("--crack", dest="hashFile",
help=SUPPRESS) # "Load and crack hashes from a file (standalone)"
@@ -761,6 +761,9 @@ def cmdLineParser(argv=None):
parser.add_argument("--debug", dest="debug", action="store_true",
help=SUPPRESS)
parser.add_argument("--disable-multi", dest="disableMulti", action="store_true",
help=SUPPRESS)
parser.add_argument("--disable-precon", dest="disablePrecon", action="store_true",
help=SUPPRESS)
+2 -2
View File
@@ -83,9 +83,9 @@ from lib.core.enums import WEB_PLATFORM
from lib.core.exception import SqlmapCompressionException
from lib.core.exception import SqlmapConnectionException
from lib.core.exception import SqlmapGenericException
from lib.core.exception import SqlmapSkipTargetException
from lib.core.exception import SqlmapSyntaxException
from lib.core.exception import SqlmapTokenException
from lib.core.exception import SqlmapUserQuitException
from lib.core.exception import SqlmapValueException
from lib.core.settings import ASTERISK_MARKER
from lib.core.settings import BOUNDARY_BACKSLASH_MARKER
@@ -787,7 +787,7 @@ class Connect(object):
kb.connErrorChoice = readInput(message, default='N', boolean=True)
if kb.connErrorChoice is False:
raise SqlmapUserQuitException
raise SqlmapSkipTargetException
if "forcibly closed" in tbMsg:
logger.critical(warnMsg)
+12 -4
View File
@@ -27,6 +27,7 @@ except ImportError:
_protocols = filterNone(getattr(ssl, _, None) for _ in ("PROTOCOL_TLSv1_2", "PROTOCOL_TLSv1_1", "PROTOCOL_TLSv1", "PROTOCOL_SSLv3", "PROTOCOL_SSLv23", "PROTOCOL_SSLv2"))
_lut = dict((getattr(ssl, _), _) for _ in dir(ssl) if _.startswith("PROTOCOL_"))
_contexts = {}
class HTTPSConnection(_http_client.HTTPSConnection):
"""
@@ -36,6 +37,12 @@ class HTTPSConnection(_http_client.HTTPSConnection):
"""
def __init__(self, *args, **kwargs):
# NOTE: Dirty patch for https://bugs.python.org/issue38251 / https://github.com/sqlmapproject/sqlmap/issues/4158
if hasattr(ssl, "_create_default_https_context"):
if None not in _contexts:
_contexts[None] = ssl._create_default_https_context()
kwargs["context"] = _contexts[None]
_http_client.HTTPSConnection.__init__(self, *args, **kwargs)
def connect(self):
@@ -54,11 +61,12 @@ class HTTPSConnection(_http_client.HTTPSConnection):
for protocol in [_ for _ in _protocols if _ >= ssl.PROTOCOL_TLSv1]:
try:
sock = create_sock()
context = ssl.SSLContext(protocol)
_ = context.wrap_socket(sock, do_handshake_on_connect=True, server_hostname=self.host)
if _:
if protocol not in _contexts:
_contexts[protocol] = ssl.SSLContext(protocol)
result = _contexts[protocol].wrap_socket(sock, do_handshake_on_connect=True, server_hostname=self.host)
if result:
success = True
self.sock = _
self.sock = result
_protocols.remove(protocol)
_protocols.insert(0, protocol)
break
+1 -1
View File
@@ -499,7 +499,7 @@ def getValue(expression, blind=True, union=True, error=True, time=True, fromUser
kb.safeCharEncode = False
if not any((kb.testMode, conf.dummy, conf.offline)) and value is None and Backend.getDbms() and conf.dbmsHandler and not conf.noCast and not conf.hexConvert:
if not any((kb.testMode, conf.dummy, conf.offline, conf.noCast, conf.hexConvert)) and value is None and Backend.getDbms() and conf.dbmsHandler and kb.fingerprinted:
warnMsg = "in case of continuous data retrieval problems you are advised to try "
warnMsg += "a switch '--no-cast' "
warnMsg += "or switch '--hex'" if hasattr(queries[Backend.getIdentifiedDbms()], "hex") else ""
+2 -2
View File
@@ -137,7 +137,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
if partialValue:
firstChar = len(partialValue)
elif re.search(r"(?i)(\b|CHAR_)(LENGTH|LEN)\(", expression):
elif re.search(r"(?i)(\b|CHAR_)(LENGTH|LEN|COUNT)\(", expression):
firstChar = 0
elif conf.firstChar is not None and (isinstance(conf.firstChar, int) or (hasattr(conf.firstChar, "isdigit") and conf.firstChar.isdigit())):
firstChar = int(conf.firstChar) - 1
@@ -148,7 +148,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
else:
firstChar = 0
if re.search(r"(?i)(\b|CHAR_)(LENGTH|LEN)\(", expression):
if re.search(r"(?i)(\b|CHAR_)(LENGTH|LEN|COUNT)\(", expression):
lastChar = 0
elif conf.lastChar is not None and (isinstance(conf.lastChar, int) or (hasattr(conf.lastChar, "isdigit") and conf.lastChar.isdigit())):
lastChar = int(conf.lastChar)
+20 -6
View File
@@ -741,7 +741,9 @@ def hashRecognition(value):
if value and len(value) >= 8 and ' ' not in value: # Note: pre-filter condition (for optimization purposes)
isOracle, isMySQL = Backend.isDbms(DBMS.ORACLE), Backend.isDbms(DBMS.MYSQL)
if isinstance(value, six.string_types):
if kb.cache.hashRegex is None:
parts = []
for name, regex in getPublicTypeMembers(HASH):
# Hashes for Oracle and old MySQL look the same hence these checks
if isOracle and regex == HASH.MYSQL_OLD or isMySQL and regex == HASH.ORACLE_OLD:
@@ -749,9 +751,16 @@ def hashRecognition(value):
elif regex == HASH.CRYPT_GENERIC:
if any((value.lower() == value, value.upper() == value)):
continue
elif re.match(regex, value):
retVal = regex
break
else:
parts.append("(?P<%s>%s)" % (name, regex))
kb.cache.hashRegex = ('|'.join(parts)).replace("(?i)", "")
if isinstance(value, six.string_types):
match = re.search(kb.cache.hashRegex, value, re.I)
if match:
algorithm, _ = [_ for _ in match.groupdict().items() if _[1] is not None][0]
retVal = getattr(HASH, algorithm)
return retVal
@@ -913,6 +922,8 @@ def _bruteProcessVariantB(user, hash_, kwargs, hash_regex, suffix, retVal, found
proc_count.value -= 1
def dictionaryAttack(attack_dict):
global _multiprocessing
suffix_list = [""]
custom_wordlist = [""]
hash_regexes = []
@@ -922,6 +933,9 @@ def dictionaryAttack(attack_dict):
processException = False
foundHash = False
if conf.disableMulti:
_multiprocessing = None
for (_, hashes) in attack_dict.items():
for hash_ in hashes:
if not hash_:
@@ -1108,7 +1122,7 @@ def dictionaryAttack(attack_dict):
else:
warnMsg = "multiprocessing hash cracking is currently "
warnMsg += "not supported on this platform"
warnMsg += "%s on this platform" % ("not supported" if not conf.disableMulti else "disabled")
singleTimeWarnMessage(warnMsg)
retVal = _queue.Queue()
@@ -1196,7 +1210,7 @@ def dictionaryAttack(attack_dict):
else:
warnMsg = "multiprocessing hash cracking is currently "
warnMsg += "not supported on this platform"
warnMsg += "%s on this platform" % ("not supported" if not conf.disableMulti else "disabled")
singleTimeWarnMessage(warnMsg)
class Value(object):
-2
View File
@@ -80,8 +80,6 @@ def purge(directory):
pass
logger.debug("deleting the whole directory tree")
os.chdir(os.path.join(directory, ".."))
try:
shutil.rmtree(directory)
except OSError as ex:
+5 -1
View File
@@ -12,6 +12,7 @@ from lib.core.common import checkFile
from lib.core.common import decloakToTemp
from lib.core.common import flattenValue
from lib.core.common import isListLike
from lib.core.common import isNoneValue
from lib.core.common import isStackingAvailable
from lib.core.common import randomStr
from lib.core.data import kb
@@ -105,7 +106,10 @@ class Takeover(GenericTakeover):
output = inject.getValue(query, resumeValue=False)
if isListLike(output):
output = os.linesep.join(flattenValue(output))
output = flattenValue(output)
if not isNoneValue(output):
output = os.linesep.join(output)
self._cleanupCmd = "DROP TABLE %s" % self.cmdTblName
inject.goStacked(self._cleanupCmd)
+3 -5
View File
@@ -450,7 +450,7 @@ class Users(object):
# In PostgreSQL we get 1 if the privilege is
# True, 0 otherwise
if Backend.isDbms(DBMS.PGSQL) and getUnicode(privilege).isdigit():
if int(privilege) == 1:
if int(privilege) == 1 and count in PGSQL_PRIVS:
privileges.add(PGSQL_PRIVS[count])
# In MySQL >= 5.0 and Oracle we get the list
@@ -585,10 +585,8 @@ class Users(object):
i = 1
for priv in privs:
if priv.isdigit() and int(priv) == 1:
for position, pgsqlPriv in PGSQL_PRIVS.items():
if position == i:
privileges.add(pgsqlPriv)
if priv.isdigit() and int(priv) == 1 and i in PGSQL_PRIVS:
privileges.add(PGSQL_PRIVS[i])
i += 1
+3
View File
@@ -693,6 +693,9 @@ trafficFile =
# Set predefined answers (e.g. "quit=N,follow=N").
answers =
# Parameter(s) containing Base64 encoded data
base64Parameter =
# Never ask for user input, use the default behaviour.
# Valid: True or False
batch = False
+6
View File
@@ -335,6 +335,12 @@ def main():
logger.critical(errMsg)
raise SystemExit
elif all(_ in excMsg for _ in ("Resource temporarily unavailable", "os.fork()", "dictionaryAttack")):
errMsg = "there has been a problem while running the multiprocessing hash cracking. "
errMsg += "Please rerun with option '--threads=1'"
logger.critical(errMsg)
raise SystemExit
elif "can't start new thread" in excMsg:
errMsg = "there has been a problem while creating new thread instance. "
errMsg += "Please make sure that you are not running too many processes"