Compare commits

...

12 Commits
1.4.4 ... 1.4.5

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
12 changed files with 94 additions and 46 deletions

View File

@@ -943,28 +943,31 @@ def setColor(message, color=None, bold=False, level=None, istty=None):
retVal = message retVal = message
if message and (IS_TTY or istty) and not conf.get("disableColoring"): # colorizing handler if message:
if level is None: if (IS_TTY or istty) and not conf.get("disableColoring"): # colorizing handler
levels = re.findall(r"\[(?P<result>%s)\]" % '|'.join(_[0] for _ in getPublicTypeMembers(LOGGING_LEVELS)), message) if level is None:
levels = re.findall(r"\[(?P<result>%s)\]" % '|'.join(_[0] for _ in getPublicTypeMembers(LOGGING_LEVELS)), message)
if len(levels) == 1: if len(levels) == 1:
level = levels[0] level = levels[0]
if bold or color: if bold or color:
retVal = colored(message, color=color, on_color=None, attrs=("bold",) if bold else None) retVal = colored(message, color=color, on_color=None, attrs=("bold",) if bold else None)
elif level: elif level:
try: try:
level = getattr(logging, level, None) level = getattr(logging, level, None)
except: except:
level = None level = None
retVal = LOGGER_HANDLER.colorize(message, level) retVal = LOGGER_HANDLER.colorize(message, level)
else: else:
match = re.search(r"\(([^)]*)\s*fork\)", message) match = re.search(r"\(([^)]*)\s*fork\)", message)
if match: if match:
retVal = retVal.replace(match.group(1), colored(match.group(1), color="lightgrey")) 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) 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"))) retVal = retVal.replace(match.group(0), "%s'%s'" % (match.group(1), colored(match.group(2), color="lightgrey")))
message = message.strip()
return retVal return retVal
@@ -988,6 +991,12 @@ def dataToStdout(data, forceOutput=False, bold=False, contentType=None, status=C
Writes text to the stdout (console) stream 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 not kb.get("threadException"):
if forceOutput or not (getCurrentThreadData().disableStdOut or kb.get("wizardMode")): if forceOutput or not (getCurrentThreadData().disableStdOut or kb.get("wizardMode")):
multiThreadMode = isMultiThreadMode() multiThreadMode = isMultiThreadMode()

View File

@@ -371,7 +371,7 @@ def _doSearch():
for link in links: for link in links:
link = urldecode(link) 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)) kb.targets.add((link, conf.method, conf.data, conf.cookie, None))
elif re.search(URI_INJECTABLE_REGEX, link, re.I): elif re.search(URI_INJECTABLE_REGEX, link, re.I):
if kb.data.onlyGETs is None and conf.data is None and not conf.googleDork: if kb.data.onlyGETs is None and conf.data is None and not conf.googleDork:
@@ -387,14 +387,18 @@ def _doSearch():
if kb.targets: if kb.targets:
infoMsg = "found %d results for your " % len(links) infoMsg = "found %d results for your " % len(links)
infoMsg += "search dork expression, " infoMsg += "search dork expression"
if len(links) == len(kb.targets): if not conf.forms:
infoMsg += "all " infoMsg += ", "
else:
infoMsg += "%d " % len(kb.targets) 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) logger.info(infoMsg)
break break
@@ -1867,6 +1871,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.cache.content = {} kb.cache.content = {}
kb.cache.encoding = {} kb.cache.encoding = {}
kb.cache.alphaBoundaries = None kb.cache.alphaBoundaries = None
kb.cache.hashRegex = None
kb.cache.intBoundaries = None kb.cache.intBoundaries = None
kb.cache.parsedDbms = {} kb.cache.parsedDbms = {}
kb.cache.regex = {} kb.cache.regex = {}

View File

@@ -201,6 +201,7 @@ optDict = {
"trafficFile": "string", "trafficFile": "string",
"answers": "string", "answers": "string",
"batch": "boolean", "batch": "boolean",
"base64Parameter": "string",
"binaryFields": "string", "binaryFields": "string",
"charset": "string", "charset": "string",
"checkInternet": "boolean", "checkInternet": "boolean",

View File

@@ -18,7 +18,7 @@ from lib.core.enums import OS
from thirdparty.six import unichr as _unichr from thirdparty.six import unichr as _unichr
# sqlmap version (<major>.<minor>.<month>.<monthly commit>) # sqlmap version (<major>.<minor>.<month>.<monthly commit>)
VERSION = "1.4.4.0" VERSION = "1.4.5.0"
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable" TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34} 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) 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): if key.upper().startswith("%s_" % SQLMAP_ENVIRONMENT_PREFIX):
_ = key[len(SQLMAP_ENVIRONMENT_PREFIX) + 1:].upper() _ = key[len(SQLMAP_ENVIRONMENT_PREFIX) + 1:].upper()
if _ in globals(): 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 # Installing "reversible" unicode (decoding) error handler
def _reversible(ex): def _reversible(ex):

View File

@@ -616,6 +616,9 @@ def cmdLineParser(argv=None):
general.add_argument("--answers", dest="answers", general.add_argument("--answers", dest="answers",
help="Set predefined answers (e.g. \"quit=N,follow=N\")") 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", general.add_argument("--batch", dest="batch", action="store_true",
help="Never ask for user input, use the default behavior") 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") help="Simple wizard interface for beginner users")
# Hidden and/or experimental options # 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", parser.add_argument("--crack", dest="hashFile",
help=SUPPRESS) # "Load and crack hashes from a file (standalone)" help=SUPPRESS) # "Load and crack hashes from a file (standalone)"

View File

