mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-12-06 20:51:31 +00:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3c93872d53 | ||
|
|
881d767df8 | ||
|
|
1156b53eee | ||
|
|
5cacf20eb5 | ||
|
|
1825390951 | ||
|
|
7815f88027 | ||
|
|
f63a92a272 | ||
|
|
e3b3dea46c | ||
|
|
55595edce2 | ||
|
|
aaa0c5c6a8 | ||
|
|
57bb710ae6 | ||
|
|
ce9285381d |
@@ -943,28 +943,31 @@ def setColor(message, color=None, bold=False, level=None, istty=None):
|
||||
|
||||
retVal = message
|
||||
|
||||
if message and (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)
|
||||
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)
|
||||
|
||||
if len(levels) == 1:
|
||||
level = levels[0]
|
||||
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"))
|
||||
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")))
|
||||
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
|
||||
|
||||
@@ -988,6 +991,12 @@ def dataToStdout(data, forceOutput=False, bold=False, contentType=None, status=C
|
||||
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()
|
||||
|
||||
@@ -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 = {}
|
||||
|
||||
@@ -201,6 +201,7 @@ optDict = {
|
||||
"trafficFile": "string",
|
||||
"answers": "string",
|
||||
"batch": "boolean",
|
||||
"base64Parameter": "string",
|
||||
"binaryFields": "string",
|
||||
"charset": "string",
|
||||
"checkInternet": "boolean",
|
||||
|
||||
@@ -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.4.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):
|
||||
|
||||
@@ -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)"
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user