mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-12-06 20:51:31 +00:00
Compare commits
79 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cfe34f61b8 | ||
|
|
c1c7ea33fe | ||
|
|
4458a443ef | ||
|
|
16bd3a1f02 | ||
|
|
a358bc0a38 | ||
|
|
aebae6e27b | ||
|
|
0a3e771b1b | ||
|
|
f82c0497fa | ||
|
|
715763885d | ||
|
|
4aae5d9a9d | ||
|
|
1bc583d358 | ||
|
|
e506a390db | ||
|
|
c5b4af8636 | ||
|
|
c29e47f72f | ||
|
|
4087213501 | ||
|
|
e4725366d3 | ||
|
|
60e8c725f9 | ||
|
|
5dba32b2e1 | ||
|
|
ef04c99069 | ||
|
|
e2fb16c98c | ||
|
|
d2b16c5c91 | ||
|
|
9f0c42dde0 | ||
|
|
78ca371162 | ||
|
|
a35c976759 | ||
|
|
89e9f4939d | ||
|
|
71984fc452 | ||
|
|
a0a6702a4e | ||
|
|
b18444f215 | ||
|
|
7ea524800a | ||
|
|
7960045cf9 | ||
|
|
d253a97a6f | ||
|
|
1475ba441c | ||
|
|
b2585cc8ea | ||
|
|
7b263327cc | ||
|
|
cd31bf4ecb | ||
|
|
1b938c758f | ||
|
|
5a08b71999 | ||
|
|
4b420e7579 | ||
|
|
6b580a682a | ||
|
|
d6e7c2acdc | ||
|
|
4d3aa1605c | ||
|
|
7fe1820ce4 | ||
|
|
98e449e38c | ||
|
|
9acf122ba6 | ||
|
|
2ed144ec85 | ||
|
|
ec0c103952 | ||
|
|
a35d1e5373 | ||
|
|
f5cf22a536 | ||
|
|
38f16decef | ||
|
|
15f86e85b1 | ||
|
|
5217efc69b | ||
|
|
03bbf552ef | ||
|
|
664684ad8f | ||
|
|
ddea0bf6e4 | ||
|
|
1c1f259df4 | ||
|
|
6249823335 | ||
|
|
bad3f80a1c | ||
|
|
529089ba5b | ||
|
|
9851a5703a | ||
|
|
aa9989ff90 | ||
|
|
2a3014b606 | ||
|
|
16d5e22b72 | ||
|
|
a8a6dce38b | ||
|
|
f542e828d2 | ||
|
|
cf182882b1 | ||
|
|
2224ac76aa | ||
|
|
dd5ac6f1e7 | ||
|
|
1e7a453ff6 | ||
|
|
8a84c252be | ||
|
|
138aa6db65 | ||
|
|
121f0376ea | ||
|
|
dfc684640a | ||
|
|
104fbc80af | ||
|
|
cadba37059 | ||
|
|
750d57ec96 | ||
|
|
9a86365d92 | ||
|
|
f794d9d5a5 | ||
|
|
c29db43bfa | ||
|
|
e0eeed0a96 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,3 +3,4 @@ output/
|
||||
.sqlmap_history
|
||||
traffic.txt
|
||||
*~
|
||||
.idea/
|
||||
@@ -361,7 +361,6 @@ This license does not apply to the following components:
|
||||
* The MultipartPost library located under thirdparty/multipartpost/.
|
||||
* The Odict library located under thirdparty/odict/.
|
||||
* The Oset library located under thirdparty/oset/.
|
||||
* The PageRank library located under thirdparty/pagerank/.
|
||||
* The PrettyPrint library located under thirdparty/prettyprint/.
|
||||
* The PyDes library located under thirdparty/pydes/.
|
||||
* The SocksiPy library located under thirdparty/socks/.
|
||||
|
||||
@@ -281,8 +281,6 @@ be bound by the terms and conditions of this License Agreement.
|
||||
|
||||
* The bottle web framework library located under thirdparty/bottle/.
|
||||
Copyright (C) 2012, Marcel Hellkamp.
|
||||
* The PageRank library located under thirdparty/pagerank/.
|
||||
Copyright (C) 2010, Corey Goldberg.
|
||||
* The Termcolor library located under thirdparty/termcolor/.
|
||||
Copyright (C) 2008-2011, Volvox Development Team.
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ then
|
||||
NEW_TAG=$(python -c "import re, sys, time; version = re.search('\"([0-9.]*)\"', sys.argv[1]).group(1); _ = version.split('.'); print '.'.join(_[:-1]) if len(_) == 4 and _[-1] == '0' else ''" "$LINE")
|
||||
if [ -n "$NEW_TAG" ]
|
||||
then
|
||||
git commit -am "Automatic monthly tagging"
|
||||
#git commit -am "Automatic monthly tagging"
|
||||
echo "Creating new tag ${NEW_TAG}"
|
||||
git tag $NEW_TAG
|
||||
git push origin $NEW_TAG
|
||||
|
||||
@@ -107,7 +107,7 @@ If you prefer fetching daily updates, you can download sqlmap by cloning the
|
||||
|
||||
::
|
||||
|
||||
git clone https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
|
||||
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
|
||||
|
||||
sqlmap works out of the box with
|
||||
`Python <http://www.python.org/download/>`__ version **2.6.x** and
|
||||
|
||||
@@ -20,6 +20,7 @@ from lib.core.common import extractRegexResult
|
||||
from lib.core.common import extractTextTagContent
|
||||
from lib.core.common import findDynamicContent
|
||||
from lib.core.common import Format
|
||||
from lib.core.common import getFilteredPageContent
|
||||
from lib.core.common import getLastRequestHTTPError
|
||||
from lib.core.common import getPublicTypeMembers
|
||||
from lib.core.common import getSafeExString
|
||||
@@ -63,6 +64,7 @@ from lib.core.exception import SqlmapConnectionException
|
||||
from lib.core.exception import SqlmapNoneDataException
|
||||
from lib.core.exception import SqlmapSilentQuitException
|
||||
from lib.core.exception import SqlmapUserQuitException
|
||||
from lib.core.settings import CANDIDATE_SENTENCE_MIN_LENGTH
|
||||
from lib.core.settings import DEFAULT_GET_POST_DELIMITER
|
||||
from lib.core.settings import DUMMY_NON_SQLI_CHECK_APPENDIX
|
||||
from lib.core.settings import FI_ERROR_REGEX
|
||||
@@ -478,6 +480,26 @@ def checkSqlInjection(place, parameter, value):
|
||||
|
||||
injectable = True
|
||||
|
||||
elif threadData.lastComparisonRatio > UPPER_RATIO_BOUND and not any((conf.string, conf.notString, conf.regexp, conf.code, kb.nullConnection)):
|
||||
originalSet = set(getFilteredPageContent(kb.pageTemplate, True, "\n").split("\n"))
|
||||
trueSet = set(getFilteredPageContent(truePage, True, "\n").split("\n"))
|
||||
falseSet = set(getFilteredPageContent(falsePage, True, "\n").split("\n"))
|
||||
|
||||
if originalSet == trueSet != falseSet:
|
||||
candidates = trueSet - falseSet
|
||||
|
||||
if candidates:
|
||||
candidates = sorted(candidates, key=lambda _: len(_))
|
||||
for candidate in candidates:
|
||||
if re.match(r"\A[\w.,! ]+\Z", candidate) and ' ' in candidate and len(candidate) > CANDIDATE_SENTENCE_MIN_LENGTH:
|
||||
conf.string = candidate
|
||||
injectable = True
|
||||
|
||||
infoMsg = "%s parameter '%s' appears to be '%s' injectable (with --string=\"%s\")" % (paramType, parameter, title, repr(conf.string).lstrip('u').strip("'"))
|
||||
logger.info(infoMsg)
|
||||
|
||||
break
|
||||
|
||||
if injectable:
|
||||
if kb.pageStable and not any((conf.string, conf.notString, conf.regexp, conf.code, kb.nullConnection)):
|
||||
if all((falseCode, trueCode)) and falseCode != trueCode:
|
||||
|
||||
@@ -65,7 +65,6 @@ from lib.core.settings import REFERER_ALIASES
|
||||
from lib.core.settings import USER_AGENT_ALIASES
|
||||
from lib.core.target import initTargetEnv
|
||||
from lib.core.target import setupTargetEnv
|
||||
from thirdparty.pagerank.pagerank import get_pagerank
|
||||
|
||||
def _selectInjection():
|
||||
"""
|
||||
@@ -163,6 +162,7 @@ def _showInjections():
|
||||
header = "sqlmap resumed the following injection point(s) from stored session"
|
||||
|
||||
if hasattr(conf, "api"):
|
||||
conf.dumper.string("", {"url": conf.url, "query": conf.parameters.get(PLACE.GET), "data": conf.parameters.get(PLACE.POST)}, content_type=CONTENT_TYPE.TARGET)
|
||||
conf.dumper.string("", kb.injections, content_type=CONTENT_TYPE.TECHNIQUES)
|
||||
else:
|
||||
data = "".join(set(_formatInjection(_) for _ in kb.injections)).rstrip("\n")
|
||||
@@ -319,7 +319,7 @@ def start():
|
||||
if conf.forms and conf.method:
|
||||
message = "[#%d] form:\n%s %s" % (hostCount, conf.method, targetUrl)
|
||||
else:
|
||||
message = "URL %d:\n%s %s%s" % (hostCount, HTTPMETHOD.GET, targetUrl, " (PageRank: %s)" % get_pagerank(targetUrl) if conf.googleDork and conf.pageRank else "")
|
||||
message = "URL %d:\n%s %s" % (hostCount, HTTPMETHOD.GET, targetUrl)
|
||||
|
||||
if conf.cookie:
|
||||
message += "\nCookie: %s" % conf.cookie
|
||||
|
||||
@@ -77,11 +77,6 @@ def setHandler():
|
||||
items.insert(0, _)
|
||||
|
||||
for dbms, aliases, Handler, Connector in items:
|
||||
if conf.dbms and conf.dbms.lower() != dbms and conf.dbms.lower() not in aliases:
|
||||
debugMsg = "skipping test for %s" % dbms
|
||||
logger.debug(debugMsg)
|
||||
continue
|
||||
|
||||
handler = Handler()
|
||||
conf.dbmsConnector = Connector()
|
||||
|
||||
@@ -107,6 +102,8 @@ def setHandler():
|
||||
conf.dbmsHandler = max(_ for _ in items if _[0] == kb.resolutionDbms)[2]()
|
||||
else:
|
||||
conf.dbmsHandler = handler
|
||||
|
||||
conf.dbmsHandler._dbms = dbms
|
||||
break
|
||||
else:
|
||||
conf.dbmsConnector = None
|
||||
|
||||
@@ -1079,5 +1079,20 @@ class Agent(object):
|
||||
|
||||
return query
|
||||
|
||||
def whereQuery(self, query):
|
||||
if conf.dumpWhere and query:
|
||||
prefix, suffix = query.split(" ORDER BY ") if " ORDER BY " in query else (query, "")
|
||||
|
||||
if "%s)" % conf.tbl.upper() in prefix.upper():
|
||||
prefix = re.sub(r"(?i)%s\)" % re.escape(conf.tbl), "%s WHERE %s)" % (conf.tbl, conf.dumpWhere), prefix)
|
||||
elif re.search(r"(?i)\bWHERE\b", prefix):
|
||||
prefix += " AND %s" % conf.dumpWhere
|
||||
else:
|
||||
prefix += " WHERE %s" % conf.dumpWhere
|
||||
|
||||
query = "%s ORDER BY %s" % (prefix, suffix) if suffix else prefix
|
||||
|
||||
return query
|
||||
|
||||
# SQL agent
|
||||
agent = Agent()
|
||||
|
||||
@@ -465,6 +465,8 @@ class Backend:
|
||||
|
||||
if not kb:
|
||||
pass
|
||||
elif not kb.get("testMode") and conf.get("dbmsHandler") and getattr(conf.dbmsHandler, "_dbms", None):
|
||||
dbms = conf.dbmsHandler._dbms
|
||||
elif Backend.getForcedDbms() is not None:
|
||||
dbms = Backend.getForcedDbms()
|
||||
elif Backend.getDbms() is not None:
|
||||
@@ -515,10 +517,9 @@ class Backend:
|
||||
# Comparison methods
|
||||
@staticmethod
|
||||
def isDbms(dbms):
|
||||
if Backend.getDbms() is not None:
|
||||
return Backend.getDbms() == aliasToDbmsEnum(dbms)
|
||||
else:
|
||||
return Backend.getIdentifiedDbms() == aliasToDbmsEnum(dbms)
|
||||
if not kb.get("testMode") and all((Backend.getDbms(), Backend.getIdentifiedDbms())) and Backend.getDbms() != Backend.getIdentifiedDbms():
|
||||
singleTimeWarnMessage("identified ('%s') and fingerprinted ('%s') DBMSes differ. If you experience problems in enumeration phase please rerun with '--flush-session'" % (Backend.getIdentifiedDbms(), Backend.getDbms()))
|
||||
return Backend.getIdentifiedDbms() == aliasToDbmsEnum(dbms)
|
||||
|
||||
@staticmethod
|
||||
def isDbmsWithin(aliases):
|
||||
@@ -589,7 +590,7 @@ def paramToDict(place, parameters=None):
|
||||
or re.search(r'\A9{3,}', _) or re.search(r'\A-\d+\Z', _) or re.search(DUMMY_USER_INJECTION, _))\
|
||||
and not parameter.upper().startswith(GOOGLE_ANALYTICS_COOKIE_PREFIX):
|
||||
warnMsg = "it appears that you have provided tainted parameter values "
|
||||
warnMsg += "('%s') with most probably leftover " % element
|
||||
warnMsg += "('%s') with most likely leftover " % element
|
||||
warnMsg += "chars/statements from manual SQL injection test(s). "
|
||||
warnMsg += "Please, always use only valid parameter values "
|
||||
warnMsg += "so sqlmap could be able to run properly"
|
||||
@@ -613,7 +614,8 @@ def paramToDict(place, parameters=None):
|
||||
candidates = OrderedDict()
|
||||
|
||||
def walk(head, current=None):
|
||||
current = current or head
|
||||
if current is None:
|
||||
current = head
|
||||
if isListLike(current):
|
||||
for _ in current:
|
||||
walk(head, _)
|
||||
@@ -621,14 +623,15 @@ def paramToDict(place, parameters=None):
|
||||
for key in current.keys():
|
||||
value = current[key]
|
||||
if isinstance(value, (list, tuple, set, dict)):
|
||||
walk(head, value)
|
||||
if value:
|
||||
walk(head, value)
|
||||
elif isinstance(value, (bool, int, float, basestring)):
|
||||
original = current[key]
|
||||
if isinstance(value, bool):
|
||||
current[key] = "%s%s" % (str(value).lower(), BOUNDED_INJECTION_MARKER)
|
||||
else:
|
||||
current[key] = "%s%s" % (value, BOUNDED_INJECTION_MARKER)
|
||||
candidates["%s (%s)" % (parameter, key)] = json.dumps(deserialized)
|
||||
candidates["%s (%s)" % (parameter, key)] = re.sub("(%s\s*=\s*)%s" % (re.escape(parameter), re.escape(testableParameters[parameter])), r"\g<1>%s" % json.dumps(deserialized), parameters)
|
||||
current[key] = original
|
||||
|
||||
deserialized = json.loads(testableParameters[parameter])
|
||||
@@ -728,7 +731,11 @@ def getManualDirectories():
|
||||
|
||||
directories = normalizePath(directories)
|
||||
|
||||
if directories:
|
||||
if conf.webRoot:
|
||||
directories = [conf.webRoot]
|
||||
infoMsg = "using '%s' as web server document root" % conf.webRoot
|
||||
logger.info(infoMsg)
|
||||
elif directories:
|
||||
infoMsg = "retrieved the web server document root: '%s'" % directories
|
||||
logger.info(infoMsg)
|
||||
else:
|
||||
@@ -1260,7 +1267,7 @@ def parseTargetDirect():
|
||||
remote = False
|
||||
|
||||
for dbms in SUPPORTED_DBMS:
|
||||
details = re.search("^(?P<dbms>%s)://(?P<credentials>(?P<user>.+?)\:(?P<pass>.*)\@)?(?P<remote>(?P<hostname>.+?)\:(?P<port>[\d]+)\/)?(?P<db>[\w\d\ \:\.\_\-\/\\\\]+?)$" % dbms, conf.direct, re.I)
|
||||
details = re.search("^(?P<dbms>%s)://(?P<credentials>(?P<user>.+?)\:(?P<pass>.*)\@)?(?P<remote>(?P<hostname>[\w.-]+?)\:(?P<port>[\d]+)\/)?(?P<db>[\w\d\ \:\.\_\-\/\\\\]+?)$" % dbms, conf.direct, re.I)
|
||||
|
||||
if details:
|
||||
conf.dbms = details.group("dbms")
|
||||
@@ -1491,11 +1498,12 @@ def getLimitRange(count, plusOne=False):
|
||||
count = int(count)
|
||||
limitStart, limitStop = 1, count
|
||||
|
||||
if isinstance(conf.limitStop, int) and conf.limitStop > 0 and conf.limitStop < limitStop:
|
||||
limitStop = conf.limitStop
|
||||
if kb.dumpTable:
|
||||
if isinstance(conf.limitStop, int) and conf.limitStop > 0 and conf.limitStop < limitStop:
|
||||
limitStop = conf.limitStop
|
||||
|
||||
if isinstance(conf.limitStart, int) and conf.limitStart > 0 and conf.limitStart <= limitStop:
|
||||
limitStart = conf.limitStart
|
||||
if isinstance(conf.limitStart, int) and conf.limitStart > 0 and conf.limitStart <= limitStop:
|
||||
limitStart = conf.limitStart
|
||||
|
||||
retVal = xrange(limitStart, limitStop + 1) if plusOne else xrange(limitStart - 1, limitStop)
|
||||
|
||||
@@ -1755,7 +1763,7 @@ def safeStringFormat(format_, params):
|
||||
break
|
||||
return retVal
|
||||
|
||||
def getFilteredPageContent(page, onlyText=True):
|
||||
def getFilteredPageContent(page, onlyText=True, split=" "):
|
||||
"""
|
||||
Returns filtered page content without script, style and/or comments
|
||||
or all HTML tags
|
||||
@@ -1768,10 +1776,10 @@ def getFilteredPageContent(page, onlyText=True):
|
||||
|
||||
# only if the page's charset has been successfully identified
|
||||
if isinstance(page, unicode):
|
||||
retVal = re.sub(r"(?si)<script.+?</script>|<!--.+?-->|<style.+?</style>%s" % (r"|<[^>]+>|\t|\n|\r" if onlyText else ""), " ", page)
|
||||
while retVal.find(" ") != -1:
|
||||
retVal = retVal.replace(" ", " ")
|
||||
retVal = htmlunescape(retVal.strip())
|
||||
retVal = re.sub(r"(?si)<script.+?</script>|<!--.+?-->|<style.+?</style>%s" % (r"|<[^>]+>|\t|\n|\r" if onlyText else ""), split, page)
|
||||
while retVal.find(2 * split) != -1:
|
||||
retVal = retVal.replace(2 * split, split)
|
||||
retVal = htmlunescape(retVal.strip().strip(split))
|
||||
|
||||
return retVal
|
||||
|
||||
@@ -2327,7 +2335,7 @@ def wasLastResponseDBMSError():
|
||||
|
||||
def wasLastResponseHTTPError():
|
||||
"""
|
||||
Returns True if the last web request resulted in an errornous HTTP code (like 500)
|
||||
Returns True if the last web request resulted in an erroneous HTTP code (like 500)
|
||||
"""
|
||||
|
||||
threadData = getCurrentThreadData()
|
||||
@@ -2345,7 +2353,7 @@ def wasLastResponseDelayed():
|
||||
deviation = stdev(kb.responseTimes.get(kb.responseTimeMode, []))
|
||||
threadData = getCurrentThreadData()
|
||||
|
||||
if deviation and not conf.direct:
|
||||
if deviation and not conf.direct and not conf.disableStats:
|
||||
if len(kb.responseTimes[kb.responseTimeMode]) < MIN_TIME_RESPONSES:
|
||||
warnMsg = "time-based standard deviation method used on a model "
|
||||
warnMsg += "with less than %d response times" % MIN_TIME_RESPONSES
|
||||
@@ -2365,7 +2373,10 @@ def wasLastResponseDelayed():
|
||||
|
||||
return retVal
|
||||
else:
|
||||
return (threadData.lastQueryDuration - conf.timeSec) >= 0
|
||||
delta = threadData.lastQueryDuration - conf.timeSec
|
||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL,): # MySQL's SLEEP(X) lasts 0.05 seconds shorter on average
|
||||
delta += 0.05
|
||||
return delta >= 0
|
||||
|
||||
def adjustTimeDelay(lastQueryDuration, lowerStdLimit):
|
||||
"""
|
||||
@@ -2604,7 +2615,7 @@ def getPublicTypeMembers(type_, onlyValues=False):
|
||||
retVal = []
|
||||
|
||||
for name, value in inspect.getmembers(type_):
|
||||
if not name.startswith('__'):
|
||||
if not name.startswith("__"):
|
||||
if not onlyValues:
|
||||
retVal.append((name, value))
|
||||
else:
|
||||
@@ -2664,7 +2675,7 @@ def extractTextTagContent(page):
|
||||
except MemoryError:
|
||||
page = page.replace(REFLECTED_VALUE_MARKER, "")
|
||||
|
||||
return filter(None, (_.group('result').strip() for _ in re.finditer(TEXT_TAG_REGEX, page)))
|
||||
return filter(None, (_.group("result").strip() for _ in re.finditer(TEXT_TAG_REGEX, page)))
|
||||
|
||||
def trimAlphaNum(value):
|
||||
"""
|
||||
@@ -2776,11 +2787,11 @@ def removeDynamicContent(page):
|
||||
if prefix is None and suffix is None:
|
||||
continue
|
||||
elif prefix is None:
|
||||
page = re.sub(r'(?s)^.+%s' % re.escape(suffix), suffix.replace('\\', r'\\'), page)
|
||||
page = re.sub(r"(?s)^.+%s" % re.escape(suffix), suffix.replace('\\', r'\\'), page)
|
||||
elif suffix is None:
|
||||
page = re.sub(r'(?s)%s.+$' % re.escape(prefix), prefix.replace('\\', r'\\'), page)
|
||||
page = re.sub(r"(?s)%s.+$" % re.escape(prefix), prefix.replace('\\', r'\\'), page)
|
||||
else:
|
||||
page = re.sub(r'(?s)%s.+%s' % (re.escape(prefix), re.escape(suffix)), '%s%s' % (prefix.replace('\\', r'\\'), suffix.replace('\\', r'\\')), page)
|
||||
page = re.sub(r"(?s)%s.+%s" % (re.escape(prefix), re.escape(suffix)), "%s%s" % (prefix.replace('\\', r'\\'), suffix.replace('\\', r'\\')), page)
|
||||
|
||||
return page
|
||||
|
||||
@@ -3633,13 +3644,31 @@ def randomizeParameterValue(value):
|
||||
value = re.sub(r"%[0-9a-fA-F]{2}", "", value)
|
||||
|
||||
for match in re.finditer('[A-Z]+', value):
|
||||
retVal = retVal.replace(match.group(), randomStr(len(match.group())).upper())
|
||||
while True:
|
||||
original = match.group()
|
||||
candidate = randomStr(len(match.group())).upper()
|
||||
if original != candidate:
|
||||
break
|
||||
|
||||
retVal = retVal.replace(original, candidate)
|
||||
|
||||
for match in re.finditer('[a-z]+', value):
|
||||
retVal = retVal.replace(match.group(), randomStr(len(match.group())).lower())
|
||||
while True:
|
||||
original = match.group()
|
||||
candidate = randomStr(len(match.group())).lower()
|
||||
if original != candidate:
|
||||
break
|
||||
|
||||
retVal = retVal.replace(original, candidate)
|
||||
|
||||
for match in re.finditer('[0-9]+', value):
|
||||
retVal = retVal.replace(match.group(), str(randomInt(len(match.group()))))
|
||||
while True:
|
||||
original = match.group()
|
||||
candidate = str(randomInt(len(match.group())))
|
||||
if original != candidate:
|
||||
break
|
||||
|
||||
retVal = retVal.replace(original, candidate)
|
||||
|
||||
return retVal
|
||||
|
||||
|
||||
@@ -176,6 +176,7 @@ class HTTP_HEADER:
|
||||
PROXY_CONNECTION = "Proxy-Connection"
|
||||
RANGE = "Range"
|
||||
REFERER = "Referer"
|
||||
REFRESH = "Refresh" # Reference: http://stackoverflow.com/a/283794
|
||||
SERVER = "Server"
|
||||
SET_COOKIE = "Set-Cookie"
|
||||
TRANSFER_ENCODING = "Transfer-Encoding"
|
||||
@@ -286,31 +287,32 @@ class WEB_API:
|
||||
JSP = "jsp"
|
||||
|
||||
class CONTENT_TYPE:
|
||||
TECHNIQUES = 0
|
||||
DBMS_FINGERPRINT = 1
|
||||
BANNER = 2
|
||||
CURRENT_USER = 3
|
||||
CURRENT_DB = 4
|
||||
HOSTNAME = 5
|
||||
IS_DBA = 6
|
||||
USERS = 7
|
||||
PASSWORDS = 8
|
||||
PRIVILEGES = 9
|
||||
ROLES = 10
|
||||
DBS = 11
|
||||
TABLES = 12
|
||||
COLUMNS = 13
|
||||
SCHEMA = 14
|
||||
COUNT = 15
|
||||
DUMP_TABLE = 16
|
||||
SEARCH = 17
|
||||
SQL_QUERY = 18
|
||||
COMMON_TABLES = 19
|
||||
COMMON_COLUMNS = 20
|
||||
FILE_READ = 21
|
||||
FILE_WRITE = 22
|
||||
OS_CMD = 23
|
||||
REG_READ = 24
|
||||
TARGET = 0
|
||||
TECHNIQUES = 1
|
||||
DBMS_FINGERPRINT = 2
|
||||
BANNER = 3
|
||||
CURRENT_USER = 4
|
||||
CURRENT_DB = 5
|
||||
HOSTNAME = 6
|
||||
IS_DBA = 7
|
||||
USERS = 8
|
||||
PASSWORDS = 9
|
||||
PRIVILEGES = 10
|
||||
ROLES = 11
|
||||
DBS = 12
|
||||
TABLES = 13
|
||||
COLUMNS = 14
|
||||
SCHEMA = 15
|
||||
COUNT = 16
|
||||
DUMP_TABLE = 17
|
||||
SEARCH = 18
|
||||
SQL_QUERY = 19
|
||||
COMMON_TABLES = 20
|
||||
COMMON_COLUMNS = 21
|
||||
FILE_READ = 22
|
||||
FILE_WRITE = 23
|
||||
OS_CMD = 24
|
||||
REG_READ = 25
|
||||
|
||||
PART_RUN_CONTENT_TYPES = {
|
||||
"checkDbms": CONTENT_TYPE.TECHNIQUES,
|
||||
|
||||
@@ -897,20 +897,25 @@ def _setTamperingFunctions():
|
||||
for script in re.split(PARAMETER_SPLITTING_REGEX, conf.tamper):
|
||||
found = False
|
||||
|
||||
path = paths.SQLMAP_TAMPER_PATH.encode(sys.getfilesystemencoding() or UNICODE_ENCODING)
|
||||
script = script.strip().encode(sys.getfilesystemencoding() or UNICODE_ENCODING)
|
||||
|
||||
if not script:
|
||||
continue
|
||||
try:
|
||||
if not script:
|
||||
continue
|
||||
|
||||
elif os.path.exists(os.path.join(paths.SQLMAP_TAMPER_PATH, script if script.endswith(".py") else "%s.py" % script)):
|
||||
script = os.path.join(paths.SQLMAP_TAMPER_PATH, script if script.endswith(".py") else "%s.py" % script)
|
||||
elif os.path.exists(os.path.join(path, script if script.endswith(".py") else "%s.py" % script)):
|
||||
script = os.path.join(path, script if script.endswith(".py") else "%s.py" % script)
|
||||
|
||||
elif not os.path.exists(script):
|
||||
errMsg = "tamper script '%s' does not exist" % script
|
||||
raise SqlmapFilePathException(errMsg)
|
||||
elif not os.path.exists(script):
|
||||
errMsg = "tamper script '%s' does not exist" % script
|
||||
raise SqlmapFilePathException(errMsg)
|
||||
|
||||
elif not script.endswith(".py"):
|
||||
errMsg = "tamper script '%s' should have an extension '.py'" % script
|
||||
elif not script.endswith(".py"):
|
||||
errMsg = "tamper script '%s' should have an extension '.py'" % script
|
||||
raise SqlmapSyntaxException(errMsg)
|
||||
except UnicodeDecodeError:
|
||||
errMsg = "invalid character provided in option '--tamper'"
|
||||
raise SqlmapSyntaxException(errMsg)
|
||||
|
||||
dirname, filename = os.path.split(script)
|
||||
@@ -928,7 +933,7 @@ def _setTamperingFunctions():
|
||||
sys.path.insert(0, dirname)
|
||||
|
||||
try:
|
||||
module = __import__(filename[:-3])
|
||||
module = __import__(filename[:-3].encode(sys.getfilesystemencoding() or UNICODE_ENCODING))
|
||||
except (ImportError, SyntaxError), ex:
|
||||
raise SqlmapSyntaxException("cannot import tamper script '%s' (%s)" % (filename[:-3], getSafeExString(ex)))
|
||||
|
||||
@@ -1001,7 +1006,7 @@ def _setWafFunctions():
|
||||
try:
|
||||
if filename[:-3] in sys.modules:
|
||||
del sys.modules[filename[:-3]]
|
||||
module = __import__(filename[:-3])
|
||||
module = __import__(filename[:-3].encode(sys.getfilesystemencoding() or UNICODE_ENCODING))
|
||||
except ImportError, msg:
|
||||
raise SqlmapSyntaxException("cannot import WAF script '%s' (%s)" % (filename[:-3], msg))
|
||||
|
||||
@@ -2319,7 +2324,7 @@ def _setProxyList():
|
||||
return
|
||||
|
||||
conf.proxyList = []
|
||||
for match in re.finditer(r"(?i)((http[^:]*|socks[^:]*)://)?([\w.]+):(\d+)", readCachedFileContent(conf.proxyFile)):
|
||||
for match in re.finditer(r"(?i)((http[^:]*|socks[^:]*)://)?([\w\-.]+):(\d+)", readCachedFileContent(conf.proxyFile)):
|
||||
_, type_, address, port = match.groups()
|
||||
conf.proxyList.append("%s://%s:%s" % (type_ or "http", address, port))
|
||||
|
||||
|
||||
@@ -225,11 +225,11 @@ optDict = {
|
||||
"identifyWaf": "boolean",
|
||||
"mobile": "boolean",
|
||||
"offline": "boolean",
|
||||
"pageRank": "boolean",
|
||||
"purgeOutput": "boolean",
|
||||
"skipWaf": "boolean",
|
||||
"smart": "boolean",
|
||||
"tmpDir": "string",
|
||||
"webRoot": "string",
|
||||
"wizard": "boolean",
|
||||
"verbose": "integer",
|
||||
},
|
||||
|
||||
@@ -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.1"
|
||||
VERSION = "1.1.4.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)
|
||||
@@ -109,7 +109,7 @@ DUMMY_SEARCH_USER_AGENT = "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:49.0) Geck
|
||||
TEXT_TAG_REGEX = r"(?si)<(abbr|acronym|b|blockquote|br|center|cite|code|dt|em|font|h\d|i|li|p|pre|q|strong|sub|sup|td|th|title|tt|u)(?!\w).*?>(?P<result>[^<]+)"
|
||||
|
||||
# Regular expression used for recognition of IP addresses
|
||||
IP_ADDRESS_REGEX = r"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b"
|
||||
IP_ADDRESS_REGEX = r"\b(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\b"
|
||||
|
||||
# Regular expression used for recognition of generic "your ip has been blocked" messages
|
||||
BLOCKED_IP_REGEX = r"(?i)(\A|\b)ip\b.*\b(banned|blocked|block list|firewall)"
|
||||
@@ -303,6 +303,7 @@ ERROR_PARSING_REGEXES = (
|
||||
r"(?m)^(fatal|error|warning|exception):?\s*(?P<result>[^\n]+?)$",
|
||||
r"(?P<result>[^\n>]*SQL Syntax[^\n<]+)",
|
||||
r"<li>Error Type:<br>(?P<result>.+?)</li>",
|
||||
r"CDbCommand (?P<result>[^<>\n]*SQL[^<>\n]+)",
|
||||
r"error '[0-9a-f]{8}'((<[^>]+>)|\s)+(?P<result>[^<>]+)",
|
||||
r"\[[^\n\]]+(ODBC|JDBC)[^\n\]]+\](\[[^\]]+\])?(?P<result>[^\n]+(in query expression|\(SQL| at /[^ ]+pdo)[^\n<]+)"
|
||||
)
|
||||
@@ -358,6 +359,9 @@ MIN_RATIO = 0.0
|
||||
# Maximum value for comparison ratio
|
||||
MAX_RATIO = 1.0
|
||||
|
||||
# Minimum length of sentence for automatic choosing of --string (in case of high matching ratio)
|
||||
CANDIDATE_SENTENCE_MIN_LENGTH = 10
|
||||
|
||||
# Character used for marking injectable position inside provided data
|
||||
CUSTOM_INJECTION_MARK_CHAR = '*'
|
||||
|
||||
@@ -587,7 +591,7 @@ BANNER = re.sub(r"\[.\]", lambda _: "[\033[01;41m%s\033[01;49m]" % random.sample
|
||||
DUMMY_NON_SQLI_CHECK_APPENDIX = "<'\">"
|
||||
|
||||
# Regular expression used for recognition of file inclusion errors
|
||||
FI_ERROR_REGEX = "(?i)[^\n]*(no such file|failed (to )?open)[^\n]*"
|
||||
FI_ERROR_REGEX = "(?i)[^\n]{0,100}(no such file|failed (to )?open)[^\n]{0,100}"
|
||||
|
||||
# Length of prefix and suffix used in non-SQLI heuristic checks
|
||||
NON_SQLI_CHECK_PREFIX_SUFFIX_LENGTH = 6
|
||||
@@ -692,7 +696,7 @@ MAX_HISTORY_LENGTH = 1000
|
||||
MIN_ENCODED_LEN_CHECK = 5
|
||||
|
||||
# Timeout in seconds in which Metasploit remote session has to be initialized
|
||||
METASPLOIT_SESSION_TIMEOUT = 300
|
||||
METASPLOIT_SESSION_TIMEOUT = 120
|
||||
|
||||
# Reference: http://www.postgresql.org/docs/9.0/static/catalog-pg-largeobject.html
|
||||
LOBLKSIZE = 2048
|
||||
|
||||
@@ -7,12 +7,11 @@ See the file 'doc/COPYING' for copying permission
|
||||
|
||||
import difflib
|
||||
import random
|
||||
import thread
|
||||
import threading
|
||||
import time
|
||||
import traceback
|
||||
|
||||
from thread import error as ThreadError
|
||||
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
from lib.core.data import logger
|
||||
@@ -47,6 +46,7 @@ class _ThreadData(threading.local):
|
||||
self.lastComparisonPage = None
|
||||
self.lastComparisonHeaders = None
|
||||
self.lastComparisonCode = None
|
||||
self.lastComparisonRatio = None
|
||||
self.lastErrorPage = None
|
||||
self.lastHTTPError = None
|
||||
self.lastRedirectMsg = None
|
||||
@@ -151,7 +151,7 @@ def runThreads(numThreads, threadFunction, cleanupFunction=None, forwardExceptio
|
||||
|
||||
try:
|
||||
thread.start()
|
||||
except ThreadError, ex:
|
||||
except thread.error, ex:
|
||||
errMsg = "error occurred while starting new thread ('%s')" % ex.message
|
||||
logger.critical(errMsg)
|
||||
break
|
||||
|
||||
@@ -482,10 +482,10 @@ def cmdLineParser(argv=None):
|
||||
help="Use WHERE condition while table dumping")
|
||||
|
||||
enumeration.add_option("--start", dest="limitStart", type="int",
|
||||
help="First query output entry to retrieve")
|
||||
help="First dump table entry to retrieve")
|
||||
|
||||
enumeration.add_option("--stop", dest="limitStop", type="int",
|
||||
help="Last query output entry to retrieve")
|
||||
help="Last dump table entry to retrieve")
|
||||
|
||||
enumeration.add_option("--first", dest="firstChar", type="int",
|
||||
help="First query output word character to retrieve")
|
||||
@@ -738,10 +738,6 @@ def cmdLineParser(argv=None):
|
||||
action="store_true",
|
||||
help="Work in offline mode (only use session data)")
|
||||
|
||||
miscellaneous.add_option("--page-rank", dest="pageRank",
|
||||
action="store_true",
|
||||
help="Display page rank (PR) for Google dork results")
|
||||
|
||||
miscellaneous.add_option("--purge-output", dest="purgeOutput",
|
||||
action="store_true",
|
||||
help="Safely remove all content from output directory")
|
||||
@@ -760,6 +756,9 @@ def cmdLineParser(argv=None):
|
||||
miscellaneous.add_option("--tmp-dir", dest="tmpDir",
|
||||
help="Local directory for storing temporary files")
|
||||
|
||||
miscellaneous.add_option("--web-root", dest="webRoot",
|
||||
help="Web server document root directory (e.g. \"/var/www\")")
|
||||
|
||||
miscellaneous.add_option("--wizard", dest="wizard",
|
||||
action="store_true",
|
||||
help="Simple wizard interface for beginner users")
|
||||
@@ -777,6 +776,9 @@ def cmdLineParser(argv=None):
|
||||
parser.add_option("--disable-precon", dest="disablePrecon", action="store_true",
|
||||
help=SUPPRESS_HELP)
|
||||
|
||||
parser.add_option("--disable-stats", dest="disableStats", action="store_true",
|
||||
help=SUPPRESS_HELP)
|
||||
|
||||
parser.add_option("--profile", dest="profile", action="store_true",
|
||||
help=SUPPRESS_HELP)
|
||||
|
||||
@@ -900,6 +902,9 @@ def cmdLineParser(argv=None):
|
||||
elif len(argv[i]) > 1 and all(ord(_) in xrange(0x2018, 0x2020) for _ in ((argv[i].split('=', 1)[-1].strip() or ' ')[0], argv[i][-1])):
|
||||
dataToStdout("[!] copy-pasting illegal (non-console) quote characters from Internet is, well, illegal (%s)\n" % argv[i])
|
||||
raise SystemExit
|
||||
elif len(argv[i]) > 1 and u"\uff0c" in argv[i].split('=', 1)[-1]:
|
||||
dataToStdout("[!] copy-pasting illegal (non-console) comma characters from Internet is, well, illegal (%s)\n" % argv[i])
|
||||
raise SystemExit
|
||||
elif re.search(r"\A-\w=.+", argv[i]):
|
||||
dataToStdout("[!] potentially miswritten (illegal '=') short option detected ('%s')\n" % argv[i])
|
||||
raise SystemExit
|
||||
|
||||
@@ -14,13 +14,14 @@ from lib.core.common import UnicodeRawConfigParser
|
||||
from lib.core.data import cmdLineOptions
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import logger
|
||||
from lib.core.enums import OPTION_TYPE
|
||||
from lib.core.exception import SqlmapMissingMandatoryOptionException
|
||||
from lib.core.exception import SqlmapSyntaxException
|
||||
from lib.core.optiondict import optDict
|
||||
|
||||
config = None
|
||||
|
||||
def configFileProxy(section, option, boolean=False, integer=False):
|
||||
def configFileProxy(section, option, datatype):
|
||||
"""
|
||||
Parse configuration file and save settings into the configuration
|
||||
advanced dictionary.
|
||||
@@ -30,10 +31,12 @@ def configFileProxy(section, option, boolean=False, integer=False):
|
||||
|
||||
if config.has_option(section, option):
|
||||
try:
|
||||
if boolean:
|
||||
if datatype == OPTION_TYPE.BOOLEAN:
|
||||
value = config.getboolean(section, option) if config.get(section, option) else False
|
||||
elif integer:
|
||||
elif datatype == OPTION_TYPE.INTEGER:
|
||||
value = config.getint(section, option) if config.get(section, option) else 0
|
||||
elif datatype == OPTION_TYPE.FLOAT:
|
||||
value = config.getfloat(section, option) if config.get(section, option) else 0.0
|
||||
else:
|
||||
value = config.get(section, option)
|
||||
except ValueError, ex:
|
||||
@@ -91,8 +94,4 @@ def configFileParser(configFile):
|
||||
for family, optionData in optDict.items():
|
||||
for option, datatype in optionData.items():
|
||||
datatype = unArrayizeValue(datatype)
|
||||
|
||||
boolean = datatype == "boolean"
|
||||
integer = datatype == "integer"
|
||||
|
||||
configFileProxy(family, option, boolean, integer)
|
||||
configFileProxy(family, option, datatype)
|
||||
|
||||
@@ -102,7 +102,7 @@ def forgeHeaders(items=None):
|
||||
message = "you provided a HTTP %s header value. " % HTTP_HEADER.COOKIE
|
||||
message += "The target URL provided its own cookies within "
|
||||
message += "the HTTP %s header which intersect with yours. " % HTTP_HEADER.SET_COOKIE
|
||||
message += "Do you want to merge them in futher requests? [Y/n] "
|
||||
message += "Do you want to merge them in further requests? [Y/n] "
|
||||
_ = readInput(message, default="Y")
|
||||
kb.mergeCookies = not _ or _[0] in ("y", "Y")
|
||||
|
||||
@@ -168,6 +168,8 @@ def checkCharEncoding(encoding, warn=True):
|
||||
encoding = encoding.replace("8858", "8859") # iso-8858 -> iso-8859
|
||||
elif "8559" in encoding:
|
||||
encoding = encoding.replace("8559", "8859") # iso-8559 -> iso-8859
|
||||
elif "8895" in encoding:
|
||||
encoding = encoding.replace("8895", "8859") # iso-8895 -> iso-8859
|
||||
elif "5889" in encoding:
|
||||
encoding = encoding.replace("5889", "8859") # iso-5889 -> iso-8859
|
||||
elif "5589" in encoding:
|
||||
@@ -314,6 +316,12 @@ def decodePage(page, contentEncoding, contentType):
|
||||
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))
|
||||
|
||||
if kb.pageEncoding and kb.pageEncoding.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)
|
||||
|
||||
# e.g. ’…™
|
||||
@@ -363,7 +371,7 @@ def processResponse(page, responseHeaders):
|
||||
if readInput(msg, default='N').strip().upper() != 'Y':
|
||||
continue
|
||||
conf.paramDict[PLACE.POST][name] = value
|
||||
conf.parameters[PLACE.POST] = re.sub("(?i)(%s=)[^&]+" % name, r"\g<1>%s" % value, conf.parameters[PLACE.POST])
|
||||
conf.parameters[PLACE.POST] = re.sub("(?i)(%s=)[^&]+" % re.escape(name), r"\g<1>%s" % re.escape(value), conf.parameters[PLACE.POST])
|
||||
|
||||
if not kb.captchaDetected and re.search(r"(?i)captcha", page or ""):
|
||||
for match in re.finditer(r"(?si)<form.+?</form>", page):
|
||||
|
||||
@@ -144,6 +144,9 @@ def _comparison(page, headers, code, getRatioValue, pageLength):
|
||||
kb.matchRatio = ratio
|
||||
logger.debug("setting match ratio for current parameter to %.3f" % kb.matchRatio)
|
||||
|
||||
if kb.testMode:
|
||||
threadData.lastComparisonRatio = ratio
|
||||
|
||||
# If it has been requested to return the ratio and not a comparison
|
||||
# response
|
||||
if getRatioValue:
|
||||
|
||||
@@ -146,9 +146,9 @@ class Connect(object):
|
||||
if kb.testMode and kb.previousMethod == PAYLOAD.METHOD.TIME:
|
||||
# timed based payloads can cause web server unresponsiveness
|
||||
# if the injectable piece of code is some kind of JOIN-like query
|
||||
warnMsg = "most probably web server instance hasn't recovered yet "
|
||||
warnMsg = "most likely web server instance hasn't recovered yet "
|
||||
warnMsg += "from previous timed based payload. If the problem "
|
||||
warnMsg += "persists please wait for few minutes and rerun "
|
||||
warnMsg += "persists please wait for a few minutes and rerun "
|
||||
warnMsg += "without flag 'T' in option '--technique' "
|
||||
warnMsg += "(e.g. '--flush-session --technique=BEUS') or try to "
|
||||
warnMsg += "lower the value of option '--time-sec' (e.g. '--time-sec=2')"
|
||||
@@ -374,9 +374,7 @@ class Connect(object):
|
||||
|
||||
# Reset header values to original in case of provided request file
|
||||
if target and conf.requestFile:
|
||||
headers = OrderedDict(conf.httpHeaders)
|
||||
if cookie:
|
||||
headers[HTTP_HEADER.COOKIE] = cookie
|
||||
headers = forgeHeaders({HTTP_HEADER.COOKIE: cookie})
|
||||
|
||||
if auxHeaders:
|
||||
for key, value in auxHeaders.items():
|
||||
@@ -475,7 +473,7 @@ class Connect(object):
|
||||
return conn, None, None
|
||||
|
||||
# Get HTTP response
|
||||
if hasattr(conn, 'redurl'):
|
||||
if hasattr(conn, "redurl"):
|
||||
page = (threadData.lastRedirectMsg[1] if kb.redirectChoice == REDIRECTION.NO\
|
||||
else Connect._connReadProxy(conn)) if not skipRead else None
|
||||
skipLogTraffic = kb.redirectChoice == REDIRECTION.NO
|
||||
@@ -483,45 +481,54 @@ class Connect(object):
|
||||
else:
|
||||
page = Connect._connReadProxy(conn) if not skipRead else None
|
||||
|
||||
code = code or (conn.code if conn else None)
|
||||
responseHeaders = conn.info()
|
||||
responseHeaders[URI_HTTP_HEADER] = conn.geturl()
|
||||
if conn:
|
||||
code = conn.code
|
||||
responseHeaders = conn.info()
|
||||
responseHeaders[URI_HTTP_HEADER] = conn.geturl()
|
||||
else:
|
||||
code = None
|
||||
responseHeaders = {}
|
||||
|
||||
page = decodePage(page, responseHeaders.get(HTTP_HEADER.CONTENT_ENCODING), responseHeaders.get(HTTP_HEADER.CONTENT_TYPE))
|
||||
status = getUnicode(conn.msg)
|
||||
status = getUnicode(conn.msg) if conn else None
|
||||
|
||||
kb.connErrorCounter = 0
|
||||
|
||||
if extractRegexResult(META_REFRESH_REGEX, page) and not refreshing:
|
||||
refresh = extractRegexResult(META_REFRESH_REGEX, page)
|
||||
if not refreshing:
|
||||
refresh = responseHeaders.get(HTTP_HEADER.REFRESH, "").split("url=")[-1].strip()
|
||||
|
||||
debugMsg = "got HTML meta refresh header"
|
||||
logger.debug(debugMsg)
|
||||
if extractRegexResult(META_REFRESH_REGEX, page):
|
||||
refresh = extractRegexResult(META_REFRESH_REGEX, page)
|
||||
|
||||
if kb.alwaysRefresh is None:
|
||||
msg = "sqlmap got a refresh request "
|
||||
msg += "(redirect like response common to login pages). "
|
||||
msg += "Do you want to apply the refresh "
|
||||
msg += "from now on (or stay on the original page)? [Y/n]"
|
||||
choice = readInput(msg, default="Y")
|
||||
debugMsg = "got HTML meta refresh header"
|
||||
logger.debug(debugMsg)
|
||||
|
||||
kb.alwaysRefresh = choice not in ("n", "N")
|
||||
if refresh:
|
||||
if kb.alwaysRefresh is None:
|
||||
msg = "sqlmap got a refresh request "
|
||||
msg += "(redirect like response common to login pages). "
|
||||
msg += "Do you want to apply the refresh "
|
||||
msg += "from now on (or stay on the original page)? [Y/n]"
|
||||
choice = readInput(msg, default="Y")
|
||||
|
||||
if kb.alwaysRefresh:
|
||||
if re.search(r"\Ahttps?://", refresh, re.I):
|
||||
url = refresh
|
||||
else:
|
||||
url = urlparse.urljoin(url, refresh)
|
||||
kb.alwaysRefresh = choice not in ("n", "N")
|
||||
|
||||
threadData.lastRedirectMsg = (threadData.lastRequestUID, page)
|
||||
kwargs['refreshing'] = True
|
||||
kwargs['url'] = url
|
||||
kwargs['get'] = None
|
||||
kwargs['post'] = None
|
||||
if kb.alwaysRefresh:
|
||||
if re.search(r"\Ahttps?://", refresh, re.I):
|
||||
url = refresh
|
||||
else:
|
||||
url = urlparse.urljoin(url, refresh)
|
||||
|
||||
try:
|
||||
return Connect._getPageProxy(**kwargs)
|
||||
except SqlmapSyntaxException:
|
||||
pass
|
||||
threadData.lastRedirectMsg = (threadData.lastRequestUID, page)
|
||||
kwargs["refreshing"] = True
|
||||
kwargs["url"] = url
|
||||
kwargs["get"] = None
|
||||
kwargs["post"] = None
|
||||
|
||||
try:
|
||||
return Connect._getPageProxy(**kwargs)
|
||||
except SqlmapSyntaxException:
|
||||
pass
|
||||
|
||||
# Explicit closing of connection object
|
||||
if conn and not conf.keepAlive:
|
||||
@@ -627,6 +634,14 @@ class Connect(object):
|
||||
if kb.testMode and kb.testType not in (None, PAYLOAD.TECHNIQUE.TIME, PAYLOAD.TECHNIQUE.STACKED):
|
||||
singleTimeWarnMessage("there is a possibility that the target (or WAF/IPS/IDS) is dropping 'suspicious' requests")
|
||||
warnMsg = "connection timed out to the target URL"
|
||||
elif "Connection reset" in tbMsg:
|
||||
if not conf.disablePrecon:
|
||||
singleTimeWarnMessage("turning off pre-connect mechanism because of connection reset(s)")
|
||||
conf.disablePrecon = True
|
||||
|
||||
if kb.testMode:
|
||||
singleTimeWarnMessage("there is a possibility that the target (or WAF/IPS/IDS) is resetting 'suspicious' requests")
|
||||
warnMsg = "connection reset to the target URL"
|
||||
elif "URLError" in tbMsg or "error" in tbMsg:
|
||||
warnMsg = "unable to connect to the target URL"
|
||||
match = re.search(r"Errno \d+\] ([^>]+)", tbMsg)
|
||||
@@ -1038,15 +1053,29 @@ class Connect(object):
|
||||
found = False
|
||||
value = getUnicode(value)
|
||||
|
||||
if kb.postHint and re.search(r"\b%s\b" % re.escape(name), post or ""):
|
||||
if kb.postHint in (POST_HINT.XML, POST_HINT.SOAP):
|
||||
if re.search(r"<%s\b" % re.escape(name), post):
|
||||
found = True
|
||||
post = re.sub(r"(?s)(<%s\b[^>]*>)(.*?)(</%s)" % (re.escape(name), re.escape(name)), "\g<1>%s\g<3>" % value, post)
|
||||
elif re.search(r"\b%s>" % re.escape(name), post):
|
||||
found = True
|
||||
post = re.sub(r"(?s)(\b%s>)(.*?)(</[^<]*\b%s>)" % (re.escape(name), re.escape(name)), "\g<1>%s\g<3>" % value, post)
|
||||
|
||||
regex = r"\b(%s)\b([^\w]+)(\w+)" % re.escape(name)
|
||||
if not found and re.search(regex, (post or "")):
|
||||
found = True
|
||||
post = re.sub(regex, "\g<1>\g<2>%s" % value, post)
|
||||
|
||||
regex = r"((\A|%s)%s=).+?(%s|\Z)" % (re.escape(delimiter), re.escape(name), re.escape(delimiter))
|
||||
if not found and re.search(regex, (post or "")):
|
||||
found = True
|
||||
post = re.sub(regex, "\g<1>%s\g<3>" % value, post)
|
||||
|
||||
if re.search(regex, (get or "")):
|
||||
found = True
|
||||
get = re.sub(regex, "\g<1>%s\g<3>" % value, get)
|
||||
|
||||
if re.search(regex, (post or "")):
|
||||
found = True
|
||||
post = re.sub(regex, "\g<1>%s\g<3>" % value, post)
|
||||
|
||||
if re.search(regex, (query or "")):
|
||||
found = True
|
||||
uri = re.sub(regex.replace(r"\A", r"\?"), "\g<1>%s\g<3>" % value, uri)
|
||||
@@ -1073,7 +1102,7 @@ class Connect(object):
|
||||
elif kb.postUrlEncode:
|
||||
post = urlencode(post, spaceplus=kb.postSpaceToPlus)
|
||||
|
||||
if timeBasedCompare:
|
||||
if timeBasedCompare and not conf.disableStats:
|
||||
if len(kb.responseTimes.get(kb.responseTimeMode, [])) < MIN_TIME_RESPONSES:
|
||||
clearConsoleLine()
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
import re
|
||||
import types
|
||||
import urllib2
|
||||
import urlparse
|
||||
@@ -123,7 +124,12 @@ class SmartRedirectHandler(urllib2.HTTPRedirectHandler):
|
||||
|
||||
req.headers[HTTP_HEADER.HOST] = getHostHeader(redurl)
|
||||
if headers and HTTP_HEADER.SET_COOKIE in headers:
|
||||
req.headers[HTTP_HEADER.COOKIE] = headers[HTTP_HEADER.SET_COOKIE].split(conf.cookieDel or DEFAULT_COOKIE_DELIMITER)[0]
|
||||
delimiter = conf.cookieDel or DEFAULT_COOKIE_DELIMITER
|
||||
_ = headers[HTTP_HEADER.SET_COOKIE].split(delimiter)[0]
|
||||
if HTTP_HEADER.COOKIE not in req.headers:
|
||||
req.headers[HTTP_HEADER.COOKIE] = _
|
||||
else:
|
||||
req.headers[HTTP_HEADER.COOKIE] = re.sub("%s{2,}" % delimiter, delimiter, ("%s%s%s" % (re.sub(r"\b%s=[^%s]*%s?" % (_.split('=')[0], delimiter, delimiter), "", req.headers[HTTP_HEADER.COOKIE]), delimiter, _)).strip(delimiter))
|
||||
try:
|
||||
result = urllib2.HTTPRedirectHandler.http_error_302(self, req, fp, code, msg, headers)
|
||||
except urllib2.HTTPError, e:
|
||||
|
||||
@@ -351,7 +351,7 @@ class Metasploit:
|
||||
|
||||
self._cliCmd += " E"
|
||||
else:
|
||||
self._cliCmd = "%s -x 'use multi/handler; set PAYLOAD %s" % (self._msfConsole, self.payloadConnStr)
|
||||
self._cliCmd = "%s -L -x 'use multi/handler; set PAYLOAD %s" % (self._msfConsole, self.payloadConnStr)
|
||||
self._cliCmd += "; set EXITFUNC %s" % exitfunc
|
||||
self._cliCmd += "; set LPORT %s" % self.portStr
|
||||
|
||||
@@ -601,6 +601,8 @@ class Metasploit:
|
||||
|
||||
except (EOFError, IOError, select.error):
|
||||
return proc.returncode
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
|
||||
def createMsfShellcode(self, exitfunc, format, extra, encode):
|
||||
infoMsg = "creating Metasploit Framework multi-stage shellcode "
|
||||
@@ -620,7 +622,7 @@ class Metasploit:
|
||||
pollProcess(process)
|
||||
payloadStderr = process.communicate()[1]
|
||||
|
||||
match = re.search("(Total size:|Length:|succeeded with size) ([\d]+)", payloadStderr)
|
||||
match = re.search("(Total size:|Length:|succeeded with size|Final size of exe file:) ([\d]+)", payloadStderr)
|
||||
|
||||
if match:
|
||||
payloadSize = int(match.group(2))
|
||||
|
||||
@@ -26,6 +26,7 @@ from lib.core.common import ntToPosixSlashes
|
||||
from lib.core.common import isTechniqueAvailable
|
||||
from lib.core.common import isWindowsDriveLetterPath
|
||||
from lib.core.common import normalizePath
|
||||
from lib.core.common import parseFilePaths
|
||||
from lib.core.common import posixToNtSlashes
|
||||
from lib.core.common import randomInt
|
||||
from lib.core.common import randomStr
|
||||
@@ -38,8 +39,10 @@ from lib.core.data import kb
|
||||
from lib.core.data import logger
|
||||
from lib.core.data import paths
|
||||
from lib.core.enums import DBMS
|
||||
from lib.core.enums import HTTP_HEADER
|
||||
from lib.core.enums import OS
|
||||
from lib.core.enums import PAYLOAD
|
||||
from lib.core.enums import PLACE
|
||||
from lib.core.enums import WEB_API
|
||||
from lib.core.exception import SqlmapNoneDataException
|
||||
from lib.core.settings import BACKDOOR_RUN_CMD_TIMEOUT
|
||||
@@ -196,6 +199,60 @@ class Web:
|
||||
self.webApi = choices[int(choice) - 1]
|
||||
break
|
||||
|
||||
if not kb.absFilePaths:
|
||||
message = "do you want sqlmap to further try to "
|
||||
message += "provoke the full path disclosure? [Y/n] "
|
||||
getOutput = readInput(message, default="Y")
|
||||
|
||||
if getOutput in ("y", "Y"):
|
||||
headers = {}
|
||||
been = {conf.url}
|
||||
|
||||
for match in re.finditer(r"=['\"]((https?):)?(//[^/'\"]+)?(/[\w/.-]*)\bwp-", kb.originalPage, re.I):
|
||||
url = "%s%s" % (conf.url.replace(conf.path, match.group(4)), "wp-content/wp-db.php")
|
||||
if url not in been:
|
||||
try:
|
||||
page, _, _ = Request.getPage(url=url, raise404=False, silent=True)
|
||||
parseFilePaths(page)
|
||||
except:
|
||||
pass
|
||||
finally:
|
||||
been.add(url)
|
||||
|
||||
url = re.sub(r"(\.\w+)\Z", "~\g<1>", conf.url)
|
||||
if url not in been:
|
||||
try:
|
||||
page, _, _ = Request.getPage(url=url, raise404=False, silent=True)
|
||||
parseFilePaths(page)
|
||||
except:
|
||||
pass
|
||||
finally:
|
||||
been.add(url)
|
||||
|
||||
for place in (PLACE.GET, PLACE.POST):
|
||||
if place in conf.parameters:
|
||||
value = re.sub(r"(\A|&)(\w+)=", "\g<2>[]=", conf.parameters[place])
|
||||
if "[]" in value:
|
||||
page, headers = Request.queryPage(value=value, place=place, content=True, raise404=False, silent=True, noteResponseTime=False)
|
||||
parseFilePaths(page)
|
||||
|
||||
cookie = None
|
||||
if PLACE.COOKIE in conf.parameters:
|
||||
cookie = conf.parameters[PLACE.COOKIE]
|
||||
elif headers and HTTP_HEADER.SET_COOKIE in headers:
|
||||
cookie = headers[HTTP_HEADER.SET_COOKIE]
|
||||
|
||||
if cookie:
|
||||
value = re.sub(r"(\A|;)(\w+)=[^;]*", "\g<2>=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", cookie)
|
||||
if value != cookie:
|
||||
page, _ = Request.queryPage(value=value, place=PLACE.COOKIE, content=True, raise404=False, silent=True, noteResponseTime=False)
|
||||
parseFilePaths(page)
|
||||
|
||||
value = re.sub(r"(\A|;)(\w+)=[^;]*", "\g<2>=", cookie)
|
||||
if value != cookie:
|
||||
page, _ = Request.queryPage(value=value, place=PLACE.COOKIE, content=True, raise404=False, silent=True, noteResponseTime=False)
|
||||
parseFilePaths(page)
|
||||
|
||||
directories = list(arrayizeValue(getManualDirectories()))
|
||||
directories.extend(getAutoDirectories())
|
||||
directories = list(oset(directories))
|
||||
|
||||
@@ -70,8 +70,8 @@ def tableExists(tableFile, regex=None):
|
||||
|
||||
if result:
|
||||
errMsg = "can't use table existence check because of detected invalid results "
|
||||
errMsg += "(most probably caused by inability of the used injection "
|
||||
errMsg += "to distinguish errornous results)"
|
||||
errMsg += "(most likely caused by inability of the used injection "
|
||||
errMsg += "to distinguish erroneous results)"
|
||||
raise SqlmapDataException(errMsg)
|
||||
|
||||
tables = getFileItems(tableFile, lowercase=Backend.getIdentifiedDbms() in (DBMS.ACCESS,), unique=True)
|
||||
@@ -178,8 +178,8 @@ def columnExists(columnFile, regex=None):
|
||||
|
||||
if result:
|
||||
errMsg = "can't use column existence check because of detected invalid results "
|
||||
errMsg += "(most probably caused by inability of the used injection "
|
||||
errMsg += "to distinguish errornous results)"
|
||||
errMsg += "(most likely caused by inability of the used injection "
|
||||
errMsg += "to distinguish erroneous results)"
|
||||
raise SqlmapDataException(errMsg)
|
||||
|
||||
infoMsg = "checking column existence using items from '%s'" % columnFile
|
||||
|
||||
@@ -5,6 +5,7 @@ Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
import logging
|
||||
import random
|
||||
import re
|
||||
|
||||
@@ -154,7 +155,7 @@ def _findUnionCharCount(comment, place, parameter, value, prefix, suffix, where=
|
||||
|
||||
if retVal:
|
||||
infoMsg = "target URL appears to be UNION injectable with %d columns" % retVal
|
||||
singleTimeLogMessage(infoMsg)
|
||||
singleTimeLogMessage(infoMsg, logging.INFO, re.sub(r"\d+", "N", infoMsg))
|
||||
|
||||
return retVal
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
import contextlib
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
@@ -163,6 +164,8 @@ class Task(object):
|
||||
def engine_start(self):
|
||||
if os.path.exists("sqlmap.py"):
|
||||
self.process = Popen(["python", "sqlmap.py", "--pickled-options", base64pickle(self.options)], shell=False, close_fds=not IS_WIN)
|
||||
elif os.path.exists(os.path.join(os.getcwd(), "sqlmap.py")):
|
||||
self.process = Popen(["python", "sqlmap.py", "--pickled-options", base64pickle(self.options)], shell=False, cwd=os.getcwd(), close_fds=not IS_WIN)
|
||||
else:
|
||||
self.process = Popen(["sqlmap", "--pickled-options", base64pickle(self.options)], shell=False, close_fds=not IS_WIN)
|
||||
|
||||
@@ -646,6 +649,11 @@ def server(host=RESTAPI_DEFAULT_ADDRESS, port=RESTAPI_DEFAULT_PORT, adapter=REST
|
||||
DataStore.admin_id = hexencode(os.urandom(16))
|
||||
Database.filepath = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.IPC, text=False)[1]
|
||||
|
||||
if port == 0: # random
|
||||
with contextlib.closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
|
||||
s.bind((host, 0))
|
||||
port = s.getsockname()[1]
|
||||
|
||||
logger.info("Running REST-JSON API server at '%s:%d'.." % (host, port))
|
||||
logger.info("Admin ID: %s" % DataStore.admin_id)
|
||||
logger.debug("IPC database: %s" % Database.filepath)
|
||||
@@ -738,12 +746,33 @@ def client(host=RESTAPI_DEFAULT_ADDRESS, port=RESTAPI_DEFAULT_PORT):
|
||||
logger.error("Failed to execute command %s" % command)
|
||||
dataToStdout("%s\n" % raw)
|
||||
|
||||
elif command.startswith("option"):
|
||||
if not taskid:
|
||||
logger.error("No task ID in use")
|
||||
continue
|
||||
try:
|
||||
command, option = command.split(" ")
|
||||
except ValueError:
|
||||
raw = _client("%s/option/%s/list" % (addr, taskid))
|
||||
else:
|
||||
options = {"option": option}
|
||||
raw = _client("%s/option/%s/get" % (addr, taskid), options)
|
||||
res = dejsonize(raw)
|
||||
if not res["success"]:
|
||||
logger.error("Failed to execute command %s" % command)
|
||||
dataToStdout("%s\n" % raw)
|
||||
|
||||
elif command.startswith("new"):
|
||||
if ' ' not in command:
|
||||
logger.error("Program arguments are missing")
|
||||
continue
|
||||
|
||||
argv = ["sqlmap.py"] + shlex.split(command)[1:]
|
||||
try:
|
||||
argv = ["sqlmap.py"] + shlex.split(command)[1:]
|
||||
except Exception, ex:
|
||||
logger.error("Error occurred while parsing arguments ('%s')" % ex)
|
||||
taskid = None
|
||||
continue
|
||||
|
||||
try:
|
||||
cmdLineOptions = cmdLineParser(argv).__dict__
|
||||
@@ -795,17 +824,19 @@ def client(host=RESTAPI_DEFAULT_ADDRESS, port=RESTAPI_DEFAULT_PORT):
|
||||
return
|
||||
|
||||
elif command in ("help", "?"):
|
||||
msg = "help Show this help message\n"
|
||||
msg += "new ARGS Start a new scan task with provided arguments (e.g. 'new -u \"http://testphp.vulnweb.com/artists.php?artist=1\"')\n"
|
||||
msg += "use TASKID Switch current context to different task (e.g. 'use c04d8c5c7582efb4')\n"
|
||||
msg += "data Retrieve and show data for current task\n"
|
||||
msg += "log Retrieve and show log for current task\n"
|
||||
msg += "status Retrieve and show status for current task\n"
|
||||
msg += "stop Stop current task\n"
|
||||
msg += "kill Kill current task\n"
|
||||
msg += "list Display all tasks\n"
|
||||
msg += "flush Flush tasks (delete all tasks)\n"
|
||||
msg += "exit Exit this client\n"
|
||||
msg = "help Show this help message\n"
|
||||
msg += "new ARGS Start a new scan task with provided arguments (e.g. 'new -u \"http://testphp.vulnweb.com/artists.php?artist=1\"')\n"
|
||||
msg += "use TASKID Switch current context to different task (e.g. 'use c04d8c5c7582efb4')\n"
|
||||
msg += "data Retrieve and show data for current task\n"
|
||||
msg += "log Retrieve and show log for current task\n"
|
||||
msg += "status Retrieve and show status for current task\n"
|
||||
msg += "option OPTION Retrieve and show option for current task\n"
|
||||
msg += "options Retrieve and show all options for current task\n"
|
||||
msg += "stop Stop current task\n"
|
||||
msg += "kill Kill current task\n"
|
||||
msg += "list Display all tasks\n"
|
||||
msg += "flush Flush tasks (delete all tasks)\n"
|
||||
msg += "exit Exit this client\n"
|
||||
|
||||
dataToStdout(msg)
|
||||
|
||||
|
||||
@@ -63,14 +63,14 @@ def crawl(target):
|
||||
if current:
|
||||
content = Request.getPage(url=current, crawling=True, raise404=False)[0]
|
||||
except SqlmapConnectionException, ex:
|
||||
errMsg = "connection exception detected (%s). skipping " % ex
|
||||
errMsg = "connection exception detected (%s). skipping " % getSafeExString(ex)
|
||||
errMsg += "URL '%s'" % current
|
||||
logger.critical(errMsg)
|
||||
except SqlmapSyntaxException:
|
||||
errMsg = "invalid URL detected. skipping '%s'" % current
|
||||
logger.critical(errMsg)
|
||||
except httplib.InvalidURL, ex:
|
||||
errMsg = "invalid URL detected (%s). skipping " % ex
|
||||
errMsg = "invalid URL detected (%s). skipping " % getSafeExString(ex)
|
||||
errMsg += "URL '%s'" % current
|
||||
logger.critical(errMsg)
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ def pivotDumpTable(table, colList, count=None, blind=True):
|
||||
|
||||
if count is None:
|
||||
query = dumpNode.count % table
|
||||
query = whereQuery(query)
|
||||
query = agent.whereQuery(query)
|
||||
count = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS) if blind else inject.getValue(query, blind=False, time=False, expected=EXPECTED.INT)
|
||||
|
||||
if isinstance(count, basestring) and count.isdigit():
|
||||
@@ -91,7 +91,7 @@ def pivotDumpTable(table, colList, count=None, blind=True):
|
||||
logger.info(infoMsg)
|
||||
|
||||
query = dumpNode.count2 % (column, table)
|
||||
query = whereQuery(query)
|
||||
query = agent.whereQuery(query)
|
||||
value = inject.getValue(query, blind=blind, union=not blind, error=not blind, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)
|
||||
|
||||
if isNumPosStrValue(value):
|
||||
@@ -125,7 +125,7 @@ def pivotDumpTable(table, colList, count=None, blind=True):
|
||||
else:
|
||||
query = dumpNode.query2.replace("'%s'", "%s") % (agent.preprocessField(table, column), table, agent.preprocessField(table, colList[0]), unescaper.escape(pivotValue, False))
|
||||
|
||||
query = whereQuery(query)
|
||||
query = agent.whereQuery(query)
|
||||
return unArrayizeValue(inject.getValue(query, blind=blind, time=blind, union=not blind, error=not blind))
|
||||
|
||||
try:
|
||||
@@ -179,18 +179,3 @@ def pivotDumpTable(table, colList, count=None, blind=True):
|
||||
logger.critical(errMsg)
|
||||
|
||||
return entries, lengths
|
||||
|
||||
def whereQuery(query):
|
||||
if conf.dumpWhere and query:
|
||||
prefix, suffix = query.split(" ORDER BY ") if " ORDER BY " in query else (query, "")
|
||||
|
||||
if "%s)" % conf.tbl.upper() in prefix.upper():
|
||||
prefix = re.sub(r"(?i)%s\)" % re.escape(conf.tbl), "%s WHERE %s)" % (conf.tbl, conf.dumpWhere), prefix)
|
||||
elif re.search(r"(?i)\bWHERE\b", prefix):
|
||||
prefix += " AND %s" % conf.dumpWhere
|
||||
else:
|
||||
prefix += " WHERE %s" % conf.dumpWhere
|
||||
|
||||
query = "%s ORDER BY %s" % (prefix, suffix) if suffix else prefix
|
||||
|
||||
return query
|
||||
|
||||
@@ -18,6 +18,6 @@ try:
|
||||
__import__(_)
|
||||
except ImportError:
|
||||
errMsg = "missing one or more core extensions (%s) " % (", ".join("'%s'" % _ for _ in extensions))
|
||||
errMsg += "most probably because current version of Python has been "
|
||||
errMsg += "most likely because current version of Python has been "
|
||||
errMsg += "built without appropriate dev packages (e.g. 'libsqlite3-dev')"
|
||||
exit(errMsg)
|
||||
@@ -146,7 +146,7 @@ class Fingerprint(GenericFingerprint):
|
||||
return value
|
||||
|
||||
def checkDbms(self):
|
||||
if not conf.extensiveFp and (Backend.isDbmsWithin(ACCESS_ALIASES) or (conf.dbms or "").lower() in ACCESS_ALIASES):
|
||||
if not conf.extensiveFp and Backend.isDbmsWithin(ACCESS_ALIASES):
|
||||
setDbms(DBMS.ACCESS)
|
||||
|
||||
return True
|
||||
|
||||
@@ -18,4 +18,3 @@ class Enumeration(GenericEnumeration):
|
||||
logger.warn(warnMsg)
|
||||
|
||||
return {}
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ class Fingerprint(GenericFingerprint):
|
||||
return value
|
||||
|
||||
def checkDbms(self):
|
||||
if not conf.extensiveFp and (Backend.isDbmsWithin(DB2_ALIASES) or (conf.dbms or "").lower() in DB2_ALIASES):
|
||||
if not conf.extensiveFp and Backend.isDbmsWithin(DB2_ALIASES):
|
||||
setDbms(DBMS.DB2)
|
||||
|
||||
return True
|
||||
|
||||
@@ -103,9 +103,7 @@ class Fingerprint(GenericFingerprint):
|
||||
return retVal
|
||||
|
||||
def checkDbms(self):
|
||||
if not conf.extensiveFp and (Backend.isDbmsWithin(FIREBIRD_ALIASES) \
|
||||
or (conf.dbms or "").lower() in FIREBIRD_ALIASES) and Backend.getVersion() and \
|
||||
Backend.getVersion() != UNKNOWN_DBMS_VERSION:
|
||||
if not conf.extensiveFp and Backend.isDbmsWithin(FIREBIRD_ALIASES):
|
||||
setDbms("%s %s" % (DBMS.FIREBIRD, Backend.getVersion()))
|
||||
|
||||
self.getBanner()
|
||||
|
||||
@@ -80,9 +80,7 @@ class Fingerprint(GenericFingerprint):
|
||||
|
||||
"""
|
||||
|
||||
if not conf.extensiveFp and (Backend.isDbmsWithin(HSQLDB_ALIASES) \
|
||||
or (conf.dbms or "").lower() in HSQLDB_ALIASES) and Backend.getVersion() and \
|
||||
Backend.getVersion() != UNKNOWN_DBMS_VERSION:
|
||||
if not conf.extensiveFp and Backend.isDbmsWithin(HSQLDB_ALIASES):
|
||||
setDbms("%s %s" % (DBMS.HSQLDB, Backend.getVersion()))
|
||||
|
||||
if Backend.isVersionGreaterOrEqualThan("1.7.2"):
|
||||
|
||||
@@ -56,7 +56,7 @@ class Fingerprint(GenericFingerprint):
|
||||
return value
|
||||
|
||||
def checkDbms(self):
|
||||
if not conf.extensiveFp and (Backend.isDbmsWithin(INFORMIX_ALIASES) or (conf.dbms or "").lower() in INFORMIX_ALIASES):
|
||||
if not conf.extensiveFp and Backend.isDbmsWithin(INFORMIX_ALIASES):
|
||||
setDbms(DBMS.INFORMIX)
|
||||
|
||||
self.getBanner()
|
||||
|
||||
@@ -91,7 +91,7 @@ class Fingerprint(GenericFingerprint):
|
||||
return value
|
||||
|
||||
def checkDbms(self):
|
||||
if not conf.extensiveFp and (Backend.isDbmsWithin(MAXDB_ALIASES) or (conf.dbms or "").lower() in MAXDB_ALIASES):
|
||||
if not conf.extensiveFp and Backend.isDbmsWithin(MAXDB_ALIASES):
|
||||
setDbms(DBMS.MAXDB)
|
||||
|
||||
self.getBanner()
|
||||
|
||||
@@ -65,9 +65,7 @@ class Fingerprint(GenericFingerprint):
|
||||
return value
|
||||
|
||||
def checkDbms(self):
|
||||
if not conf.extensiveFp and (Backend.isDbmsWithin(MSSQL_ALIASES) \
|
||||
or (conf.dbms or "").lower() in MSSQL_ALIASES) and Backend.getVersion() and \
|
||||
Backend.getVersion().isdigit():
|
||||
if not conf.extensiveFp and Backend.isDbmsWithin(MSSQL_ALIASES):
|
||||
setDbms("%s %s" % (DBMS.MSSQL, Backend.getVersion()))
|
||||
|
||||
self.getBanner()
|
||||
|
||||
@@ -46,12 +46,12 @@ class Fingerprint(GenericFingerprint):
|
||||
(32300, 32359), # MySQL 3.23
|
||||
(40000, 40032), # MySQL 4.0
|
||||
(40100, 40131), # MySQL 4.1
|
||||
(50000, 50092), # MySQL 5.0
|
||||
(50000, 50096), # MySQL 5.0
|
||||
(50100, 50172), # MySQL 5.1
|
||||
(50400, 50404), # MySQL 5.4
|
||||
(50500, 50552), # MySQL 5.5
|
||||
(50600, 50633), # MySQL 5.6
|
||||
(50700, 50715), # MySQL 5.7
|
||||
(50500, 50554), # MySQL 5.5
|
||||
(50600, 50635), # MySQL 5.6
|
||||
(50700, 50717), # MySQL 5.7
|
||||
(60000, 60014), # MySQL 6.0
|
||||
)
|
||||
|
||||
@@ -150,9 +150,7 @@ class Fingerprint(GenericFingerprint):
|
||||
* http://dev.mysql.com/doc/refman/6.0/en/news-6-0-x.html (manual has been withdrawn)
|
||||
"""
|
||||
|
||||
if not conf.extensiveFp and (Backend.isDbmsWithin(MYSQL_ALIASES) \
|
||||
or (conf.dbms or "").lower() in MYSQL_ALIASES) and Backend.getVersion() and \
|
||||
Backend.getVersion() != UNKNOWN_DBMS_VERSION:
|
||||
if not conf.extensiveFp and Backend.isDbmsWithin(MYSQL_ALIASES):
|
||||
setDbms("%s %s" % (DBMS.MYSQL, Backend.getVersion()))
|
||||
|
||||
if Backend.isVersionGreaterOrEqualThan("5"):
|
||||
|
||||
@@ -58,7 +58,7 @@ class Fingerprint(GenericFingerprint):
|
||||
return value
|
||||
|
||||
def checkDbms(self):
|
||||
if not conf.extensiveFp and (Backend.isDbmsWithin(ORACLE_ALIASES) or (conf.dbms or "").lower() in ORACLE_ALIASES):
|
||||
if not conf.extensiveFp and Backend.isDbmsWithin(ORACLE_ALIASES):
|
||||
setDbms(DBMS.ORACLE)
|
||||
|
||||
self.getBanner()
|
||||
|
||||
@@ -63,7 +63,7 @@ class Fingerprint(GenericFingerprint):
|
||||
* http://www.postgresql.org/docs/9.1/interactive/release.html (up to 9.1.3)
|
||||
"""
|
||||
|
||||
if not conf.extensiveFp and (Backend.isDbmsWithin(PGSQL_ALIASES) or (conf.dbms or "").lower() in PGSQL_ALIASES):
|
||||
if not conf.extensiveFp and Backend.isDbmsWithin(PGSQL_ALIASES):
|
||||
setDbms(DBMS.PGSQL)
|
||||
|
||||
self.getBanner()
|
||||
|
||||
@@ -64,7 +64,7 @@ class Fingerprint(GenericFingerprint):
|
||||
* http://www.sqlite.org/cvstrac/wiki?p=LoadableExtensions
|
||||
"""
|
||||
|
||||
if not conf.extensiveFp and (Backend.isDbmsWithin(SQLITE_ALIASES) or (conf.dbms or "").lower() in SQLITE_ALIASES):
|
||||
if not conf.extensiveFp and Backend.isDbmsWithin(SQLITE_ALIASES):
|
||||
setDbms(DBMS.SQLITE)
|
||||
|
||||
self.getBanner()
|
||||
|
||||
@@ -58,9 +58,7 @@ class Fingerprint(GenericFingerprint):
|
||||
return value
|
||||
|
||||
def checkDbms(self):
|
||||
if not conf.extensiveFp and (Backend.isDbmsWithin(SYBASE_ALIASES) \
|
||||
or (conf.dbms or "").lower() in SYBASE_ALIASES) and Backend.getVersion() and \
|
||||
Backend.getVersion().isdigit():
|
||||
if not conf.extensiveFp and Backend.isDbmsWithin(SYBASE_ALIASES):
|
||||
setDbms("%s %s" % (DBMS.SYBASE, Backend.getVersion()))
|
||||
|
||||
self.getBanner()
|
||||
|
||||
@@ -11,6 +11,7 @@ from lib.core.data import conf
|
||||
from lib.core.data import logger
|
||||
from lib.core.exception import SqlmapFilePathException
|
||||
from lib.core.exception import SqlmapUndefinedMethod
|
||||
from lib.core.settings import UNICODE_ENCODING
|
||||
|
||||
class Connector:
|
||||
"""
|
||||
@@ -22,8 +23,8 @@ class Connector:
|
||||
self.cursor = None
|
||||
|
||||
def initConnection(self):
|
||||
self.user = conf.dbmsUser
|
||||
self.password = conf.dbmsPass if conf.dbmsPass is not None else ""
|
||||
self.user = conf.dbmsUser.encode(UNICODE_ENCODING) if conf.dbmsUser is not None else ""
|
||||
self.password = conf.dbmsPass.encode(UNICODE_ENCODING) if conf.dbmsPass is not None else ""
|
||||
self.hostname = conf.hostname
|
||||
self.port = conf.port
|
||||
self.db = conf.dbmsDb
|
||||
|
||||
@@ -43,7 +43,6 @@ from lib.core.settings import NULL
|
||||
from lib.request import inject
|
||||
from lib.utils.hash import attackDumpedTable
|
||||
from lib.utils.pivotdumptable import pivotDumpTable
|
||||
from lib.utils.pivotdumptable import whereQuery
|
||||
|
||||
class Entries:
|
||||
"""
|
||||
@@ -190,10 +189,17 @@ class Entries:
|
||||
else:
|
||||
query = rootQuery.inband.query % (colString, conf.db, tbl)
|
||||
|
||||
query = whereQuery(query)
|
||||
query = agent.whereQuery(query)
|
||||
|
||||
if not entries and query:
|
||||
entries = inject.getValue(query, blind=False, time=False, dump=True)
|
||||
try:
|
||||
entries = inject.getValue(query, blind=False, time=False, dump=True)
|
||||
except KeyboardInterrupt:
|
||||
entries = None
|
||||
kb.dumpKeyboardInterrupt = True
|
||||
clearConsoleLine()
|
||||
warnMsg = "Ctrl+C detected in dumping phase"
|
||||
logger.warn(warnMsg)
|
||||
|
||||
if not isNoneValue(entries):
|
||||
if isinstance(entries, basestring):
|
||||
@@ -244,7 +250,7 @@ class Entries:
|
||||
else:
|
||||
query = rootQuery.blind.count % (conf.db, tbl)
|
||||
|
||||
query = whereQuery(query)
|
||||
query = agent.whereQuery(query)
|
||||
|
||||
count = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)
|
||||
|
||||
@@ -329,7 +335,7 @@ class Entries:
|
||||
elif Backend.isDbms(DBMS.INFORMIX):
|
||||
query = rootQuery.blind.query % (index, agent.preprocessField(tbl, column), conf.db, tbl, sorted(colList, key=len)[0])
|
||||
|
||||
query = whereQuery(query)
|
||||
query = agent.whereQuery(query)
|
||||
|
||||
value = NULL if column in emptyColumns else inject.getValue(query, union=False, error=False, dump=True)
|
||||
value = '' if value is None else value
|
||||
|
||||
@@ -120,6 +120,8 @@ class Filesystem:
|
||||
back-end DBMS underlying file system
|
||||
"""
|
||||
|
||||
checkFile(fileName)
|
||||
|
||||
with open(fileName, "rb") as f:
|
||||
content = f.read()
|
||||
|
||||
|
||||
13
sqlmap.conf
13
sqlmap.conf
@@ -512,13 +512,13 @@ excludeSysDbs = False
|
||||
|
||||
# First query output entry to retrieve
|
||||
# Valid: integer
|
||||
# Default: 0 (sqlmap will start to retrieve the query output entries from
|
||||
# the first)
|
||||
# Default: 0 (sqlmap will start to retrieve the table dump entries from
|
||||
# first one)
|
||||
limitStart = 0
|
||||
|
||||
# Last query output entry to retrieve
|
||||
# Valid: integer
|
||||
# Default: 0 (sqlmap will detect the number of query output entries and
|
||||
# Default: 0 (sqlmap will detect the number of table dump entries and
|
||||
# retrieve them until the last)
|
||||
limitStop = 0
|
||||
|
||||
@@ -779,10 +779,6 @@ mobile = False
|
||||
# Valid: True or False
|
||||
offline = False
|
||||
|
||||
# Display page rank (PR) for Google dork results.
|
||||
# Valid: True or False
|
||||
pageRank = False
|
||||
|
||||
# Skip heuristic detection of WAF/IPS/IDS protection.
|
||||
# Valid: True or False
|
||||
skipWaf = False
|
||||
@@ -794,6 +790,9 @@ smart = False
|
||||
# Local directory for storing temporary files.
|
||||
tmpDir =
|
||||
|
||||
# Web server document root directory (e.g. "/var/www").
|
||||
webRoot =
|
||||
|
||||
# Simple wizard interface for beginner users.
|
||||
# Valid: True or False
|
||||
wizard = False
|
||||
|
||||
@@ -5,6 +5,8 @@ Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from lib.core.common import zeroDepthSearch
|
||||
from lib.core.enums import PRIORITY
|
||||
|
||||
@@ -28,6 +30,9 @@ def tamper(payload, **kwargs):
|
||||
|
||||
>>> tamper('SELECT CHAR(113)+CHAR(114)+CHAR(115) FROM DUAL')
|
||||
'SELECT CONCAT(CHAR(113),CHAR(114),CHAR(115)) FROM DUAL'
|
||||
|
||||
>>> tamper('SELECT (CHAR(113)+CHAR(114)+CHAR(115)) FROM DUAL')
|
||||
'SELECT CONCAT(CHAR(113),CHAR(114),CHAR(115)) FROM DUAL'
|
||||
"""
|
||||
|
||||
retVal = payload
|
||||
@@ -35,6 +40,7 @@ def tamper(payload, **kwargs):
|
||||
if payload:
|
||||
while True:
|
||||
indexes = zeroDepthSearch(retVal, '+')
|
||||
|
||||
if indexes:
|
||||
first, last = 0, 0
|
||||
for i in xrange(1, len(indexes)):
|
||||
@@ -52,6 +58,19 @@ def tamper(payload, **kwargs):
|
||||
|
||||
retVal = "%sCONCAT(%s)%s" % (retVal[:start], ''.join(chars)[start:end], retVal[end:])
|
||||
else:
|
||||
break
|
||||
match = re.search(r"\((CHAR\(\d+.+CHAR\(\d+\))\)", retVal)
|
||||
if match:
|
||||
part = match.group(0)
|
||||
indexes = set(zeroDepthSearch(match.group(1), '+'))
|
||||
if not indexes:
|
||||
break
|
||||
chars = [char for char in part]
|
||||
for i in xrange(1, len(chars)):
|
||||
if i - 1 in indexes:
|
||||
chars[i] = ','
|
||||
replacement = "CONCAT%s" % "".join(chars)
|
||||
retVal = retVal.replace(part, replacement)
|
||||
else:
|
||||
break
|
||||
|
||||
return retVal
|
||||
|
||||
89
tamper/plus2fnconcat.py
Normal file
89
tamper/plus2fnconcat.py
Normal file
@@ -0,0 +1,89 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from lib.core.common import zeroDepthSearch
|
||||
from lib.core.enums import PRIORITY
|
||||
|
||||
__priority__ = PRIORITY.HIGHEST
|
||||
|
||||
def dependencies():
|
||||
pass
|
||||
|
||||
def tamper(payload, **kwargs):
|
||||
"""
|
||||
Replaces plus ('+') character with ODBC function {fn CONCAT()}
|
||||
|
||||
Tested against:
|
||||
* Microsoft SQL Server 2008
|
||||
|
||||
Requirements:
|
||||
* Microsoft SQL Server 2008+
|
||||
|
||||
Notes:
|
||||
* Useful in case ('+') character is filtered
|
||||
* https://msdn.microsoft.com/en-us/library/bb630290.aspx
|
||||
|
||||
>>> tamper('SELECT CHAR(113)+CHAR(114)+CHAR(115) FROM DUAL')
|
||||
'SELECT {fn CONCAT({fn CONCAT(CHAR(113),CHAR(114))},CHAR(115))} FROM DUAL'
|
||||
|
||||
>>> tamper('SELECT (CHAR(113)+CHAR(114)+CHAR(115)) FROM DUAL')
|
||||
'SELECT {fn CONCAT({fn CONCAT(CHAR(113),CHAR(114))},CHAR(115))} FROM DUAL'
|
||||
"""
|
||||
|
||||
retVal = payload
|
||||
|
||||
if payload:
|
||||
while True:
|
||||
indexes = zeroDepthSearch(retVal, '+')
|
||||
|
||||
if indexes:
|
||||
first, last = 0, 0
|
||||
for i in xrange(1, len(indexes)):
|
||||
if ' ' in retVal[indexes[0]:indexes[i]]:
|
||||
break
|
||||
else:
|
||||
last = i
|
||||
|
||||
start = retVal[:indexes[first]].rfind(' ') + 1
|
||||
end = (retVal[indexes[last] + 1:].find(' ') + indexes[last] + 1) if ' ' in retVal[indexes[last] + 1:] else len(retVal) - 1
|
||||
|
||||
count = 0
|
||||
chars = [char for char in retVal]
|
||||
for index in indexes[first:last + 1]:
|
||||
if count == 0:
|
||||
chars[index] = ','
|
||||
else:
|
||||
chars[index] = '\x01'
|
||||
count += 1
|
||||
|
||||
retVal = "%s%s%s)}%s" % (retVal[:start], "{fn CONCAT(" * count, ''.join(chars)[start:end].replace('\x01', ")},"), retVal[end:])
|
||||
else:
|
||||
match = re.search(r"\((CHAR\(\d+.+CHAR\(\d+\))\)", retVal)
|
||||
if match:
|
||||
part = match.group(0)
|
||||
indexes = set(zeroDepthSearch(match.group(1), '+'))
|
||||
if not indexes:
|
||||
break
|
||||
|
||||
count = 0
|
||||
chars = [char for char in part]
|
||||
for i in xrange(1, len(chars)):
|
||||
if i - 1 in indexes:
|
||||
if count == 0:
|
||||
chars[i] = ','
|
||||
else:
|
||||
chars[i] = '\x01'
|
||||
count += 1
|
||||
|
||||
replacement = "%s%s}" % (("{fn CONCAT(" * count)[:-1], "".join(chars).replace('\x01', ")},"))
|
||||
retVal = retVal.replace(part, replacement)
|
||||
else:
|
||||
break
|
||||
|
||||
return retVal
|
||||
54
tamper/space2morecomment.py
Normal file
54
tamper/space2morecomment.py
Normal file
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
from lib.core.enums import PRIORITY
|
||||
|
||||
__priority__ = PRIORITY.LOW
|
||||
|
||||
def dependencies():
|
||||
pass
|
||||
|
||||
def tamper(payload, **kwargs):
|
||||
"""
|
||||
Replaces space character (' ') with comments '/**_**/'
|
||||
|
||||
Tested against:
|
||||
* MySQL 5.0 and 5.5
|
||||
|
||||
Notes:
|
||||
* Useful to bypass weak and bespoke web application firewalls
|
||||
|
||||
>>> tamper('SELECT id FROM users')
|
||||
'SELECT/**_**/id/**_**/FROM/**_**/users'
|
||||
"""
|
||||
|
||||
retVal = payload
|
||||
|
||||
if payload:
|
||||
retVal = ""
|
||||
quote, doublequote, firstspace = False, False, False
|
||||
|
||||
for i in xrange(len(payload)):
|
||||
if not firstspace:
|
||||
if payload[i].isspace():
|
||||
firstspace = True
|
||||
retVal += "/**_**/"
|
||||
continue
|
||||
|
||||
elif payload[i] == '\'':
|
||||
quote = not quote
|
||||
|
||||
elif payload[i] == '"':
|
||||
doublequote = not doublequote
|
||||
|
||||
elif payload[i] == " " and not doublequote and not quote:
|
||||
retVal += "/**_**/"
|
||||
continue
|
||||
|
||||
retVal += payload[i]
|
||||
|
||||
return retVal
|
||||
26
thirdparty/pagerank/__init__.py
vendored
26
thirdparty/pagerank/__init__.py
vendored
@@ -1,26 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# The MIT License
|
||||
#
|
||||
# Copyright 2010 Corey Goldberg
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
#
|
||||
|
||||
pass
|
||||
87
thirdparty/pagerank/pagerank.py
vendored
87
thirdparty/pagerank/pagerank.py
vendored
@@ -1,87 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Script for getting Google Page Rank of page
|
||||
# Google Toolbar 3.0.x/4.0.x Pagerank Checksum Algorithm
|
||||
#
|
||||
# original from http://pagerank.gamesaga.net/
|
||||
# this version was adapted from http://www.djangosnippets.org/snippets/221/
|
||||
# by Corey Goldberg - 2010
|
||||
#
|
||||
# important update (http://www.seroundtable.com/google-pagerank-change-14132.html)
|
||||
# by Miroslav Stampar - 2012
|
||||
#
|
||||
# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
|
||||
|
||||
import sys
|
||||
import urllib
|
||||
import urllib2
|
||||
|
||||
def get_pagerank(url, timeout=10):
|
||||
url = url.encode('utf8') if isinstance(url, unicode) else url
|
||||
_ = 'http://toolbarqueries.google.com/tbr?client=navclient-auto&features=Rank&ch=%s&q=info:%s' % (check_hash(hash_url(url)), urllib.quote(url))
|
||||
try:
|
||||
req = urllib2.Request(_)
|
||||
rank = urllib2.urlopen(req, timeout=timeout).read().strip()[9:]
|
||||
except:
|
||||
rank = 'N/A'
|
||||
else:
|
||||
rank = '0' if not rank or not rank.isdigit() else rank
|
||||
return rank
|
||||
|
||||
def int_str(string_, integer, factor):
|
||||
for i in xrange(len(string_)) :
|
||||
integer *= factor
|
||||
integer &= 0xFFFFFFFF
|
||||
integer += ord(string_[i])
|
||||
|
||||
return integer
|
||||
|
||||
def hash_url(string_):
|
||||
c1 = int_str(string_, 0x1505, 0x21)
|
||||
c2 = int_str(string_, 0, 0x1003F)
|
||||
|
||||
c1 >>= 2
|
||||
c1 = ((c1 >> 4) & 0x3FFFFC0) | (c1 & 0x3F)
|
||||
c1 = ((c1 >> 4) & 0x3FFC00) | (c1 & 0x3FF)
|
||||
c1 = ((c1 >> 4) & 0x3C000) | (c1 & 0x3FFF)
|
||||
|
||||
t1 = (c1 & 0x3C0) << 4
|
||||
t1 |= c1 & 0x3C
|
||||
t1 = (t1 << 2) | (c2 & 0xF0F)
|
||||
|
||||
t2 = (c1 & 0xFFFFC000) << 4
|
||||
t2 |= c1 & 0x3C00
|
||||
t2 = (t2 << 0xA) | (c2 & 0xF0F0000)
|
||||
|
||||
return (t1 | t2)
|
||||
|
||||
def check_hash(hash_int):
|
||||
hash_str = '%u' % (hash_int)
|
||||
flag = 0
|
||||
check_byte = 0
|
||||
|
||||
i = len(hash_str) - 1
|
||||
while i >= 0:
|
||||
byte = int(hash_str[i])
|
||||
if 1 == (flag % 2):
|
||||
byte *= 2;
|
||||
byte = byte / 10 + byte % 10
|
||||
check_byte += byte
|
||||
flag += 1
|
||||
i -= 1
|
||||
|
||||
check_byte %= 10
|
||||
if 0 != check_byte:
|
||||
check_byte = 10 - check_byte
|
||||
if 1 == flag % 2:
|
||||
if 1 == check_byte % 2:
|
||||
check_byte += 9
|
||||
check_byte >>= 1
|
||||
|
||||
return '7' + str(check_byte) + hash_str
|
||||
|
||||
def main():
|
||||
print get_pagerank(sys.argv[1]) if len(sys.argv) > 1 else "[x] missing hostname"
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -20,13 +20,13 @@ c55b400b72acc43e0e59c87dd8bb8d75 extra/shellcodeexec/windows/shellcodeexec.x32.
|
||||
310efc965c862cfbd7b0da5150a5ad36 extra/sqlharvest/__init__.py
|
||||
7713aa366c983cdf1f3dbaa7383ea9e1 extra/sqlharvest/sqlharvest.py
|
||||
5df358defc488bee9b40084892e3d1cb lib/controller/action.py
|
||||
699fd4757390aedb5ad17f4316d17972 lib/controller/checks.py
|
||||
10edc8d1057e89c145218d4c5ccaaa31 lib/controller/controller.py
|
||||
b3eec7f44bcc5d784d171a187b7fe8cb lib/controller/handler.py
|
||||
9cb94acd4c59822a5e1a258c4d1a4860 lib/controller/checks.py
|
||||
dc386321e8813788f155dc557a78be8d lib/controller/controller.py
|
||||
d79481ab99acd739615e747d4a79d9d0 lib/controller/handler.py
|
||||
310efc965c862cfbd7b0da5150a5ad36 lib/controller/__init__.py
|
||||
178066b5737f0e719cbf9271051559a2 lib/core/agent.py
|
||||
19905ecb4437b94512cf21d5f1720091 lib/core/agent.py
|
||||
6cc95a117fbd34ef31b9aa25520f0e31 lib/core/bigarray.py
|
||||
445bd2c2fe0dcca0dd3aab87eb3839d3 lib/core/common.py
|
||||
145d131884dd5401d7a52effaea2ee9e lib/core/common.py
|
||||
5065a4242a8cccf72f91e22e1007ae63 lib/core/convert.py
|
||||
a8143dab9d3a27490f7d49b6b29ea530 lib/core/data.py
|
||||
7936d78b1a7f1f008ff92bf2f88574ba lib/core/datatype.py
|
||||
@@ -34,30 +34,30 @@ a8143dab9d3a27490f7d49b6b29ea530 lib/core/data.py
|
||||
47eecd5499eaa15e931793e1d1ac3566 lib/core/defaults.py
|
||||
4029f6869b36eb5f796c2bcc948f4fae lib/core/dicts.py
|
||||
77edcfd3d7c5522bb64baf59ac23a047 lib/core/dump.py
|
||||
0c0f18761e9bb61d289bfa884dcd7dbd lib/core/enums.py
|
||||
2acf5449c71bfae4feec8da538e70116 lib/core/enums.py
|
||||
9381a0c7e8bc19986299e84f4edda1a0 lib/core/exception.py
|
||||
310efc965c862cfbd7b0da5150a5ad36 lib/core/__init__.py
|
||||
9ba39bf66e9ecd469446bdbbeda906c3 lib/core/log.py
|
||||
e544108e2238d756c94a240e8a1ce061 lib/core/optiondict.py
|
||||
44a61841bcd0bafc4151e31d5a14287d lib/core/option.py
|
||||
66c9795e2e7da32f46f04497ae910070 lib/core/optiondict.py
|
||||
0324fce84ef88ed0416123f73c54a6d7 lib/core/option.py
|
||||
5f2f56e6c5f274408df61943f1e080c0 lib/core/profiling.py
|
||||
40be71cd774662a7b420caeb7051e7d5 lib/core/readlineng.py
|
||||
d8e9250f3775119df07e9070eddccd16 lib/core/replication.py
|
||||
785f86e3f963fa3798f84286a4e83ff2 lib/core/revision.py
|
||||
40c80b28b3a5819b737a5a17d4565ae9 lib/core/session.py
|
||||
75d8ca625f08e39702965b2b3569b5d8 lib/core/settings.py
|
||||
50edc9861e7441371210f5fae263207c lib/core/settings.py
|
||||
d91291997d2bd2f6028aaf371bf1d3b6 lib/core/shell.py
|
||||
2ad85c130cc5f2b3701ea85c2f6bbf20 lib/core/subprocessng.py
|
||||
afd0636d2e93c23f4f0a5c9b6023ea17 lib/core/target.py
|
||||
8970b88627902239d695280b1160e16c lib/core/testing.py
|
||||
ce5578a2e6b25dc6fd115133f92e0643 lib/core/threads.py
|
||||
5521241c750855a4e44747fbac7771c6 lib/core/threads.py
|
||||
ad74fc58fc7214802fd27067bce18dd2 lib/core/unescaper.py
|
||||
1f1fa616b5b19308d78c610ec8046399 lib/core/update.py
|
||||
4d13ed693401a498b6d073a2a494bd83 lib/core/wordlist.py
|
||||
310efc965c862cfbd7b0da5150a5ad36 lib/__init__.py
|
||||
8c4b04062db2245d9e190b413985202a lib/parse/banner.py
|
||||
7af43d486b7183862b932218ed4c988d lib/parse/cmdline.py
|
||||
1a71306c965d563ae2d01e4c48646030 lib/parse/configfile.py
|
||||
54f06c50771ce894a3c6a418d545f4bf lib/parse/cmdline.py
|
||||
3a31657bc38f277d0016ff6d50bde61f lib/parse/configfile.py
|
||||
14539f1be714d4f1ed042067d63bc50a lib/parse/handler.py
|
||||
64e5bb3ecbdd75144500588b437ba8da lib/parse/headers.py
|
||||
165dc27660c8559318009d44354f27cb lib/parse/html.py
|
||||
@@ -65,9 +65,9 @@ ad74fc58fc7214802fd27067bce18dd2 lib/core/unescaper.py
|
||||
0b010b7cdb2e42b5aa0caa59607279ad lib/parse/payloads.py
|
||||
a0444cc351cd6d29015ad16d9eb46ff4 lib/parse/sitemap.py
|
||||
403d873f1d2fd0c7f73d83f104e41850 lib/request/basicauthhandler.py
|
||||
c347898f7b2e3d59d0a108b16b0542a3 lib/request/basic.py
|
||||
4e89d0e13de2eb3576f5412b21e9b648 lib/request/comparison.py
|
||||
30d7b0df341762c5aa7aab537878ce05 lib/request/connect.py
|
||||
0035612a620934d7ebe6d18426cfb065 lib/request/basic.py
|
||||
ef48de622b0a6b4a71df64b0d2785ef8 lib/request/comparison.py
|
||||
74a2a83e3af11ab02088c79b6367ef29 lib/request/connect.py
|
||||
fb6b788d0016ab4ec5e5f661f0f702ad lib/request/direct.py
|
||||
cc1163d38e9b7ee5db2adac6784c02bb lib/request/dns.py
|
||||
5dcdb37823a0b5eff65cd1018bcf09e4 lib/request/httpshandler.py
|
||||
@@ -76,20 +76,20 @@ e68e1f00c7bb47b2c4ea6201995c56fb lib/request/inject.py
|
||||
dc1e0af84ee8eb421797d61c8cb8f172 lib/request/methodrequest.py
|
||||
bb9c165b050f7696b089b96b5947fac3 lib/request/pkihandler.py
|
||||
602d4338a9fceaaee40c601410d8ac0b lib/request/rangehandler.py
|
||||
e687a727b641211dfae7346b671059c5 lib/request/redirecthandler.py
|
||||
b581e0c5e27cd927883f2c7f1705bf4e lib/request/redirecthandler.py
|
||||
20a0e6dac2edcf98fa8c47ee9a332c28 lib/request/templates.py
|
||||
36518b36ae0cf199490457916a85b367 lib/takeover/abstraction.py
|
||||
c6bc7961a186baabe0a9f5b7e0d8974b lib/takeover/icmpsh.py
|
||||
310efc965c862cfbd7b0da5150a5ad36 lib/takeover/__init__.py
|
||||
71d45fd7f11804872284ee3ae5e60970 lib/takeover/metasploit.py
|
||||
c90c993b020a6ae0f0e497fd84f37466 lib/takeover/metasploit.py
|
||||
ac541a0d38e4ecb4e41e97799a7235f4 lib/takeover/registry.py
|
||||
4cd0322f22fbc26284cffa9f8f7545ef lib/takeover/udf.py
|
||||
a610e0ef2fb8512604c2b6c081174850 lib/takeover/web.py
|
||||
ab021269ad7f4d552025448ae08c51d0 lib/takeover/web.py
|
||||
e5a82481947e798d0c11f3acf3e9db60 lib/takeover/xp_cmdshell.py
|
||||
cae752650755c706272a45ae84519a4b lib/techniques/blind/inference.py
|
||||
310efc965c862cfbd7b0da5150a5ad36 lib/techniques/blind/__init__.py
|
||||
310efc965c862cfbd7b0da5150a5ad36 lib/techniques/brute/__init__.py
|
||||
b24fa5fe58828e00a84991015c561f59 lib/techniques/brute/use.py
|
||||
a693c023a9fed1eebb9ca9ef51e0aeb8 lib/techniques/brute/use.py
|
||||
310efc965c862cfbd7b0da5150a5ad36 lib/techniques/dns/__init__.py
|
||||
ab1601a7f429b47637c4fb8af703d0f1 lib/techniques/dns/test.py
|
||||
d3da4c7ceaf57c4687a052d58722f6bb lib/techniques/dns/use.py
|
||||
@@ -97,56 +97,56 @@ d3da4c7ceaf57c4687a052d58722f6bb lib/techniques/dns/use.py
|
||||
2fb0eb698fc9d6e19960d2136bce787d lib/techniques/error/use.py
|
||||
310efc965c862cfbd7b0da5150a5ad36 lib/techniques/__init__.py
|
||||
310efc965c862cfbd7b0da5150a5ad36 lib/techniques/union/__init__.py
|
||||
4bed3ed51faad9b910899cacf56e8eac lib/techniques/union/test.py
|
||||
19fd73af7a278fd72b46a5a60f5bdd09 lib/techniques/union/test.py
|
||||
8cd5655c60a638caa30ca1220896aeda lib/techniques/union/use.py
|
||||
b3afde39a56dd767f5338ba6464b9f43 lib/utils/api.py
|
||||
6842092e1d27b71d28acd0e421f90693 lib/utils/crawler.py
|
||||
b8c9bbf1a50f1b2fdd0d3644922e252a lib/utils/api.py
|
||||
29e32d59fcdd63c5a13498af1f367c8c lib/utils/crawler.py
|
||||
ba12c69a90061aa14d848b8396e79191 lib/utils/deps.py
|
||||
3b9fd519164e0bf275d5fd361c3f11ff lib/utils/getch.py
|
||||
ccfdad414ce2ec0c394c3deaa39a82bf lib/utils/hashdb.py
|
||||
aff7355d582fc6c00a675eeee2a5217a lib/utils/hash.py
|
||||
e76a08237ee6a4cd6855af79610ea8a5 lib/utils/htmlentities.py
|
||||
310efc965c862cfbd7b0da5150a5ad36 lib/utils/__init__.py
|
||||
8e4ecc5e5bd8a5c7e2ad0a940cb1a5b1 lib/utils/pivotdumptable.py
|
||||
9d8c858417d356e49e1959ba253aede4 lib/utils/pivotdumptable.py
|
||||
8520a745c9b4db3814fe46f4c34c6fbc lib/utils/progress.py
|
||||
2c3638d499f3c01c34187e531f77d004 lib/utils/purge.py
|
||||
2da1b35339667646e51101adaa1dfc32 lib/utils/search.py
|
||||
569521a83b2b6c62497879267b963b21 lib/utils/sqlalchemy.py
|
||||
caeea96ec9c9d489f615f282259b32ca lib/utils/timeout.py
|
||||
0b84e74f9eb7681bab7364617e2f2577 lib/utils/versioncheck.py
|
||||
6fa36b9742293756b226cddee11b7d52 lib/utils/versioncheck.py
|
||||
31c51a3cc73120ee9490f2e3fa6d0dca lib/utils/xrange.py
|
||||
b90aae84100a6c4c2bd5eeb4197fbc6e plugins/dbms/access/connector.py
|
||||
a71f7c8ffcb9b250cc785cad830e8980 plugins/dbms/access/enumeration.py
|
||||
38a0c758d9b86915fce894b779e79e4d plugins/dbms/access/filesystem.py
|
||||
818482929a68a270bc4331cf6c436d13 plugins/dbms/access/fingerprint.py
|
||||
fe34217a0b79ac25e3af007dd46cd340 plugins/dbms/access/fingerprint.py
|
||||
5a691580a59eca29bae2283b57682025 plugins/dbms/access/__init__.py
|
||||
c12f4f266830636462eac98e35ebb73e plugins/dbms/access/syntax.py
|
||||
3fc75c350a30597962bc692c973eeeb3 plugins/dbms/access/takeover.py
|
||||
a763887d6e6e99c5a73d9cf450cd84fe plugins/dbms/db2/connector.py
|
||||
c1f6eeb6fccbcb75b53566568c582e9c plugins/dbms/db2/enumeration.py
|
||||
9d54e01e1576a423159f0e47aeb2837a plugins/dbms/db2/enumeration.py
|
||||
667e50aa06883f0f194bef335015d694 plugins/dbms/db2/filesystem.py
|
||||
d82e641f156d7c0fe015510a2f593b16 plugins/dbms/db2/fingerprint.py
|
||||
9c6ef13c056a256e4704b924af0d7cc6 plugins/dbms/db2/fingerprint.py
|
||||
35ed6e262cf68d4ab2c6111dd5fb0414 plugins/dbms/db2/__init__.py
|
||||
ce8bc86383f2ade41e08f2dbee1844bf plugins/dbms/db2/syntax.py
|
||||
744fb5044f2b9f9d5ebda6e3f08e3be7 plugins/dbms/db2/takeover.py
|
||||
b8dcd6e97166f58ee452e68c46bfe2c4 plugins/dbms/firebird/connector.py
|
||||
147afe5f4a3d09548a8a1dbc954fe29e plugins/dbms/firebird/enumeration.py
|
||||
4e421504f59861bf1ed1a89abda583d1 plugins/dbms/firebird/filesystem.py
|
||||
fc6fdb1fb1be84db541995c87746efe1 plugins/dbms/firebird/fingerprint.py
|
||||
bbd239cd27b35c2fbd29443f0af5d973 plugins/dbms/firebird/fingerprint.py
|
||||
f86ace7fcaea5ff3f9e86ab2dce052c5 plugins/dbms/firebird/__init__.py
|
||||
04f7c2977ab5198c6f4aa6233b872ae0 plugins/dbms/firebird/syntax.py
|
||||
1cb1ab93e4b8c97e81586acfe4d030a2 plugins/dbms/firebird/takeover.py
|
||||
3a97bd07cce66bc812309341e7b54697 plugins/dbms/hsqldb/connector.py
|
||||
015281fb8f96dbade0d2e30fc8da9c4c plugins/dbms/hsqldb/enumeration.py
|
||||
c0b14e62e1ecbb679569a1abb9cf1913 plugins/dbms/hsqldb/filesystem.py
|
||||
205ec651547b3fef04afc9580ab35672 plugins/dbms/hsqldb/fingerprint.py
|
||||
82304c5d7b06bb564dcdd8cda84dbeae plugins/dbms/hsqldb/fingerprint.py
|
||||
0b18e3cf582b128cf9f16ee34ef85727 plugins/dbms/hsqldb/__init__.py
|
||||
65e8f8edc9d18fe482deb474a29f83ff plugins/dbms/hsqldb/syntax.py
|
||||
0a1584e2b01f33abe3ef91d99bafbd3f plugins/dbms/hsqldb/takeover.py
|
||||
f8eaeb71239369e6ceff47596439871b plugins/dbms/informix/connector.py
|
||||
989e75a65503dd648a45258217ae3371 plugins/dbms/informix/enumeration.py
|
||||
667e50aa06883f0f194bef335015d694 plugins/dbms/informix/filesystem.py
|
||||
df241894bc46576590fae7809650aa58 plugins/dbms/informix/fingerprint.py
|
||||
f06d263b2c9b52ea7a120593eb5806c4 plugins/dbms/informix/fingerprint.py
|
||||
859d2ed1e0c1b8a1b92c8b2044e6afc5 plugins/dbms/informix/__init__.py
|
||||
0aa8ec7b83435a1ecec19c5320728051 plugins/dbms/informix/syntax.py
|
||||
744fb5044f2b9f9d5ebda6e3f08e3be7 plugins/dbms/informix/takeover.py
|
||||
@@ -154,58 +154,58 @@ df241894bc46576590fae7809650aa58 plugins/dbms/informix/fingerprint.py
|
||||
e50b624ff23c3e180d80e065deb1763f plugins/dbms/maxdb/connector.py
|
||||
cbd90f22ce862409fe392e65f0ea94ac plugins/dbms/maxdb/enumeration.py
|
||||
815ea8e7b9bd714d73d9d6c454aff774 plugins/dbms/maxdb/filesystem.py
|
||||
30ace2bbd22cf6152e4a7e9d8176bdc1 plugins/dbms/maxdb/fingerprint.py
|
||||
017c723354eff28188773670d3837c01 plugins/dbms/maxdb/fingerprint.py
|
||||
c03001c1f70e76de39d26241dfcbd033 plugins/dbms/maxdb/__init__.py
|
||||
e6036f5b2e39aec37ba036a8cf0efd6f plugins/dbms/maxdb/syntax.py
|
||||
0be362015605e26551e5d79cc83ed466 plugins/dbms/maxdb/takeover.py
|
||||
e3e78fab9b5eb97867699f0b20e59b62 plugins/dbms/mssqlserver/connector.py
|
||||
a7ed0510e47384eaf93164d53e2b6b36 plugins/dbms/mssqlserver/enumeration.py
|
||||
8554437c437052c30237be170ba8ce3a plugins/dbms/mssqlserver/filesystem.py
|
||||
4e4bb17dfb175b5f6485d7513e4c8fb1 plugins/dbms/mssqlserver/fingerprint.py
|
||||
13cb15e8abfb05818e6f66c687b78664 plugins/dbms/mssqlserver/fingerprint.py
|
||||
40bd890988f9acd3942255d687445371 plugins/dbms/mssqlserver/__init__.py
|
||||
400ce654ff6bc57a40fb291322a18282 plugins/dbms/mssqlserver/syntax.py
|
||||
20c669e084ea4d6b968a5834f7fec66c plugins/dbms/mssqlserver/takeover.py
|
||||
48fb283a0dbf980495ca054f7b55783f plugins/dbms/mysql/connector.py
|
||||
7fe94b803fa273baf479b76ce7a3fb51 plugins/dbms/mysql/enumeration.py
|
||||
1bd5e659962e814b66a451b807de9110 plugins/dbms/mysql/filesystem.py
|
||||
e9076fe684eb3fe037f945601c7017f0 plugins/dbms/mysql/fingerprint.py
|
||||
1a17c2dea2cd7554cf9082fdf96f8360 plugins/dbms/mysql/fingerprint.py
|
||||
42568a66a13a43ed46748290c503a652 plugins/dbms/mysql/__init__.py
|
||||
96dfafcc4aecc1c574148ac05dbdb6da plugins/dbms/mysql/syntax.py
|
||||
33b2dc28075ab560fd8a4dc898682a0d plugins/dbms/mysql/takeover.py
|
||||
ea4b9cd238075b79945bd2607810934a plugins/dbms/oracle/connector.py
|
||||
3a08ef0037de6df9f9a92ec5b126d705 plugins/dbms/oracle/enumeration.py
|
||||
dc5962a1d4d69d4206b6c03e00e7f33d plugins/dbms/oracle/filesystem.py
|
||||
d19215a6aee5d04d67ee67eb2cac9893 plugins/dbms/oracle/fingerprint.py
|
||||
525381f48505095b14e567c1f59ca9c7 plugins/dbms/oracle/fingerprint.py
|
||||
25a99a9dd7072b6b7346438599c78050 plugins/dbms/oracle/__init__.py
|
||||
783d4795fac75f73a7cfba3cd9c3d01c plugins/dbms/oracle/syntax.py
|
||||
c05176f6efe66069756fb78dfa0ed3f6 plugins/dbms/oracle/takeover.py
|
||||
e087d54b9b2617a9f40be15a2bd478c2 plugins/dbms/postgresql/connector.py
|
||||
8377c5ab3de500f9a495fcd9e2a75d3e plugins/dbms/postgresql/enumeration.py
|
||||
48822058c620ffaa2acc599b4d39c667 plugins/dbms/postgresql/filesystem.py
|
||||
1d514afa3106fa5fbd6fa2dd33970917 plugins/dbms/postgresql/fingerprint.py
|
||||
c10df993e8b243ba3d6a94e8ae28a875 plugins/dbms/postgresql/fingerprint.py
|
||||
a3a4e82e9a68329c44762897c87acfec plugins/dbms/postgresql/__init__.py
|
||||
76bde1ffb3040ae709156449a583e9ed plugins/dbms/postgresql/syntax.py
|
||||
286f95526a6ce0b8ae9bff6fc3117af0 plugins/dbms/postgresql/takeover.py
|
||||
719fdd12e360458e822950f245d67ad0 plugins/dbms/sqlite/connector.py
|
||||
28b9d7d0614e52275a30b5a57fc76027 plugins/dbms/sqlite/enumeration.py
|
||||
954e503cfc8dd1acf9fc50868f5dafb0 plugins/dbms/sqlite/filesystem.py
|
||||
60febaa44bd2fe5919e80e3bd7f0c2dd plugins/dbms/sqlite/fingerprint.py
|
||||
ee430d142fa8f9ee571578d0a0916679 plugins/dbms/sqlite/fingerprint.py
|
||||
6b17cc8cc94a912a0a5cf15acbad5ba4 plugins/dbms/sqlite/__init__.py
|
||||
4827722159a89652005f49265bb55c43 plugins/dbms/sqlite/syntax.py
|
||||
02ab8ff465da9dd31ffe6a963c676180 plugins/dbms/sqlite/takeover.py
|
||||
e3e78fab9b5eb97867699f0b20e59b62 plugins/dbms/sybase/connector.py
|
||||
a7f4d3a194f52fbb4fb4488be41273b1 plugins/dbms/sybase/enumeration.py
|
||||
62d772c7cd08275e3503304ba90c4e8a plugins/dbms/sybase/filesystem.py
|
||||
9e3e9a1f8dd491a95e833155a4157662 plugins/dbms/sybase/fingerprint.py
|
||||
deed74334b637767fc9de8f74b37647a plugins/dbms/sybase/fingerprint.py
|
||||
45436a42c2bb8075e1482a950d993d55 plugins/dbms/sybase/__init__.py
|
||||
89412a921c8c598c19d36762d5820f05 plugins/dbms/sybase/syntax.py
|
||||
654cd5e69cf5e5c644bfa5d284e61206 plugins/dbms/sybase/takeover.py
|
||||
1f46f2eac95cfdc3fa150ec5b0500eba plugins/generic/connector.py
|
||||
be7481a96214220bcd8f51ca00239bed plugins/generic/connector.py
|
||||
a8f9d0516509e9e4226516ab4f13036a plugins/generic/custom.py
|
||||
3b54fd65feb9f70c551d315e82653384 plugins/generic/databases.py
|
||||
085f839221138aa7931bd94c33a32768 plugins/generic/entries.py
|
||||
f7387352380136ac05c0bc3decb85638 plugins/generic/entries.py
|
||||
55802d1d5d65938414c77ccc27731cab plugins/generic/enumeration.py
|
||||
b6666109aa6882ca9c526d615c1bcde3 plugins/generic/filesystem.py
|
||||
bc32b21a3ab5421b5307ff7317256229 plugins/generic/filesystem.py
|
||||
feca57a968c528a2fe3ccafbc83a17f8 plugins/generic/fingerprint.py
|
||||
310efc965c862cfbd7b0da5150a5ad36 plugins/generic/__init__.py
|
||||
8fd5913823e97e21a8eea717cd12fc96 plugins/generic/misc.py
|
||||
@@ -252,13 +252,15 @@ a3a0e76922b4f40f422a0daca4e71af3 tamper/htmlencode.py
|
||||
54e1793f30c755202ee1acaacfac45fb tamper/nonrecursivereplacement.py
|
||||
00ba60e5869055aaa7ba0cd23b5ed1f4 tamper/overlongutf8.py
|
||||
3cadacb0f39de03e0f8612c656104e03 tamper/percentage.py
|
||||
7805efc7af932c2ab452f41967f9eb7b tamper/plus2concat.py
|
||||
3e09fc9f1a6f3fee03f9213aaee97191 tamper/plus2concat.py
|
||||
7a18480b27d62eb574cf0150a57e81b1 tamper/plus2fnconcat.py
|
||||
24753ed4e8ceab6f1a1fc13ee621943b tamper/randomcase.py
|
||||
4d5fdfe77668fa44967e1d44f8a50ce7 tamper/randomcomments.py
|
||||
22561b429f41fc0bdd23e36b9a8de9e5 tamper/securesphere.py
|
||||
a8a0e2150de7c7dc473f74474db857ad tamper/space2comment.py
|
||||
8728a16a1ae0603c6d835162cc03ab96 tamper/space2dash.py
|
||||
6cc1afaeb47723886e492454e75d7b7f tamper/space2hash.py
|
||||
b2331640743170f82be9a8c27f65b206 tamper/space2morecomment.py
|
||||
507a174c64345df8df003ddba93c8cd1 tamper/space2morehash.py
|
||||
0ce89b0d602abbd64344ab038be8acbc tamper/space2mssqlblank.py
|
||||
fa66af20648b5538289748abe7a08fe6 tamper/space2mssqlhash.py
|
||||
@@ -343,8 +345,6 @@ d41d8cd98f00b204e9800998ecf8427e thirdparty/multipart/__init__.py
|
||||
08801ea0ba9ae22885275ef65d3ee9dc thirdparty/oset/_abc.py
|
||||
54a861de0f08bb80c2e8846579ec83bd thirdparty/oset/__init__.py
|
||||
179f0c584ef3fb39437bdb6e15d9c867 thirdparty/oset/pyoset.py
|
||||
d24924d878e24946e83cfc1459f806af thirdparty/pagerank/__init__.py
|
||||
7616693115d08f9b815a567515a0db56 thirdparty/pagerank/pagerank.py
|
||||
94a4abc0fdac64ef0661b82aff68d791 thirdparty/prettyprint/__init__.py
|
||||
ff80a22ee858f5331b0c088efa98b3ff thirdparty/prettyprint/prettyprint.py
|
||||
5c70f8e5f7353aedc6d8d21d4fb72b37 thirdparty/pydes/__init__.py
|
||||
@@ -400,9 +400,9 @@ ab6f6e3169cb43efcf5b6ed84b58252f waf/comodo.py
|
||||
7bde9f5ec27b41167d25a3a24853107b waf/dotdefender.py
|
||||
e4b058d759198216d24f8fed6ef97be4 waf/edgecast.py
|
||||
f633953970fb181b9ac5420a47e6a610 waf/expressionengine.py
|
||||
f2295bb96025aeeca7e38661aef7c883 waf/fortiweb.py
|
||||
1df78b6ad49259514cb6e4d68371cbcf waf/fortiweb.py
|
||||
ef151fbc34f16620958ba61dd415ae59 waf/generic.py
|
||||
9126fc8101dee36c27866df731e2d841 waf/hyperguard.py
|
||||
d50e17ed49e1a3cb846e652ed98e3b3c waf/hyperguard.py
|
||||
5b5382ccfb82ee6afdc1b47c8a4bce70 waf/incapsula.py
|
||||
310efc965c862cfbd7b0da5150a5ad36 waf/__init__.py
|
||||
5a364b68519a5872c4d60be11d2a23c1 waf/isaserver.py
|
||||
@@ -428,6 +428,7 @@ d4fbb2af37ad3ade3118668f2b516693 waf/requestvalidationmode.py
|
||||
c1062e5c165cdaeca51113e60973afb2 waf/sophos.py
|
||||
e909c359a9181e64271e6c7c8347fe15 waf/stingray.py
|
||||
33f3bdac403519a1f96fb9015680c575 waf/sucuri.py
|
||||
507f7c1019afd1c45c76bbcd179ddfe9 waf/tencent.py
|
||||
3de96df7edeae2f21ba7b9d77c90f4d6 waf/teros.py
|
||||
d428df1e83a6fac9d8dbc90d6b5dab20 waf/trafficshield.py
|
||||
385c84908b482c7f0fe93262ab5320fa waf/urlscan.py
|
||||
|
||||
@@ -10,7 +10,7 @@ import re
|
||||
from lib.core.enums import HTTP_HEADER
|
||||
from lib.core.settings import WAF_ATTACK_VECTORS
|
||||
|
||||
__product__ = "FortiWeb Web Application Firewall (Fortinet Inc.)"
|
||||
__product__ = "FortiWeb Web Application Firewall (Fortinet)"
|
||||
|
||||
def detect(get_page):
|
||||
retval = False
|
||||
|
||||
@@ -10,7 +10,7 @@ import re
|
||||
from lib.core.enums import HTTP_HEADER
|
||||
from lib.core.settings import WAF_ATTACK_VECTORS
|
||||
|
||||
__product__ = "Hyperguard Web Application Firewall (art of defence Inc.)"
|
||||
__product__ = "Hyperguard Web Application Firewall (art of defence)"
|
||||
|
||||
def detect(get_page):
|
||||
retval = False
|
||||
|
||||
23
waf/tencent.py
Normal file
23
waf/tencent.py
Normal file
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from lib.core.settings import WAF_ATTACK_VECTORS
|
||||
|
||||
__product__ = "Tencent Cloud Web Application Firewall (Tencent Cloud Computing)"
|
||||
|
||||
def detect(get_page):
|
||||
retval = False
|
||||
|
||||
for vector in WAF_ATTACK_VECTORS:
|
||||
page, _, code = get_page(get=vector)
|
||||
retval = code == 405 and "waf.tencent-cloud.com" in (page or "")
|
||||
if retval:
|
||||
break
|
||||
|
||||
return retval
|
||||
Reference in New Issue
Block a user