@@ -83,9 +83,9 @@ from lib.core.enums import WEB_PLATFORM
from lib.core.exception import SqlmapCompressionException from lib.core.exception import SqlmapCompressionException
from lib.core.exception import SqlmapConnectionException from lib.core.exception import SqlmapConnectionException
from lib.core.exception import SqlmapGenericException from lib.core.exception import SqlmapGenericException
from lib.core.exception import SqlmapSkipTargetException
from lib.core.exception import SqlmapSyntaxException from lib.core.exception import SqlmapSyntaxException
from lib.core.exception import SqlmapTokenException from lib.core.exception import SqlmapTokenException
from lib.core.exception import SqlmapUserQuitException
from lib.core.exception import SqlmapValueException from lib.core.exception import SqlmapValueException
from lib.core.settings import ASTERISK_MARKER from lib.core.settings import ASTERISK_MARKER
from lib.core.settings import BOUNDARY_BACKSLASH_MARKER from lib.core.settings import BOUNDARY_BACKSLASH_MARKER
@@ -787,7 +787,7 @@ class Connect(object):
kb.connErrorChoice = readInput(message, default='N', boolean=True) kb.connErrorChoice = readInput(message, default='N', boolean=True)
if kb.connErrorChoice is False: if kb.connErrorChoice is False:
raise SqlmapUserQuitException raise SqlmapSkipTargetException
if "forcibly closed" in tbMsg: if "forcibly closed" in tbMsg:
logger.critical(warnMsg) logger.critical(warnMsg)

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")) _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_")) _lut = dict((getattr(ssl, _), _) for _ in dir(ssl) if _.startswith("PROTOCOL_"))
_contexts = {}
class HTTPSConnection(_http_client.HTTPSConnection): class HTTPSConnection(_http_client.HTTPSConnection):
""" """
@@ -36,6 +37,12 @@ class HTTPSConnection(_http_client.HTTPSConnection):
""" """
def __init__(self, *args, **kwargs): 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) _http_client.HTTPSConnection.__init__(self, *args, **kwargs)
def connect(self): def connect(self):
@@ -54,11 +61,12 @@ class HTTPSConnection(_http_client.HTTPSConnection):
for protocol in [_ for _ in _protocols if _ >= ssl.PROTOCOL_TLSv1]: for protocol in [_ for _ in _protocols if _ >= ssl.PROTOCOL_TLSv1]:
try: try:
sock = create_sock() sock = create_sock()
context = ssl.SSLContext(protocol) if protocol not in _contexts:
_ = context.wrap_socket(sock, do_handshake_on_connect=True, server_hostname=self.host) _contexts[protocol] = ssl.SSLContext(protocol)
if _: result = _contexts[protocol].wrap_socket(sock, do_handshake_on_connect=True, server_hostname=self.host)
if result:
success = True success = True
self.sock = _ self.sock = result
_protocols.remove(protocol) _protocols.remove(protocol)
_protocols.insert(0, protocol) _protocols.insert(0, protocol)
break break

View File

@@ -137,7 +137,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
if partialValue: if partialValue:
firstChar = len(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 firstChar = 0
elif conf.firstChar is not None and (isinstance(conf.firstChar, int) or (hasattr(conf.firstChar, "isdigit") and conf.firstChar.isdigit())): 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 firstChar = int(conf.firstChar) - 1
@@ -148,7 +148,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
else: else:
firstChar = 0 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 lastChar = 0
elif conf.lastChar is not None and (isinstance(conf.lastChar, int) or (hasattr(conf.lastChar, "isdigit") and conf.lastChar.isdigit())): elif conf.lastChar is not None and (isinstance(conf.lastChar, int) or (hasattr(conf.lastChar, "isdigit") and conf.lastChar.isdigit())):
lastChar = int(conf.lastChar) lastChar = int(conf.lastChar)

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) 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) 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): for name, regex in getPublicTypeMembers(HASH):
# Hashes for Oracle and old MySQL look the same hence these checks # 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: 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: elif regex == HASH.CRYPT_GENERIC:
if any((value.lower() == value, value.upper() == value)): if any((value.lower() == value, value.upper() == value)):
continue continue
elif re.match(regex, value): else:
retVal = regex parts.append("(?P<%s>%s)" % (name, regex))
break
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 return retVal

View File

@@ -80,8 +80,6 @@ def purge(directory):
pass pass
logger.debug("deleting the whole directory tree") logger.debug("deleting the whole directory tree")
os.chdir(os.path.join(directory, ".."))
try: try:
shutil.rmtree(directory) shutil.rmtree(directory)
except OSError as ex: except OSError as ex:

View File

@@ -12,6 +12,7 @@ from lib.core.common import checkFile
from lib.core.common import decloakToTemp from lib.core.common import decloakToTemp
from lib.core.common import flattenValue from lib.core.common import flattenValue
from lib.core.common import isListLike from lib.core.common import isListLike
from lib.core.common import isNoneValue
from lib.core.common import isStackingAvailable from lib.core.common import isStackingAvailable
from lib.core.common import randomStr from lib.core.common import randomStr
from lib.core.data import kb from lib.core.data import kb
@@ -105,7 +106,10 @@ class Takeover(GenericTakeover):
output = inject.getValue(query, resumeValue=False) output = inject.getValue(query, resumeValue=False)
if isListLike(output): 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 self._cleanupCmd = "DROP TABLE %s" % self.cmdTblName
inject.goStacked(self._cleanupCmd) inject.goStacked(self._cleanupCmd)

View File

@@ -693,6 +693,9 @@ trafficFile =
# Set predefined answers (e.g. "quit=N,follow=N"). # Set predefined answers (e.g. "quit=N,follow=N").
answers = answers =
# Parameter(s) containing Base64 encoded data
base64Parameter =
# Never ask for user input, use the default behaviour. # Never ask for user input, use the default behaviour.
# Valid: True or False # Valid: True or False
batch = False batch = False