Compare commits

...

36 Commits
1.3.2 ... 1.3.3

Author SHA1 Message Date
Miroslav Stampar
cdd4007f11 Fixes #3502 2019-03-02 01:28:58 +01:00
Miroslav Stampar
c89c1e7abf Fallback for --randomize in case of empty value 2019-02-28 02:29:13 +01:00
Miroslav Stampar
9ba4da8820 Implements #3500 2019-02-28 02:23:14 +01:00
Miroslav Stampar
58acc4a0bc Fixes #3503 2019-02-28 01:05:23 +01:00
Miroslav Stampar
034bac2a11 Fixes #3498 2019-02-26 01:36:56 +01:00
Miroslav Stampar
581e4103c0 Minor patch 2019-02-25 17:19:42 +01:00
Miroslav Stampar
eb862d03eb Fixes #3496 2019-02-25 17:18:38 +01:00
Miroslav Stampar
1248fe5eee Bug fix (CFM tends to HTML encode non-alphanumeric chars in error reports - paths weren't recognized) 2019-02-21 02:50:11 +01:00
Miroslav Stampar
daeb281e91 Minor update 2019-02-21 02:05:00 +01:00
Miroslav Stampar
514ab3cc30 Trivial update 2019-02-21 01:37:58 +01:00
Miroslav Stampar
dc95558187 Fixes #373 2019-02-21 01:10:43 +01:00
Miroslav Stampar
af890d639d Implementing switch --repair (Issue #2888) 2019-02-19 00:21:37 +01:00
Miroslav Stampar
8fe37f3564 Update for #3486 2019-02-15 17:08:55 +01:00
Miroslav Stampar
9789d65c19 Fixes #3487 2019-02-15 16:54:43 +01:00
Miroslav Stampar
dfe6fe6060 Fixes #3489 2019-02-12 10:49:47 +01:00
Miroslav Stampar
ba883b77df Better exception messages (including types) 2019-02-12 10:42:32 +01:00
Miroslav Stampar
27265f56ba Update for #3488 (found samples with Server: wts) 2019-02-11 15:58:25 +01:00
Miroslav Stampar
ced9657d95 Patch for #3488 2019-02-11 10:53:04 +01:00
Infected Drake
47edf134a2 Create new detection script for WTS Firewall. (#3488) 2019-02-11 10:51:27 +01:00
Miroslav Stampar
8d46f67898 Fixes #3483 2019-02-09 23:27:55 +01:00
Miroslav Stampar
4d87b0ff67 Fixes #3467 and #3463 2019-02-09 23:18:08 +01:00
Miroslav Stampar
6f750f9529 Patch for --os-pwn on newer versions of Metasploit 2019-02-09 16:15:09 +01:00
Miroslav Stampar
9562502744 Potential patch for #3470 2019-02-09 15:49:52 +01:00
Miroslav Stampar
b42c081c0e Fixes #3475 2019-02-09 15:11:06 +01:00
Miroslav Stampar
441a40e6e1 Couple of patches for #3479 2019-02-09 14:49:20 +01:00
Dhiraj Mishra
489390c3f8 ibm_webseal.py (#3479) 2019-02-09 14:44:04 +01:00
Miroslav Stampar
5b382adc15 Trivial PEP update 2019-02-07 17:34:51 +01:00
Miroslav Stampar
ab32ad4f48 Fixes #3471 2019-02-07 17:33:16 +01:00
Miroslav Stampar
0a42d91934 Patch related to the last commit 2019-02-07 16:49:58 +01:00
Miroslav Stampar
5eb9f5729c Couple of patches related to the #3473 2019-02-07 16:45:16 +01:00
Miroslav Stampar
5b0d25ff25 Fixes #3469 2019-02-06 07:35:05 +01:00
Miroslav Stampar
4b00924826 Couple of updates regarding readline capabilities 2019-02-05 16:58:18 +01:00
Miroslav Stampar
f9ee0f4c0a Trivial update 2019-02-05 14:02:52 +01:00
Miroslav Stampar
5077844dd9 Fixes #3468 2019-02-05 13:42:44 +01:00
Miroslav Stampar
6fe827f0a4 Fixes #3465 2019-02-04 16:05:16 +01:00
Miroslav Stampar
683b587fa5 Minor update 2019-02-04 15:54:57 +01:00
32 changed files with 378 additions and 177 deletions

View File

@@ -11,6 +11,7 @@ chmod +x .git/hooks/post-commit
'
SETTINGS="../../lib/core/settings.py"
PYPI="../../extra/shutils/pypi.sh"
declare -x SCRIPTPATH="${0}"
@@ -28,6 +29,6 @@ then
git tag $NEW_TAG
git push origin $NEW_TAG
echo "Going to push PyPI package"
/bin/bash ${SCRIPTPATH%/*}/pypi.sh
/bin/bash ${SCRIPTPATH%/*}/$PYPI
fi
fi

View File

@@ -97,34 +97,84 @@ def action():
raise
if conf.getDbs:
conf.dumper.dbs(conf.dbmsHandler.getDbs())
try:
conf.dumper.dbs(conf.dbmsHandler.getDbs())
except SqlmapNoneDataException as ex:
logger.critical(ex)
except:
raise
if conf.getTables:
conf.dumper.dbTables(conf.dbmsHandler.getTables())
try:
conf.dumper.dbTables(conf.dbmsHandler.getTables())
except SqlmapNoneDataException as ex:
logger.critical(ex)
except:
raise
if conf.commonTables:
conf.dumper.dbTables(tableExists(paths.COMMON_TABLES))
try:
conf.dumper.dbTables(tableExists(paths.COMMON_TABLES))
except SqlmapNoneDataException as ex:
logger.critical(ex)
except:
raise
if conf.getSchema:
conf.dumper.dbTableColumns(conf.dbmsHandler.getSchema(), CONTENT_TYPE.SCHEMA)
try:
conf.dumper.dbTableColumns(conf.dbmsHandler.getSchema(), CONTENT_TYPE.SCHEMA)
except SqlmapNoneDataException as ex:
logger.critical(ex)
except:
raise
if conf.getColumns:
conf.dumper.dbTableColumns(conf.dbmsHandler.getColumns(), CONTENT_TYPE.COLUMNS)
try:
conf.dumper.dbTableColumns(conf.dbmsHandler.getColumns(), CONTENT_TYPE.COLUMNS)
except SqlmapNoneDataException as ex:
logger.critical(ex)
except:
raise
if conf.getCount:
conf.dumper.dbTablesCount(conf.dbmsHandler.getCount())
try:
conf.dumper.dbTablesCount(conf.dbmsHandler.getCount())
except SqlmapNoneDataException as ex:
logger.critical(ex)
except:
raise
if conf.commonColumns:
conf.dumper.dbTableColumns(columnExists(paths.COMMON_COLUMNS))
try:
conf.dumper.dbTableColumns(columnExists(paths.COMMON_COLUMNS))
except SqlmapNoneDataException as ex:
logger.critical(ex)
except:
raise
if conf.dumpTable:
conf.dbmsHandler.dumpTable()
try:
conf.dbmsHandler.dumpTable()
except SqlmapNoneDataException as ex:
logger.critical(ex)
except:
raise
if conf.dumpAll:
conf.dbmsHandler.dumpAll()
try:
conf.dbmsHandler.dumpAll()
except SqlmapNoneDataException as ex:
logger.critical(ex)
except:
raise
if conf.search:
conf.dbmsHandler.search()
try:
conf.dbmsHandler.search()
except SqlmapNoneDataException as ex:
logger.critical(ex)
except:
raise
if conf.query:
conf.dumper.query(conf.query, conf.dbmsHandler.sqlQuery(conf.query))

View File

@@ -491,7 +491,7 @@ def start():
elif parameter in conf.testParameter:
pass
elif parameter == conf.rParam:
elif parameter in conf.rParam:
testSqlInj = False
infoMsg = "skipping randomizing %s parameter '%s'" % (paramType, parameter)

View File

@@ -84,6 +84,7 @@ from lib.core.enums import PLACE
from lib.core.enums import PAYLOAD
from lib.core.enums import REFLECTIVE_COUNTER
from lib.core.enums import SORT_ORDER
from lib.core.exception import SqlmapBaseException
from lib.core.exception import SqlmapDataException
from lib.core.exception import SqlmapGenericException
from lib.core.exception import SqlmapNoneDataException
@@ -146,6 +147,7 @@ from lib.core.settings import PRINTABLE_CHAR_REGEX
from lib.core.settings import PROBLEMATIC_CUSTOM_INJECTION_PATTERNS
from lib.core.settings import PUSH_VALUE_EXCEPTION_RETRY_COUNT
from lib.core.settings import PYVERSION
from lib.core.settings import RANDOMIZATION_TLDS
from lib.core.settings import REFERER_ALIASES
from lib.core.settings import REFLECTED_BORDER_REGEX
from lib.core.settings import REFLECTED_MAX_REGEX_PARTS
@@ -1268,14 +1270,22 @@ def setPaths(rootPath):
paths.SQLMAP_XML_BANNER_PATH = os.path.join(paths.SQLMAP_XML_PATH, "banner")
paths.SQLMAP_XML_PAYLOADS_PATH = os.path.join(paths.SQLMAP_XML_PATH, "payloads")
_ = os.path.join(os.path.expandvars(os.path.expanduser("~")), ".sqlmap")
paths.SQLMAP_HOME_PATH = _
paths.SQLMAP_OUTPUT_PATH = getUnicode(paths.get("SQLMAP_OUTPUT_PATH", os.path.join(_, "output")), encoding=sys.getfilesystemencoding() or UNICODE_ENCODING)
if IS_WIN:
if os.getenv("LOCALAPPDATA"):
paths.SQLMAP_HOME_PATH = os.path.expandvars("%LOCALAPPDATA%\\sqlmap")
elif os.getenv("USERPROFILE"):
paths.SQLMAP_HOME_PATH = os.path.expandvars("%USERPROFILE%\\Local Settings\\sqlmap")
else:
paths.SQLMAP_HOME_PATH = os.path.join(os.path.expandvars(os.path.expanduser("~")), "sqlmap")
else:
paths.SQLMAP_HOME_PATH = os.path.join(os.path.expandvars(os.path.expanduser("~")), ".sqlmap")
paths.SQLMAP_OUTPUT_PATH = getUnicode(paths.get("SQLMAP_OUTPUT_PATH", os.path.join(paths.SQLMAP_HOME_PATH, "output")), encoding=sys.getfilesystemencoding() or UNICODE_ENCODING)
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
paths.SQLMAP_HISTORY_PATH = getUnicode(os.path.join(_, "history"), encoding=sys.getfilesystemencoding() or UNICODE_ENCODING)
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")
paths.SQL_SHELL_HISTORY = os.path.join(paths.SQLMAP_HISTORY_PATH, "sql.hst")
@@ -2986,16 +2996,21 @@ def parseSqliteTableSchema(value):
Parses table column names and types from specified SQLite table schema
"""
retVal = False
if value:
table = {}
columns = {}
for match in re.finditer(r"(\w+)[\"'`]?\s+(INT|INTEGER|TINYINT|SMALLINT|MEDIUMINT|BIGINT|UNSIGNED BIG INT|INT2|INT8|INTEGER|CHARACTER|VARCHAR|VARYING CHARACTER|NCHAR|NATIVE CHARACTER|NVARCHAR|TEXT|CLOB|LONGTEXT|BLOB|NONE|REAL|DOUBLE|DOUBLE PRECISION|FLOAT|REAL|NUMERIC|DECIMAL|BOOLEAN|DATE|DATETIME|NUMERIC)\b", value, re.I):
retVal = True
columns[match.group(1)] = match.group(2)
table[conf.tbl] = columns
table[safeSQLIdentificatorNaming(conf.tbl, True)] = columns
kb.data.cachedColumns[conf.db] = table
return retVal
def getTechniqueData(technique=None):
"""
Returns injection data for technique specified
@@ -3927,6 +3942,14 @@ def randomizeParameterValue(value):
retVal = retVal.replace(original, candidate)
if re.match(r"\A[^@]+@.+\.[a-z]+\Z", value):
parts = retVal.split('.')
parts[-1] = random.sample(RANDOMIZATION_TLDS, 1)[0]
retVal = '.'.join(parts)
if not retVal:
retVal = randomStr(lowercase=True)
return retVal
@cachedmethod
@@ -4767,10 +4790,12 @@ def getSafeExString(ex, encoding=None):
Safe way how to get the proper exception represtation as a string
(Note: errors to be avoided: 1) "%s" % Exception(u'\u0161') and 2) "%s" % str(Exception(u'\u0161'))
>>> getSafeExString(Exception('foobar'))
>>> getSafeExString(SqlmapBaseException('foobar'))
u'foobar'
"""
retVal = None
if getattr(ex, "message", None):
retVal = ex.message
elif getattr(ex, "msg", None):
@@ -4779,8 +4804,11 @@ def getSafeExString(ex, encoding=None):
retVal = ex[1]
elif isinstance(ex, (list, tuple)) and len(ex) > 0 and isinstance(ex[0], basestring):
retVal = ex[0]
else:
if retVal is None:
retVal = str(ex)
elif not isinstance(ex, SqlmapBaseException):
retVal = "%s: %s" % (type(ex).__name__, retVal)
return getUnicode(retVal or "", encoding=encoding).strip()

View File

@@ -120,15 +120,12 @@ class LRUDict(object):
return key in self.cache
def __getitem__(self, key):
try:
value = self.cache.pop(key)
self.cache[key] = value
return value
except KeyError:
return -1
value = self.cache.pop(key)
self.cache[key] = value
return value
def get(self, key):
return self.__getitem__(self, key)
return self.__getitem__(key)
def __setitem__(self, key, value):
try:

View File

@@ -24,12 +24,18 @@ def cachedmethod(f, cache=LRUDict(capacity=MAX_CACHE_ITEMS)):
@functools.wraps(f)
def _(*args, **kwargs):
with _lock:
key = int(hashlib.md5("|".join(str(_) for _ in (f, args, kwargs))).hexdigest(), 16) & 0x7fffffffffffffff
if key not in cache:
cache[key] = f(*args, **kwargs)
key = int(hashlib.md5("|".join(str(_) for _ in (f, args, kwargs))).hexdigest(), 16) & 0x7fffffffffffffff
return cache[key]
try:
with _lock:
result = cache[key]
except KeyError:
result = f(*args, **kwargs)
with _lock:
cache[key] = result
return result
return _

View File

@@ -133,7 +133,7 @@ class Dump(object):
if "\n" in _:
self._write("%s:\n---\n%s\n---" % (header, _))
else:
self._write("%s: %s" % (header, ("'%s'" % _) if isinstance(data, basestring) else _))
self._write("%s: %s" % (header, ("'%s'" % _) if isinstance(data, basestring) else _))
else:
self._write("%s:\tNone" % header)

View File

@@ -156,13 +156,17 @@ class HASH:
# Reference: http://www.zytrax.com/tech/web/mobile_ids.html
class MOBILES:
BLACKBERRY = ("BlackBerry 9900", "Mozilla/5.0 (BlackBerry; U; BlackBerry 9900; en) AppleWebKit/534.11+ (KHTML, like Gecko) Version/7.1.0.346 Mobile Safari/534.11+")
GALAXY = ("Samsung Galaxy S", "Mozilla/5.0 (Linux; U; Android 2.2; en-US; SGH-T959D Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1")
BLACKBERRY = ("BlackBerry Z10", "Mozilla/5.0 (BB10; Kbd) AppleWebKit/537.35+ (KHTML, like Gecko) Version/10.3.3.2205 Mobile Safari/537.35+")
GALAXY = ("Samsung Galaxy S7", "Mozilla/5.0 (Linux; Android 7.0; SM-G930V Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.125 Mobile Safari/537.36")
HP = ("HP iPAQ 6365", "Mozilla/4.0 (compatible; MSIE 4.01; Windows CE; PPC; 240x320; HP iPAQ h6300)")
HTC = ("HTC Sensation", "Mozilla/5.0 (Linux; U; Android 4.0.3; de-ch; HTC Sensation Build/IML74K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30")
IPHONE = ("Apple iPhone 4s", "Mozilla/5.0 (iPhone; CPU iPhone OS 5_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9B179 Safari/7534.48.3")
HTC = ("HTC 10", "Mozilla/5.0 (Linux; Android 8.0.0; HTC 10 Build/OPR1.170623.027) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36")
HUAWEI = ("Huawei P8", "Mozilla/5.0 (Linux; Android 4.4.4; HUAWEI H891L Build/HuaweiH891L) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/33.0.0.0 Mobile Safari/537.36")
IPHONE = ("Apple iPhone 8", "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1")
LUMIA = ("Microsoft Lumia 950", "Mozilla/5.0 (Windows Phone 10.0; Android 6.0.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Mobile Safari/537.36 Edge/15.14977")
NEXUS = ("Google Nexus 7", "Mozilla/5.0 (Linux; Android 4.1.1; Nexus 7 Build/JRO03D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19")
NOKIA = ("Nokia N97", "Mozilla/5.0 (SymbianOS/9.4; Series60/5.0 NokiaN97-1/10.0.012; Profile/MIDP-2.1 Configuration/CLDC-1.1; en-us) AppleWebKit/525 (KHTML, like Gecko) WicKed/7.1.12344")
PIXEL = ("Google Pixel", "Mozilla/5.0 (Linux; Android 8.0.0; Pixel Build/OPR3.170623.013) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Mobile Safari/537.36")
XIAOMI = ("Xiaomi Mi 3", "Mozilla/5.0 (Linux; U; Android 4.4.4; en-gb; MI 3W Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/39.0.0.0 Mobile Safari/537.36 XiaoMi/MiuiBrowser/2.1.1")
class PROXY_TYPE:
HTTP = "HTTP"

View File

@@ -13,7 +13,6 @@ import os
import random
import re
import socket
import string
import sys
import tempfile
import threading
@@ -36,11 +35,13 @@ from lib.core.common import dataToStdout
from lib.core.common import decodeStringEscape
from lib.core.common import getPublicTypeMembers
from lib.core.common import getSafeExString
from lib.core.common import getUnicode
from lib.core.common import findLocalPort
from lib.core.common import findPageForms
from lib.core.common import getConsoleWidth
from lib.core.common import getFileItems
from lib.core.common import getFileType
from lib.core.common import intersect
from lib.core.common import normalizePath
from lib.core.common import ntToPosixSlashes
from lib.core.common import openFile
@@ -547,11 +548,11 @@ def _setMetasploit():
if conf.msfPath:
for path in (conf.msfPath, os.path.join(conf.msfPath, "bin")):
if any(os.path.exists(normalizePath(os.path.join(path, _))) for _ in ("msfcli", "msfconsole")):
if any(os.path.exists(normalizePath(os.path.join(path, "%s%s" % (_, ".bat" if IS_WIN else "")))) for _ in ("msfcli", "msfconsole")):
msfEnvPathExists = True
if all(os.path.exists(normalizePath(os.path.join(path, _))) for _ in ("msfvenom",)):
if all(os.path.exists(normalizePath(os.path.join(path, "%s%s" % (_, ".bat" if IS_WIN else "")))) for _ in ("msfvenom",)):
kb.oldMsf = False
elif all(os.path.exists(normalizePath(os.path.join(path, _))) for _ in ("msfencode", "msfpayload")):
elif all(os.path.exists(normalizePath(os.path.join(path, "%s%s" % (_, ".bat" if IS_WIN else "")))) for _ in ("msfencode", "msfpayload")):
kb.oldMsf = True
else:
msfEnvPathExists = False
@@ -586,11 +587,11 @@ def _setMetasploit():
for envPath in envPaths:
envPath = envPath.replace(";", "")
if any(os.path.exists(normalizePath(os.path.join(envPath, _))) for _ in ("msfcli", "msfconsole")):
if any(os.path.exists(normalizePath(os.path.join(envPath, "%s%s" % (_, ".bat" if IS_WIN else "")))) for _ in ("msfcli", "msfconsole")):
msfEnvPathExists = True
if all(os.path.exists(normalizePath(os.path.join(envPath, _))) for _ in ("msfvenom",)):
if all(os.path.exists(normalizePath(os.path.join(envPath, "%s%s" % (_, ".bat" if IS_WIN else "")))) for _ in ("msfvenom",)):
kb.oldMsf = False
elif all(os.path.exists(normalizePath(os.path.join(envPath, _))) for _ in ("msfencode", "msfpayload")):
elif all(os.path.exists(normalizePath(os.path.join(envPath, "%s%s" % (_, ".bat" if IS_WIN else "")))) for _ in ("msfencode", "msfpayload")):
kb.oldMsf = True
else:
msfEnvPathExists = False
@@ -1277,28 +1278,32 @@ def _setHTTPUserAgent():
file choosed as user option
"""
debugMsg = "setting the HTTP User-Agent header"
logger.debug(debugMsg)
if conf.mobile:
message = "which smartphone do you want sqlmap to imitate "
message += "through HTTP User-Agent header?\n"
items = sorted(getPublicTypeMembers(MOBILES, True))
if conf.randomAgent:
_ = random.sample([_[1] for _ in getPublicTypeMembers(MOBILES, True)], 1)[0]
conf.httpHeaders.append((HTTP_HEADER.USER_AGENT, _))
else:
message = "which smartphone do you want sqlmap to imitate "
message += "through HTTP User-Agent header?\n"
items = sorted(getPublicTypeMembers(MOBILES, True))
for count in xrange(len(items)):
item = items[count]
message += "[%d] %s%s\n" % (count + 1, item[0], " (default)" if item == MOBILES.IPHONE else "")
for count in xrange(len(items)):
item = items[count]
message += "[%d] %s%s\n" % (count + 1, item[0], " (default)" if item == MOBILES.IPHONE else "")
test = readInput(message.rstrip('\n'), default=items.index(MOBILES.IPHONE) + 1)
test = readInput(message.rstrip('\n'), default=items.index(MOBILES.IPHONE) + 1)
try:
item = items[int(test) - 1]
except:
item = MOBILES.IPHONE
try:
item = items[int(test) - 1]
except:
item = MOBILES.IPHONE
conf.httpHeaders.append((HTTP_HEADER.USER_AGENT, item[1]))
conf.httpHeaders.append((HTTP_HEADER.USER_AGENT, item[1]))
elif conf.agent:
debugMsg = "setting the HTTP User-Agent header"
logger.debug(debugMsg)
conf.httpHeaders.append((HTTP_HEADER.USER_AGENT, conf.agent))
elif not conf.randomAgent:
@@ -1412,6 +1417,41 @@ def _checkDependencies():
if conf.dependencies:
checkDependencies()
def _createHomeDirectories():
"""
Creates directories inside sqlmap's home directory
"""
for context in "output", "history":
directory = paths["SQLMAP_%s_PATH" % context.upper()]
try:
if not os.path.isdir(directory):
os.makedirs(directory)
_ = os.path.join(directory, randomStr())
open(_, "w+b").close()
os.remove(_)
if conf.outputDir and context == "output":
warnMsg = "using '%s' as the %s directory" % (directory, context)
logger.warn(warnMsg)
except (OSError, IOError) as ex:
try:
tempDir = tempfile.mkdtemp(prefix="sqlmap%s" % context)
except Exception as _:
errMsg = "unable to write to the temporary directory ('%s'). " % _
errMsg += "Please make sure that your disk is not full and "
errMsg += "that you have sufficient write permissions to "
errMsg += "create temporary files and/or directories"
raise SqlmapSystemException(errMsg)
warnMsg = "unable to %s %s directory " % ("create" if not os.path.isdir(directory) else "write to the", context)
warnMsg += "'%s' (%s). " % (directory, getUnicode(ex))
warnMsg += "Using temporary directory '%s' instead" % getUnicode(tempDir)
logger.warn(warnMsg)
paths["SQLMAP_%s_PATH" % context.upper()] = tempDir
def _createTemporaryDirectory():
"""
Creates temporary directory for this run.
@@ -2416,8 +2456,14 @@ def _basicOptionValidation():
raise SqlmapSyntaxException(errMsg)
if conf.skip and conf.testParameter:
errMsg = "option '--skip' is incompatible with option '-p'"
raise SqlmapSyntaxException(errMsg)
if intersect(conf.skip, conf.testParameter):
errMsg = "option '--skip' is incompatible with option '-p'"
raise SqlmapSyntaxException(errMsg)
if conf.rParam and conf.testParameter:
if intersect(conf.rParam, conf.testParameter):
errMsg = "option '--randomize' is incompatible with option '-p'"
raise SqlmapSyntaxException(errMsg)
if conf.mobile and conf.agent:
errMsg = "switch '--mobile' is incompatible with option '--user-agent'"
@@ -2493,6 +2539,7 @@ def init():
_cleanupEnvironment()
_purge()
_checkDependencies()
_createHomeDirectories()
_createTemporaryDirectory()
_basicOptionValidation()
_setProxyList()

View File

@@ -211,6 +211,7 @@ optDict = {
"hexConvert": "boolean",
"outputDir": "string",
"parseErrors": "boolean",
"repair": "boolean",
"saveConfig": "string",
"scope": "string",
"testFilter": "string",

View File

@@ -56,9 +56,7 @@ if PLATFORM == 'mac' and _readline:
# http://mail.python.org/pipermail/python-dev/2003-August/037845.html
# has the original discussion.
if _readline:
try:
_readline.clear_history()
except AttributeError:
if not hasattr(_readline, "clear_history"):
def clear_history():
pass

View File

@@ -19,7 +19,7 @@ from lib.core.enums import DBMS_DIRECTORY_NAME
from lib.core.enums import OS
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
VERSION = "1.3.2.0"
VERSION = "1.3.3.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)
@@ -185,7 +185,7 @@ MAX_TIME_RESPONSES = 200
MIN_UNION_RESPONSES = 5
# After these number of blanks at the end inference should stop (just in case)
INFERENCE_BLANK_BREAK = 10
INFERENCE_BLANK_BREAK = 5
# Use this replacement character for cases when inference is not able to retrieve the proper character value
INFERENCE_UNKNOWN_CHAR = '?'
@@ -330,7 +330,7 @@ CURRENT_DB = "CD"
SESSION_SQLITE_FILE = "session.sqlite"
# Regular expressions used for finding file paths in error messages
FILE_PATH_REGEXES = (r"<b>(?P<result>[^<>]+?)</b> on line \d+", r"in (?P<result>[^<>'\"]+?)['\"]? on line \d+", r"(?:[>(\[\s])(?P<result>[A-Za-z]:[\\/][\w. \\/-]*)", r"(?:[>(\[\s])(?P<result>/\w[/\w.~-]+)", r"href=['\"]file://(?P<result>/[^'\"]+)")
FILE_PATH_REGEXES = (r"<b>(?P<result>[^<>]+?)</b> on line \d+", r"\bin (?P<result>[^<>'\"]+?)['\"]? on line \d+", r"(?:[>(\[\s])(?P<result>[A-Za-z]:[\\/][\w. \\/-]*)", r"(?:[>(\[\s])(?P<result>/\w[/\w.~-]+)", r"\bhref=['\"]file://(?P<result>/[^'\"]+)", r"\bin <b>(?P<result>[^<]+): line \d+")
# Regular expressions used for parsing error messages (--parse-errors)
ERROR_PARSING_REGEXES = (
@@ -680,6 +680,9 @@ CHECK_ZERO_COLUMNS_THRESHOLD = 10
# Boldify all logger messages containing these "patterns"
BOLD_PATTERNS = ("' injectable", "provided empty", "leftover chars", "might be injectable", "' is vulnerable", "is not injectable", "does not seem to be", "test failed", "test passed", "live test final result", "test shows that", "the back-end DBMS is", "created Github", "blocked by the target server", "protection is involved", "CAPTCHA", "specific response", "NULL connection is supported", "PASSED", "FAILED")
# TLDs used in randomization of email-alike parameter values
RANDOMIZATION_TLDS = ("com", "net", "ru", "org", "de", "jp", "cn", "fr", "it", "pl", "tv", "edu", "in", "ir", "es", "me", "info", "gr", "gov", "ca", "co", "se", "cz", "to", "vn", "nl", "cc", "az", "hu", "ua", "be", "no", "biz", "io", "ch", "ro", "sk", "eu", "us", "tw", "pt", "fi", "at", "lt", "kz", "cl", "hr", "pk", "lv", "la", "pe")
# Generic www root directory names
GENERIC_DOC_ROOT_DIRECTORY_NAMES = ("htdocs", "httpdocs", "public", "wwwroot", "www")
@@ -690,7 +693,7 @@ MAX_HELP_OPTION_LENGTH = 18
MAX_CONNECT_RETRIES = 100
# Strings for detecting formatting errors
FORMAT_EXCEPTION_STRINGS = ("Type mismatch", "Error converting", "Please enter a", "Conversion failed", "String or binary data would be truncated", "Failed to convert", "unable to interpret text value", "Input string was not in a correct format", "System.FormatException", "java.lang.NumberFormatException", "ValueError: invalid literal", "TypeMismatchException", "CF_SQL_INTEGER", " for CFSQLTYPE ", "cfqueryparam cfsqltype", "InvalidParamTypeException", "Invalid parameter type", "is not of type numeric", "<cfif Not IsNumeric(", "invalid input syntax for integer", "invalid input syntax for type", "invalid number", "character to number conversion error", "unable to interpret text value", "String was not recognized as a valid", "Convert.ToInt", "cannot be converted to a ", "InvalidDataException")
FORMAT_EXCEPTION_STRINGS = ("Type mismatch", "Error converting", "Please enter a", "Conversion failed", "String or binary data would be truncated", "Failed to convert", "unable to interpret text value", "Input string was not in a correct format", "System.FormatException", "java.lang.NumberFormatException", "ValueError: invalid literal", "TypeMismatchException", "CF_SQL_INTEGER", "CF_SQL_NUMERIC", " for CFSQLTYPE ", "cfqueryparam cfsqltype", "InvalidParamTypeException", "Invalid parameter type", "Attribute validation error for tag", "is not of type numeric", "<cfif Not IsNumeric(", "invalid input syntax for integer", "invalid input syntax for type", "invalid number", "character to number conversion error", "unable to interpret text value", "String was not recognized as a valid", "Convert.ToInt", "cannot be converted to a ", "InvalidDataException")
# Regular expression used for extracting ASP.NET view state values
VIEWSTATE_REGEX = r'(?i)(?P<name>__VIEWSTATE[^"]*)[^>]+value="(?P<result>[^"]+)'
@@ -773,6 +776,9 @@ BRUTE_DOC_ROOT_PREFIXES = {
OS.WINDOWS: ("/xampp", "/Program Files/xampp", "/wamp", "/Program Files/wampp", "/apache", "/Program Files/Apache Group/Apache", "/Program Files/Apache Group/Apache2", "/Program Files/Apache Group/Apache2.2", "/Program Files/Apache Group/Apache2.4", "/Inetpub/wwwroot", "/Inetpub/wwwroot/%TARGET%", "/Inetpub/vhosts/%TARGET%")
}
# Table prefix to use in "takeover" functionalities (i.e. auxiliary tables used by sqlmap at the vulnerable DBMS)
TAKEOVER_TABLE_PREFIX = "sqlmap"
# Suffixes used in brute force search for web server document root
BRUTE_DOC_ROOT_SUFFIXES = ("", "html", "htdocs", "httpdocs", "php", "public", "src", "site", "build", "web", "www", "data", "sites/all", "www/build")
@@ -809,3 +815,11 @@ th{
font-size:12px;
}
</style>"""
# Leaving (dirty) possibility to change values from here (e.g. `export SQLMAP__MAX_NUMBER_OF_THREADS=20`)
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

View File

@@ -630,36 +630,6 @@ def _createTargetDirs():
Create the output directory.
"""
for context in "output", "history":
directory = paths["SQLMAP_%s_PATH" % context.upper()]
try:
if not os.path.isdir(directory):
os.makedirs(directory)
_ = os.path.join(directory, randomStr())
open(_, "w+b").close()
os.remove(_)
if conf.outputDir and context == "output":
warnMsg = "using '%s' as the %s directory" % (directory, context)
logger.warn(warnMsg)
except (OSError, IOError) as ex:
try:
tempDir = tempfile.mkdtemp(prefix="sqlmap%s" % context)
except Exception as _:
errMsg = "unable to write to the temporary directory ('%s'). " % _
errMsg += "Please make sure that your disk is not full and "
errMsg += "that you have sufficient write permissions to "
errMsg += "create temporary files and/or directories"
raise SqlmapSystemException(errMsg)
warnMsg = "unable to %s %s directory " % ("create" if not os.path.isdir(directory) else "write to the", context)
warnMsg += "'%s' (%s). " % (directory, getUnicode(ex))
warnMsg += "Using temporary directory '%s' instead" % getUnicode(tempDir)
logger.warn(warnMsg)
paths["SQLMAP_%s_PATH" % context.upper()] = tempDir
conf.outputPath = os.path.join(getUnicode(paths.SQLMAP_OUTPUT_PATH), normalizeUnicode(getUnicode(conf.hostname)))
try:

View File

@@ -18,6 +18,7 @@ from lib.core.data import kb
from lib.core.data import logger
from lib.core.datatype import AttribDict
from lib.core.enums import PAYLOAD
from lib.core.exception import SqlmapBaseException
from lib.core.exception import SqlmapConnectionException
from lib.core.exception import SqlmapThreadException
from lib.core.exception import SqlmapUserQuitException
@@ -95,7 +96,8 @@ def exceptionHandledFunction(threadFunction, silent=False):
raise
except Exception as ex:
if not silent and kb.get("threadContinue"):
logger.error("thread %s: %s" % (threading.currentThread().getName(), ex.message))
errMsg = ex.message if isinstance(ex, SqlmapBaseException) else "%s: %s" % (type(ex).__name__, ex.message)
logger.error("thread %s: '%s'" % (threading.currentThread().getName(), errMsg))
if conf.get("verbose") > 1:
traceback.print_exc()

View File

@@ -31,6 +31,7 @@ from lib.core.exception import SqlmapShellQuitException
from lib.core.exception import SqlmapSyntaxException
from lib.core.settings import BASIC_HELP_ITEMS
from lib.core.settings import DUMMY_URL
from lib.core.settings import INFERENCE_UNKNOWN_CHAR
from lib.core.settings import IS_WIN
from lib.core.settings import MAX_HELP_OPTION_LENGTH
from lib.core.settings import VERSION_STRING
@@ -594,6 +595,9 @@ def cmdLineParser(argv=None):
general.add_option("--parse-errors", dest="parseErrors", action="store_true",
help="Parse and display DBMS error messages from responses")
general.add_option("--repair", dest="repair", action="store_true",
help="Redump entries having unknown character marker (%s)" % INFERENCE_UNKNOWN_CHAR)
general.add_option("--save", dest="saveConfig",
help="Save options to a configuration INI file")

View File

@@ -313,43 +313,40 @@ def decodePage(page, contentEncoding, contentType):
# can't do for all responses because we need to support binary files too
if not isinstance(page, unicode) and "text/" in contentType:
if kb.heuristicMode:
kb.pageEncoding = kb.pageEncoding or checkCharEncoding(getHeuristicCharEncoding(page))
page = getUnicode(page, kb.pageEncoding)
else:
# e.g. &#195;&#235;&#224;&#226;&#224;
if "&#" in page:
page = re.sub(r"&#(\d{1,3});", lambda _: chr(int(_.group(1))) if int(_.group(1)) < 256 else _.group(0), page)
# e.g. &#x9;&#195;&#235;&#224;&#226;&#224;
if "&#" in page:
page = re.sub(r"&#x([0-9a-f]{1,2});", lambda _: (_.group(1) if len(_.group(1)) == 2 else "0%s" % _.group(1)).decode("hex"), page)
page = re.sub(r"&#(\d{1,3});", lambda _: chr(int(_.group(1))) if int(_.group(1)) < 256 else _.group(0), page)
# e.g. %20%28%29
if "%" in page:
page = re.sub(r"%([0-9a-fA-F]{2})", lambda _: _.group(1).decode("hex"), page)
# e.g. %20%28%29
if "%" in page:
page = re.sub(r"%([0-9a-fA-F]{2})", lambda _: _.group(1).decode("hex"), page)
# e.g. &amp;
page = re.sub(r"&([^;]+);", lambda _: chr(htmlEntities[_.group(1)]) if htmlEntities.get(_.group(1), 256) < 256 else _.group(0), page)
# e.g. &amp;
page = re.sub(r"&([^;]+);", lambda _: chr(htmlEntities[_.group(1)]) if htmlEntities.get(_.group(1), 256) < 256 else _.group(0), page)
kb.pageEncoding = kb.pageEncoding or checkCharEncoding(getHeuristicCharEncoding(page))
kb.pageEncoding = kb.pageEncoding or checkCharEncoding(getHeuristicCharEncoding(page))
if (kb.pageEncoding or "").lower() == "utf-8-sig":
kb.pageEncoding = "utf-8"
if page and page.startswith("\xef\xbb\xbf"): # Reference: https://docs.python.org/2/library/codecs.html (Note: noticed problems when "utf-8-sig" is left to Python for handling)
page = page[3:]
if (kb.pageEncoding or "").lower() == "utf-8-sig":
kb.pageEncoding = "utf-8"
if page and page.startswith("\xef\xbb\xbf"): # Reference: https://docs.python.org/2/library/codecs.html (Note: noticed problems when "utf-8-sig" is left to Python for handling)
page = page[3:]
page = getUnicode(page, kb.pageEncoding)
page = getUnicode(page, kb.pageEncoding)
# e.g. &#8217;&#8230;&#8482;
if "&#" in page:
def _(match):
retVal = match.group(0)
try:
retVal = unichr(int(match.group(1)))
except (ValueError, OverflowError):
pass
return retVal
page = re.sub(r"&#(\d+);", _, page)
# e.g. &#8217;&#8230;&#8482;
if "&#" in page:
def _(match):
retVal = match.group(0)
try:
retVal = unichr(int(match.group(1)))
except (ValueError, OverflowError):
pass
return retVal
page = re.sub(r"&#(\d+);", _, page)
# e.g. &zeta;
page = re.sub(r"&([^;]+);", lambda _: unichr(htmlEntities[_.group(1)]) if htmlEntities.get(_.group(1), 0) > 255 else _.group(0), page)
# e.g. &zeta;
page = re.sub(r"&([^;]+);", lambda _: unichr(htmlEntities[_.group(1)]) if htmlEntities.get(_.group(1), 0) > 255 else _.group(0), page)
return page

View File

@@ -648,7 +648,7 @@ class Connect(object):
debugMsg = "got HTTP error code: %d (%s)" % (code, status)
logger.debug(debugMsg)
except (urllib2.URLError, socket.error, socket.timeout, httplib.HTTPException, struct.error, binascii.Error, ProxyError, SqlmapCompressionException, WebSocketException, TypeError, ValueError):
except (urllib2.URLError, socket.error, socket.timeout, httplib.HTTPException, struct.error, binascii.Error, ProxyError, SqlmapCompressionException, WebSocketException, TypeError, ValueError, OverflowError):
tbMsg = traceback.format_exc()
if checking:
@@ -1040,10 +1040,10 @@ class Connect(object):
if conf.rParam:
def _randomizeParameter(paramString, randomParameter):
retVal = paramString
match = re.search(r"(\A|\b)%s=(?P<value>[^&;]+)" % re.escape(randomParameter), paramString)
match = re.search(r"(\A|\b)%s=(?P<value>[^&;]*)" % re.escape(randomParameter), paramString)
if match:
origValue = match.group("value")
retVal = re.sub(r"(\A|\b)%s=[^&;]+" % re.escape(randomParameter), "%s=%s" % (randomParameter, randomizeParameterValue(origValue)), paramString)
retVal = re.sub(r"(\A|\b)%s=[^&;]*" % re.escape(randomParameter), "%s=%s" % (randomParameter, randomizeParameterValue(origValue)), paramString)
return retVal
for randomParameter in conf.rParam:

View File

@@ -25,6 +25,7 @@ from lib.core.enums import CUSTOM_LOGGING
from lib.core.enums import DBMS
from lib.core.enums import EXPECTED
from lib.core.enums import TIMEOUT_STATE
from lib.core.settings import TAKEOVER_TABLE_PREFIX
from lib.core.settings import UNICODE_ENCODING
from lib.utils.timeout import timeout
@@ -53,7 +54,7 @@ def direct(query, content=True):
if not select and "EXEC " not in query.upper():
timeout(func=conf.dbmsConnector.execute, args=(query,), duration=conf.timeout, default=None)
elif not (output and "sqlmapoutput" not in query and "sqlmapfile" not in query):
elif not (output and ("%soutput" % TAKEOVER_TABLE_PREFIX) not in query and ("%sfile" % TAKEOVER_TABLE_PREFIX) not in query):
output, state = timeout(func=conf.dbmsConnector.select, args=(query,), duration=conf.timeout, default=None)
if state == TIMEOUT_STATE.NORMAL:
hashDBWrite(query, output, True)

View File

@@ -346,8 +346,13 @@ def getValue(expression, blind=True, union=True, error=True, time=True, fromUser
affected parameter.
"""
if conf.hexConvert:
charsetType = CHARSET_TYPE.HEXADECIMAL
if conf.hexConvert and expected != EXPECTED.BOOL and Backend.getIdentifiedDbms():
if not hasattr(queries[Backend.getIdentifiedDbms()], "hex"):
warnMsg = "switch '--hex' is currently not supported on DBMS %s" % Backend.getIdentifiedDbms()
singleTimeWarnMessage(warnMsg)
conf.hexConvert = False
else:
charsetType = CHARSET_TYPE.HEXADECIMAL
kb.safeCharEncode = safeCharEncode
kb.resumeValues = resumeValue

View File

@@ -558,7 +558,7 @@ class Metasploit:
# For --os-pwn and --os-bof
pwnBofCond = self.connectionStr.startswith("reverse")
pwnBofCond &= "Starting the payload handler" in out
pwnBofCond &= any(_ in out for _ in ("Starting the payload handler", "Started reverse"))
# For --os-smbrelay
smbRelayCond = "Server started" in out

View File

@@ -77,7 +77,7 @@ class Web:
if not cmd:
cmd = conf.osCmd
cmdUrl = "%s?cmd=%s" % (self.webBackdoorUrl, cmd)
cmdUrl = "%s?cmd=%s" % (self.webBackdoorUrl, getUnicode(cmd))
page, _, _ = Request.getPage(url=cmdUrl, direct=True, silent=True, timeout=BACKDOOR_RUN_CMD_TIMEOUT)
if page is not None:

View File

@@ -82,7 +82,9 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
retVal = hashDBRetrieve(expression, checkConf=True)
if retVal:
if PARTIAL_HEX_VALUE_MARKER in retVal:
if conf.repair and INFERENCE_UNKNOWN_CHAR in retVal:
pass
elif PARTIAL_HEX_VALUE_MARKER in retVal:
retVal = retVal.replace(PARTIAL_HEX_VALUE_MARKER, "")
if retVal and conf.hexConvert:
@@ -631,9 +633,12 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
dataToStdout(filterControlChars(val))
# some DBMSes (e.g. Firebird, DB2, etc.) have issues with trailing spaces
if len(partialValue) > INFERENCE_BLANK_BREAK and partialValue[-INFERENCE_BLANK_BREAK:].isspace() and partialValue.strip(' ')[-1:] != '\n':
if len(partialValue) > INFERENCE_BLANK_BREAK and partialValue[-INFERENCE_BLANK_BREAK:].isspace():
finalValue = partialValue[:-INFERENCE_BLANK_BREAK]
break
elif charsetType and partialValue[-1:].isspace():
finalValue = partialValue[:-1]
break
if (lastChar > 0 and index >= lastChar):
finalValue = "" if length == 0 else partialValue

View File

@@ -160,11 +160,11 @@ class Task(object):
saveConfig(self.options, configFile)
if os.path.exists("sqlmap.py"):
self.process = Popen(["python", "sqlmap.py", "--api", "-c", configFile], shell=False, close_fds=not IS_WIN)
self.process = Popen([sys.executable or "python", "sqlmap.py", "--api", "-c", configFile], shell=False, close_fds=not IS_WIN)
elif os.path.exists(os.path.join(os.getcwd(), "sqlmap.py")):
self.process = Popen(["python", "sqlmap.py", "--api", "-c", configFile], shell=False, cwd=os.getcwd(), close_fds=not IS_WIN)
self.process = Popen([sys.executable or "python", "sqlmap.py", "--api", "-c", configFile], shell=False, cwd=os.getcwd(), close_fds=not IS_WIN)
elif os.path.exists(os.path.join(os.path.abspath(os.path.dirname(sys.argv[0])), "sqlmap.py")):
self.process = Popen(["python", "sqlmap.py", "--api", "-c", configFile], shell=False, cwd=os.path.join(os.path.abspath(os.path.dirname(sys.argv[0]))), close_fds=not IS_WIN)
self.process = Popen([sys.executable or "python", "sqlmap.py", "--api", "-c", configFile], shell=False, cwd=os.path.join(os.path.abspath(os.path.dirname(sys.argv[0]))), close_fds=not IS_WIN)
else:
self.process = Popen(["sqlmap", "--api", "-c", configFile], shell=False, close_fds=not IS_WIN)

View File

@@ -622,7 +622,13 @@ class Databases:
index += 1
if Backend.isDbms(DBMS.SQLITE):
parseSqliteTableSchema(unArrayizeValue(values))
if dumpMode and colList:
if conf.db not in kb.data.cachedColumns:
kb.data.cachedColumns[conf.db] = {}
kb.data.cachedColumns[conf.db][safeSQLIdentificatorNaming(conf.tbl, True)] = dict((_, None) for _ in colList)
else:
parseSqliteTableSchema(unArrayizeValue(values))
elif not isNoneValue(values):
table = {}
columns = {}
@@ -718,9 +724,15 @@ class Databases:
query += condQuery
elif Backend.isDbms(DBMS.SQLITE):
query = rootQuery.blind.query % unsafeSQLIdentificatorNaming(tbl)
value = unArrayizeValue(inject.getValue(query, union=False, error=False))
parseSqliteTableSchema(value)
if dumpMode and colList:
if conf.db not in kb.data.cachedColumns:
kb.data.cachedColumns[conf.db] = {}
kb.data.cachedColumns[conf.db][safeSQLIdentificatorNaming(conf.tbl, True)] = dict((_, None) for _ in colList)
else:
query = rootQuery.blind.query % unsafeSQLIdentificatorNaming(tbl)
value = unArrayizeValue(inject.getValue(query, union=False, error=False))
parseSqliteTableSchema(unArrayizeValue(value))
return kb.data.cachedColumns
table = {}
@@ -898,6 +910,7 @@ class Databases:
else:
query = "SELECT %s FROM %s.%s" % (queries[Backend.getIdentifiedDbms()].count.query % '*', safeSQLIdentificatorNaming(db), safeSQLIdentificatorNaming(table, True))
query = agent.whereQuery(query)
count = inject.getValue(query, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)
if isNumPosStrValue(count):

View File

@@ -28,6 +28,7 @@ from lib.core.enums import CHARSET_TYPE
from lib.core.enums import EXPECTED
from lib.core.enums import PAYLOAD
from lib.core.exception import SqlmapUndefinedMethod
from lib.core.settings import TAKEOVER_TABLE_PREFIX
from lib.core.settings import UNICODE_ENCODING
from lib.request import inject
@@ -37,7 +38,7 @@ class Filesystem:
"""
def __init__(self):
self.fileTblName = "sqlmapfile"
self.fileTblName = "%sfile" % TAKEOVER_TABLE_PREFIX
self.tblField = "data"
def _checkFileLength(self, localFile, remoteFile, fileRead=False):

View File

@@ -24,6 +24,7 @@ from lib.core.exception import SqlmapNotVulnerableException
from lib.core.exception import SqlmapSystemException
from lib.core.exception import SqlmapUndefinedMethod
from lib.core.exception import SqlmapUnsupportedDBMSException
from lib.core.settings import TAKEOVER_TABLE_PREFIX
from lib.takeover.abstraction import Abstraction
from lib.takeover.icmpsh import ICMPsh
from lib.takeover.metasploit import Metasploit
@@ -37,7 +38,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
"""
def __init__(self):
self.cmdTblName = "sqlmapoutput"
self.cmdTblName = ("%soutput" % TAKEOVER_TABLE_PREFIX)
self.tblField = "data"
Abstraction.__init__(self)

View File

@@ -725,6 +725,10 @@ outputDir =
# Valid: True or False
parseErrors = False
# Redump entries having unknown character marker (?).
# Valid: True or False
repair = False
# Regular expression for filtering targets from provided Burp.
# or WebScarab proxy log.
# Example: (google|yahoo)

View File

@@ -228,7 +228,7 @@ def main():
logger.critical(errMsg)
raise SystemExit
elif "MemoryError" in excMsg:
elif any(_ in excMsg for _ in ("MemoryError", "Cannot allocate memory")):
errMsg = "memory exhaustion detected"
logger.critical(errMsg)
raise SystemExit

View File

@@ -23,45 +23,45 @@ fb6be55d21a70765e35549af2484f762 extra/sqlharvest/__init__.py
4f82e97b09cc530cb9a92472d0835cea extra/sqlharvest/sqlharvest.py
fb6be55d21a70765e35549af2484f762 extra/wafdetectify/__init__.py
aec73042403993076f478da48066a79e extra/wafdetectify/wafdetectify.py
ec782b9cdb8d857a80b6ecf0f32db7f4 lib/controller/action.py
e6909a3b32fc09c0373101eb58c76538 lib/controller/action.py
d392dbccdb59ac36530c1182675a2609 lib/controller/checks.py
b37a93767459162b30798bd9732a12a3 lib/controller/controller.py
8581acf56b8fb0def50af3707490a834 lib/controller/controller.py
c1da277517c7ec4c23e953a51b51e203 lib/controller/handler.py
fb6be55d21a70765e35549af2484f762 lib/controller/__init__.py
ed7874be0d2d3802f3d20184f2b280d5 lib/core/agent.py
a932126e7d80e545c5d44af178d0bc0c lib/core/bigarray.py
abbe98412255c4856ef30a15da8136a2 lib/core/common.py
9deec4762d61e057b6e069b2538bdcf8 lib/core/common.py
de8d27ae6241163ff9e97aa9e7c51a18 lib/core/convert.py
abcb1121eb56d3401839d14e8ed06b6e lib/core/data.py
e1f7758f433202c50426efde5eb96768 lib/core/datatype.py
1646402a733e564f05025e848b323cf9 lib/core/decorators.py
00828c4455321b6987e3f882f4ef4f92 lib/core/datatype.py
3d547dedebef3be749cf38e4e798e120 lib/core/decorators.py
5f4680b769ae07f22157bd832c97cf8f lib/core/defaults.py
9dfc69ba47209a4ceca494dde9ee8183 lib/core/dicts.py
13ca1a870fa0b01b9593f25e9e93ed9c lib/core/dump.py
5c91145204092b995ed1ac641e9e291d lib/core/enums.py
4ba141124699fd7a763dea82f17fe523 lib/core/dump.py
0a49eaf3f940382464ee08c03c9891a8 lib/core/enums.py
84ef8f32e4582fcc294dc14e1997131d lib/core/exception.py
fb6be55d21a70765e35549af2484f762 lib/core/__init__.py
18c896b157b03af716542e5fe9233ef9 lib/core/log.py
fa9f24e88c81a6cef52da3dd5e637010 lib/core/optiondict.py
9357506018d15f30cffb99a0005d7f1c lib/core/option.py
151136142a14bee82cb02a9ca64c741d lib/core/optiondict.py
7f9d7b65f2278e5d233008a8bdd22c87 lib/core/option.py
fe370021c6bc99daf44b2bfc0d1effb3 lib/core/patch.py
4b12aa67fbf6c973d12e54cf9cb54ea0 lib/core/profiling.py
5e2c16a8e2daee22dd545df13386e7a3 lib/core/readlineng.py
d5ef43fe3cdd6c2602d7db45651f9ceb lib/core/readlineng.py
7d8a22c582ad201f65b73225e4456170 lib/core/replication.py
3179d34f371e0295dd4604568fb30bcd lib/core/revision.py
d6269c55789f78cf707e09a0f5b45443 lib/core/session.py
6b0f9c399579d0b7fdc90a4653d16424 lib/core/settings.py
dd5a87792c98d150cd5d9c85bc086d13 lib/core/settings.py
4483b4a5b601d8f1c4281071dff21ecc lib/core/shell.py
10fd19b0716ed261e6d04f311f6f527c lib/core/subprocessng.py
9c7b5c6397fb3da33e7a4d7876d159c6 lib/core/target.py
43772ea73e9e3d446f782af591cb4eda lib/core/target.py
7857b24b7865ccb4a05283faa596974d lib/core/testing.py
e9788d2992f842cf91ab67389bf4372a lib/core/threads.py
5c369aefa7c5af85dee9212acdf94bbc lib/core/threads.py
2c263c8610667fdc593c50a35ab20f57 lib/core/unescaper.py
54e9cd1968adea11283d44631f0ca400 lib/core/update.py
5b3f08208be0579356f78ce5805d37b2 lib/core/wordlist.py
fb6be55d21a70765e35549af2484f762 lib/__init__.py
4881480d0c1778053908904e04570dc3 lib/parse/banner.py
87a1d50411e74cd0afb2d1bed30f59d4 lib/parse/cmdline.py
b23a0940d21347975a783c63fe671974 lib/parse/cmdline.py
06ccbccb63255c8f1c35950a4c8a6f6b lib/parse/configfile.py
d34df646508c2dceb25205e1316673d1 lib/parse/handler.py
43deb2400e269e602e916efaec7c0903 lib/parse/headers.py
@@ -70,14 +70,14 @@ fb6be55d21a70765e35549af2484f762 lib/parse/__init__.py
adcecd2d6a8667b22872a563eb83eac0 lib/parse/payloads.py
993104046c7d97120613409ef7780c76 lib/parse/sitemap.py
e4ea70bcd461f5176867dcd89d372386 lib/request/basicauthhandler.py
97b7577fdfe3d8537fe9ea3a070d0507 lib/request/basic.py
b23163d485e0dbc038cbf1ba80be11da lib/request/basic.py
fc25d951217077fe655ed2a3a81552ae lib/request/comparison.py
2fde12a95133b26699e26a5c56311c38 lib/request/connect.py
7cba86090b02558f04c6692cef66e772 lib/request/direct.py
2b58b3ed5f3aff7025e02bb1427bc637 lib/request/connect.py
43005bd6a78e9cf0f3ed2283a1cb122e lib/request/direct.py
2b7509ba38a667c61cefff036ec4ca6f lib/request/dns.py
ceac6b3bf1f726f8ff43c6814e9d7281 lib/request/httpshandler.py
fb6be55d21a70765e35549af2484f762 lib/request/__init__.py
338f39808f63af8d4f4afe9e7b0665a2 lib/request/inject.py
f7d80b664678766a4e17486432847fed lib/request/inject.py
52a067bd2fe91ea9395269a684380cbb lib/request/methodrequest.py
ac482ec52227daf48f523827dd67078f lib/request/pkihandler.py
16ff6e078819fe517b1fc0ae3cbc1aa8 lib/request/rangehandler.py
@@ -86,12 +86,12 @@ ac482ec52227daf48f523827dd67078f lib/request/pkihandler.py
eafa28e4beb2b7492dfc8036033ac824 lib/takeover/abstraction.py
ac9efea51eba120b667b4b73536d7f1c lib/takeover/icmpsh.py
fb6be55d21a70765e35549af2484f762 lib/takeover/__init__.py
d55029a4c048e345fbb07a8f91604d83 lib/takeover/metasploit.py
2e14e89af54ea30892c1f426103ab70a lib/takeover/metasploit.py
6b5b841d445b7b973c2e033edfb01b16 lib/takeover/registry.py
ad038ac567f97a4b940b7987792d64a4 lib/takeover/udf.py
915a3fbd557fb136bd0e16c46d993be3 lib/takeover/web.py
f0a809475eb0db95ffbe89fd6ca5bd96 lib/takeover/web.py
1aadcdc058bb813d09ad23d26ea2a6b5 lib/takeover/xp_cmdshell.py
96f120e4299baaea4defd902afc85979 lib/techniques/blind/inference.py
5d402892bf1e9b2c62ab2cfde21a6e11 lib/techniques/blind/inference.py
fb6be55d21a70765e35549af2484f762 lib/techniques/blind/__init__.py
fb6be55d21a70765e35549af2484f762 lib/techniques/dns/__init__.py
ea48db4c48276d7d0e71aa467c0c523f lib/techniques/dns/test.py
@@ -102,7 +102,7 @@ fb6be55d21a70765e35549af2484f762 lib/techniques/__init__.py
fb6be55d21a70765e35549af2484f762 lib/techniques/union/__init__.py
9d9a6148f10693aaab5fac1273d981d4 lib/techniques/union/test.py
e141fb96f2a136bafd6bb2350f02d33b lib/techniques/union/use.py
936e5cb1bc25c69f0716df1c2900f52a lib/utils/api.py
8e9ddc7220f6beda89cc45c65e51e72b lib/utils/api.py
544dee96e782560fe4355cbf6ee19b8c lib/utils/brute.py
b27421eb57cea711050135f84be99258 lib/utils/crawler.py
da4bc159e6920f1f7e45c92c39941690 lib/utils/deps.py
@@ -215,16 +215,16 @@ ec3f406591fc9472f5750bd40993e72e plugins/dbms/sybase/syntax.py
369476221b3059106410de05766227e0 plugins/dbms/sybase/takeover.py
312020bc31ffb0bc6077f62e6fff6e73 plugins/generic/connector.py
d749b7f7b4bcf1f646290dec739f1e6d plugins/generic/custom.py
791db3be35714c9a2e55a7abe9127da4 plugins/generic/databases.py
b5e9bc087d2cc3defcc9e468785a0462 plugins/generic/databases.py
4cf8eb3719c980c54a92f838a999d090 plugins/generic/entries.py
f3624debb8ae6fbcfb5f1b7f1d0743d1 plugins/generic/enumeration.py
cda119b7b0d1afeb60f912009cdb0cf5 plugins/generic/filesystem.py
07733664167a2d082d253c119630d27b plugins/generic/filesystem.py
65e75cd3c2c7acffa6ac13b086e0f383 plugins/generic/fingerprint.py
fb6be55d21a70765e35549af2484f762 plugins/generic/__init__.py
de1928d6865547764ae9a896da4bf1d4 plugins/generic/misc.py
c95bf3dec22cc638100efef99e2ccc3c plugins/generic/search.py
1989f6cbed217f4222dc2dce72992d91 plugins/generic/syntax.py
44c388ea08d4296e2bf2706e19cbe64a plugins/generic/takeover.py
4b539275dcee14683557da4aaf58b36c plugins/generic/takeover.py
f57914512ae22521b988b5094f1a0d6f plugins/generic/users.py
fb6be55d21a70765e35549af2484f762 plugins/__init__.py
5dc693e22f5d020c5c568d7325bd4226 shell/backdoors/backdoor.asp_
@@ -236,7 +236,7 @@ ec2ba8c757ac96425dcd2b97970edd3a shell/stagers/stager.asp_
0c48ddb1feb7e38a951ef05a0d48e032 shell/stagers/stager.jsp_
2f9e459a4cf6a58680978cdce5ff7971 shell/stagers/stager.php_
41522f8ad02ac133ca0aeaab374c36a8 sqlmapapi.py
76998d373c6aef8d36d617a9b21d6eaf sqlmap.py
9693388e705f68e0e307dc225c64ae42 sqlmap.py
772fb3dd15edc9d4055ab9f9dee0c203 tamper/0x2char.py
3d89a5c4c33d4d1d9303f5e3bd11f0ae tamper/apostrophemask.py
1fd0eec63970728c1e6628b2e4c21d81 tamper/apostrophenullencode.py
@@ -473,7 +473,9 @@ ba0fb1e6b815446b9d6f30950900fc80 waf/trafficshield.py
67df54343a85fe053226e2a5483b2c64 waf/wallarm.py
114000c53115fa8f4dd9b1b9122ec32a waf/watchguard.py
a7b8c4c3d1463409e0e204932f0ddff0 waf/webknight.py
053c6b1ea20133bd9f563f1275ddb5a4 waf/webseal.py
ac9e4e3ced77012ed97284634a9ffc74 waf/wordfence.py
512788a2a07f41290f78c9ad0053bd84 waf/wts.py
e69f77220558564785f0b3c961782a93 waf/yundun.py
a560bee3e948b97af2c88805933dcaad waf/yunsuo.py
c8b6517da2c8a28d474956e3a6b8c1ed waf/zenedge.py
@@ -497,4 +499,4 @@ a279656ea3fcb85c727249b02f828383 xml/livetests.xml
82c65823a0af3fccbecf37f1c75f0b29 xml/payloads/stacked_queries.xml
92c41925eba27afeed76bceba6b18be2 xml/payloads/time_blind.xml
ac649aff0e7db413e4937e446e398736 xml/payloads/union_query.xml
7bbf2a82593efffc68e8001299a5691f xml/queries.xml
f20a92b2f037cebf01b916804345399a xml/queries.xml

25
waf/webseal.py Normal file
View File

@@ -0,0 +1,25 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import re
from lib.core.enums import HTTP_HEADER
from lib.core.settings import WAF_ATTACK_VECTORS
__product__ = "WebSEAL (IBM)"
def detect(get_page):
retval = False
for vector in WAF_ATTACK_VECTORS:
page, headers, _ = get_page(get=vector)
retval = re.search(r"WebSEAL", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
retval |= any(_ in (page or "") for _ in ("This is a WebSEAL error message template file", "The Access Manager WebSEAL server received an invalid HTTP request"))
if retval:
break
return retval

25
waf/wts.py Normal file
View File

@@ -0,0 +1,25 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import re
from lib.core.enums import HTTP_HEADER
from lib.core.settings import WAF_ATTACK_VECTORS
__product__ = "WTS Web Application Firewall"
def detect(get_page):
retval = False
for vector in WAF_ATTACK_VECTORS:
page, headers, _ = get_page(get=vector)
retval = ">WTS-WAF" in (page or "")
retval |= re.search(r"\Awts/", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
if retval:
break
return retval

View File

@@ -715,7 +715,7 @@
<inband query="SELECT table_schem,table_name FROM INFORMATION_SCHEMA.SYSTEM_TABLES WHERE %s" condition="table_name" condition2="table_schem"/>
</search_table>
<search_column>
<blind query="SELECT DISTINCT(table_schem) FROM INFORMATION_SCHEMA.SYSTEM_COLUMNS WHERE %s" count="SELECT COUNT(DISTINCT(table_schem)) FROM INFORMATION_SCHEMA.SYSTEM_COLUMNS WHERE %s" condition="column_name" condition2="table_schem" condition3="table_name"/>
<blind query="SELECT DISTINCT(table_schem) FROM INFORMATION_SCHEMA.SYSTEM_COLUMNS WHERE %s" query2="SELECT DISTINCT(table_name) FROM INFORMATION_SCHEMA.SYSTEM_COLUMNS WHERE table_schem='%s'" count="SELECT COUNT(DISTINCT(table_schem)) FROM INFORMATION_SCHEMA.SYSTEM_COLUMNS WHERE %s" count2="SELECT COUNT(DISTINCT(table_name)) FROM INFORMATION_SCHEMA.SYSTEM_COLUMNS WHERE table_schem='%s'" condition="column_name" condition2="table_schem" condition3="table_name"/>
<inband query="SELECT table_schem,table_name FROM INFORMATION_SCHEMA.SYSTEM_COLUMNS WHERE %s" condition="column_name" condition2="table_schem" condition3="table_name"/>
</search_column>
</dbms>