Compare commits

...
44 Commits
Author SHA1 Message Date
Miroslav Stampar e7268ffb4d Fixes #2809 2017-12-01 10:32:44 +01:00
Miroslav Stampar 7c5b051d60 Fixes #2808 2017-11-29 15:59:00 +01:00
Miroslav Stampar 5899fd5ef2 Update related to the #2806 2017-11-27 22:24:44 +01:00
Miroslav Stampar f60727a891 Minor update of sitelock.py 2017-11-26 12:11:09 +01:00
Miroslav Stampar 792ed52ab5 New WAF scripts 2017-11-26 12:06:23 +01:00
Miroslav Stampar 132a72c9bd Minor update of logging messages 2017-11-24 12:20:57 +01:00
Miroslav Stampar 8735a49f63 Some more refactoring 2017-11-24 11:49:31 +01:00
Miroslav Stampar b9e2e8b74d Minor refactoring 2017-11-24 11:44:14 +01:00
Miroslav Stampar b23626db70 Minor update 2017-11-24 11:36:27 +01:00
Miroslav Stampar 33d8ce8923 Minor patches 2017-11-24 10:54:03 +01:00
Miroslav Stampar 72f7caa23b Minor refactoring 2017-11-24 10:38:29 +01:00
Miroslav Stampar 284bdac72c Minor patch 2017-11-22 16:17:14 +01:00
Miroslav Stampar 7d6a3c4034 Refactoring shell files 2017-11-22 15:59:29 +01:00
Miroslav Stampar 02274f6db1 Minor patch (smoke test failed) 2017-11-22 13:31:44 +01:00
Miroslav Stampar bf8b2eb21e Minor update regarding #2791 2017-11-22 13:29:39 +01:00
Vitaly Salnikov 1436333960 Add new tamper script witch can Replaces instances like 'IFNULL(A, B)' with 'CASE WHEN ISNULL(A) THEN (B) ELSE (A) END', it could be usefull for bypass some weak WAFs that filter the 'IFNULL' and 'IF' functions (#2791) 2017-11-22 13:27:49 +01:00
Miroslav Stampar d7677f322d Fixes #2793 2017-11-22 13:07:04 +01:00
Miroslav Stampar ab641e9242 Minor improvement for sonicwall WAF script 2017-11-21 09:23:16 +01:00
Miroslav Stampar ec83837342 Fixes #2786 2017-11-19 02:51:29 +01:00
Miroslav Stampar 2333903b68 Fixes #2785 2017-11-19 02:16:52 +01:00
Miroslav Stampar d54ec88648 Adding compression to BigArray mechanism (to save disk space on big dumps) 2017-11-17 11:45:02 +01:00
Houziaux Mike f210d66dff fix wording to french documentation (#2782) 2017-11-17 09:39:48 +01:00
Miroslav Stampar a651c8a637 Fixes #2779 2017-11-15 10:36:32 +01:00
Miroslav Stampar b608c21dff Fixes #2778 2017-11-15 09:51:20 +01:00
Miroslav Stampar 88df293a1a Better approach as @cachedmethod got improved 2017-11-13 22:53:22 +01:00
Miroslav Stampar 323f1285b6 Fixes #2774 2017-11-13 14:07:12 +01:00
Miroslav Stampar 26b81f58bb Fixes #2772 2017-11-13 11:19:25 +01:00
Miroslav Stampar 839070d6ee Minor refactoring 2017-11-10 13:03:24 +01:00
Miroslav Stampar 28ee12c4d2 Adding delayed imports 2017-11-10 12:34:54 +01:00
Miroslav Stampar bc61a6828c Quick patch for #2770 2017-11-10 10:45:20 +01:00
Miroslav Stampar e9380627e1 Better one for Issue #2769 2017-11-10 00:44:33 +01:00
Miroslav Stampar e80e841b25 Update related to the Issue #2769 2017-11-10 00:41:03 +01:00
Miroslav Stampar 4102d87521 Better SELECT_FROM_TABLE_REGEX regex 2017-11-09 13:56:01 +01:00
Miroslav Stampar 67b470245e Minor cleanup of NULL connection 2017-11-09 13:45:52 +01:00
Miroslav Stampar d148694a4b Minor refactoring 2017-11-09 12:24:58 +01:00
Miroslav Stampar 9404b63a42 Some memory improvements of @cachedmethod 2017-11-09 12:24:11 +01:00
Miroslav Stampar 58b87e4b6b Some more refactoring 2017-11-08 15:58:23 +01:00
Miroslav Stampar 5c35aff22a Minor refactoring 2017-11-08 15:47:12 +01:00
Miroslav Stampar 18d78a34cc Removing unused methods 2017-11-06 13:53:35 +01:00
Thomas f9e80adcef Minor update to Sucuri WAF script (#2761) 2017-11-06 13:09:24 +01:00
Miroslav Stampar e5f96102af Fixes #2763 2017-11-06 10:53:50 +01:00
Miroslav Stampar d9bf33ea1d Minor beauty patch 2017-11-06 10:36:17 +01:00
Miroslav Stampar 0d1ea50785 Fixes #2762 2017-11-06 10:00:29 +01:00
Miroslav Stampar cc37b12d37 Minor update 2017-11-02 14:31:16 +01:00
40 changed files with 339 additions and 216 deletions
+4 -4
View File
@@ -13,7 +13,7 @@ Les captures d'écran disponible [ici](https://github.com/sqlmapproject/sqlmap/w
Installation
----
Vous pouvez télécharger le plus récent fichier tarball en cliquant [ici](https://github.com/sqlmapproject/sqlmap/tarball/master). Vous pouvez aussi télécharger le plus récent archive zip [ici](https://github.com/sqlmapproject/sqlmap/zipball/master).
Vous pouvez télécharger le fichier "tarball" le plus récent en cliquant [ici](https://github.com/sqlmapproject/sqlmap/tarball/master). Vous pouvez aussi télécharger l'archive zip la plus récente [ici](https://github.com/sqlmapproject/sqlmap/zipball/master).
De préférence, télécharger __sqlmap__ en le [clonant](https://github.com/sqlmapproject/sqlmap):
@@ -21,7 +21,7 @@ De préférence, télécharger __sqlmap__ en le [clonant](https://github.com/sql
sqlmap fonctionne sur n'importe quel système d'exploitation avec la version **2.6.x** et **2.7.x** de [Python](http://www.python.org/download/)
Usage
Utilisation
----
Pour afficher une liste des fonctions de bases et des commutateurs (switches), tapez:
@@ -33,7 +33,7 @@ Pour afficher une liste complète des options et des commutateurs (switches), ta
python sqlmap.py -hh
Vous pouvez regarder un vidéo [ici](https://asciinema.org/a/46601) pour plus d'exemples.
Pour obtenir un aperçu des ressources de __sqlmap__, une liste des fonctionnalités prises en charge et la description de toutes les options, ainsi que des exemples , nous vous recommandons de consulter [le wiki](https://github.com/sqlmapproject/sqlmap/wiki/Usage).
Pour obtenir un aperçu des ressources de __sqlmap__, une liste des fonctionnalités prises en charge, la description de toutes les options, ainsi que des exemples, nous vous recommandons de consulter [le wiki](https://github.com/sqlmapproject/sqlmap/wiki/Usage).
Liens
----
@@ -41,7 +41,7 @@ Liens
* Page d'acceuil: http://sqlmap.org
* Téléchargement: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) ou [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
* Commits RSS feed: https://github.com/sqlmapproject/sqlmap/commits/master.atom
* Issue tracker: https://github.com/sqlmapproject/sqlmap/issues
* Suivi des issues: https://github.com/sqlmapproject/sqlmap/issues
* Manuel de l'utilisateur: https://github.com/sqlmapproject/sqlmap/wiki
* Foire aux questions (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
* Twitter: [@sqlmap](https://twitter.com/sqlmap)
+23 -22
View File
@@ -7,6 +7,7 @@ See the file 'LICENSE' for copying permission
import copy
import httplib
import logging
import os
import random
import re
@@ -42,6 +43,7 @@ from lib.core.common import readInput
from lib.core.common import showStaticWords
from lib.core.common import singleTimeLogMessage
from lib.core.common import singleTimeWarnMessage
from lib.core.common import unArrayizeValue
from lib.core.common import urlencode
from lib.core.common import wasLastResponseDBMSError
from lib.core.common import wasLastResponseHTTPError
@@ -281,9 +283,9 @@ def checkSqlInjection(place, parameter, value):
# Skip DBMS-specific test if it does not match the
# previously identified DBMS (via DBMS-specific error message)
if kb.reduceTests and not intersect(payloadDbms, kb.reduceTests, True):
debugMsg = "skipping test '%s' because the parsed " % title
debugMsg += "error message(s) showed that the back-end DBMS "
debugMsg += "could be %s" % Format.getErrorParsedDBMSes()
debugMsg = "skipping test '%s' because the heuristic " % title
debugMsg += "tests showed that the back-end DBMS "
debugMsg += "could be '%s'" % unArrayizeValue(kb.reduceTests)
logger.debug(debugMsg)
continue
@@ -574,7 +576,7 @@ def checkSqlInjection(place, parameter, value):
page, headers, _ = Request.queryPage(reqPayload, place, content=True, raise404=False)
output = extractRegexResult(check, page, re.DOTALL | re.IGNORECASE) \
or extractRegexResult(check, threadData.lastHTTPError[2] if wasLastResponseHTTPError() else None, re.DOTALL | re.IGNORECASE) \
or extractRegexResult(check, listToStrValue([headers[key] for key in headers.keys() if key.lower() != URI_HTTP_HEADER.lower()] if headers else None), re.DOTALL | re.IGNORECASE) \
or extractRegexResult(check, listToStrValue((headers[key] for key in headers.keys() if key.lower() != URI_HTTP_HEADER.lower()) if headers else None), re.DOTALL | re.IGNORECASE) \
or extractRegexResult(check, threadData.lastRedirectMsg[1] if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == threadData.lastRequestUID else None, re.DOTALL | re.IGNORECASE)
if output:
@@ -629,11 +631,12 @@ def checkSqlInjection(place, parameter, value):
Backend.forceDbms(kb.dbmsFilter[0])
elif not Backend.getIdentifiedDbms():
if kb.heuristicDbms is None:
warnMsg = "using unescaped version of the test "
warnMsg += "because of zero knowledge of the "
warnMsg += "back-end DBMS. You can try to "
warnMsg += "explicitly set it with option '--dbms'"
singleTimeWarnMessage(warnMsg)
if kb.heuristicTest == HEURISTIC_TEST.POSITIVE or injection.data:
warnMsg = "using unescaped version of the test "
warnMsg += "because of zero knowledge of the "
warnMsg += "back-end DBMS. You can try to "
warnMsg += "explicitly set it with option '--dbms'"
singleTimeWarnMessage(warnMsg)
else:
Backend.forceDbms(kb.heuristicDbms)
@@ -1143,16 +1146,16 @@ def checkDynamicContent(firstPage, secondPage):
count += 1
if count > conf.retries:
warnMsg = "target URL is too dynamic. "
warnMsg = "target URL content appears to be too dynamic. "
warnMsg += "Switching to '--text-only' "
logger.warn(warnMsg)
conf.textOnly = True
return
warnMsg = "target URL is heavily dynamic"
warnMsg += ". sqlmap is going to retry the request"
logger.critical(warnMsg)
warnMsg = "target URL content appears to be heavily dynamic. "
warnMsg += "sqlmap is going to retry the request(s)"
singleTimeLogMessage(warnMsg, logging.CRITICAL)
secondPage, _, _ = Request.queryPage(content=True)
findDynamicContent(firstPage, secondPage)
@@ -1168,7 +1171,7 @@ def checkStability():
like for instance string matching (--string).
"""
infoMsg = "testing if the target URL is stable"
infoMsg = "testing if the target URL content is stable"
logger.info(infoMsg)
firstPage = kb.originalPage # set inside checkConnection()
@@ -1186,7 +1189,7 @@ def checkStability():
if kb.pageStable:
if firstPage:
infoMsg = "target URL is stable"
infoMsg = "target URL content is stable"
logger.info(infoMsg)
else:
errMsg = "there was an error checking the stability of page "
@@ -1196,12 +1199,11 @@ def checkStability():
logger.error(errMsg)
else:
warnMsg = "target URL is not stable. sqlmap will base the page "
warnMsg = "target URL content is not stable. sqlmap will base the page "
warnMsg += "comparison on a sequence matcher. If no dynamic nor "
warnMsg += "injectable parameters are detected, or in case of "
warnMsg += "junk results, refer to user's manual paragraph "
warnMsg += "'Page comparison' and provide a string or regular "
warnMsg += "expression to match on"
warnMsg += "'Page comparison'"
logger.warn(warnMsg)
message = "how do you want to proceed? [(C)ontinue/(s)tring/(r)egex/(q)uit] "
@@ -1454,7 +1456,7 @@ def checkNullConnection():
if not page and HTTP_HEADER.CONTENT_LENGTH in (headers or {}):
kb.nullConnection = NULLCONNECTION.HEAD
infoMsg = "NULL connection is supported with HEAD method (Content-Length)"
infoMsg = "NULL connection is supported with HEAD method ('Content-Length')"
logger.info(infoMsg)
else:
page, headers, _ = Request.getPage(auxHeaders={HTTP_HEADER.RANGE: "bytes=-1"})
@@ -1462,11 +1464,10 @@ def checkNullConnection():
if page and len(page) == 1 and HTTP_HEADER.CONTENT_RANGE in (headers or {}):
kb.nullConnection = NULLCONNECTION.RANGE
infoMsg = "NULL connection is supported with GET method (Range)"
infoMsg += "'%s'" % kb.nullConnection
infoMsg = "NULL connection is supported with GET method ('Range')"
logger.info(infoMsg)
else:
_, headers, _ = Request.getPage(skipRead = True)
_, headers, _ = Request.getPage(skipRead=True)
if HTTP_HEADER.CONTENT_LENGTH in (headers or {}):
kb.nullConnection = NULLCONNECTION.SKIP_READ
+11 -15
View File
@@ -242,11 +242,13 @@ def _saveToResultsFile():
for key, value in results.items():
place, parameter, notes = key
line = "%s,%s,%s,%s,%s%s" % (safeCSValue(kb.originalUrls.get(conf.url) or conf.url), place, parameter, "".join(techniques[_][0].upper() for _ in sorted(value)), notes, os.linesep)
conf.resultsFP.writelines(line)
conf.resultsFP.write(line)
if not results:
line = "%s,,,,%s" % (conf.url, os.linesep)
conf.resultsFP.writelines(line)
conf.resultsFP.write(line)
conf.resultsFP.flush()
def start():
"""
@@ -581,11 +583,11 @@ def start():
errMsg += "(e.g. GET parameter 'id' in 'www.site.com/index.php?id=1')"
raise SqlmapNoneDataException(errMsg)
else:
errMsg = "all tested parameters appear to be not injectable."
errMsg = "all tested parameters do not appear to be injectable."
if conf.level < 5 or conf.risk < 3:
errMsg += " Try to increase '--level'/'--risk' values "
errMsg += "to perform more tests."
errMsg += " Try to increase values for '--level'/'--risk' options "
errMsg += "if you wish to perform more tests."
if isinstance(conf.tech, list) and len(conf.tech) < 5:
errMsg += " Rerun without providing the option '--technique'."
@@ -608,15 +610,9 @@ def start():
if kb.heuristicTest == HEURISTIC_TEST.POSITIVE:
errMsg += " As heuristic test turned out positive you are "
errMsg += "strongly advised to continue on with the tests. "
errMsg += "Please, consider usage of tampering scripts as "
errMsg += "your target might filter the queries."
errMsg += "strongly advised to continue on with the tests."
if not conf.string and not conf.notString and not conf.regexp:
errMsg += " Also, you can try to rerun by providing "
errMsg += "either a valid value for option '--string' "
errMsg += "(or '--regexp')."
elif conf.string:
if conf.string:
errMsg += " Also, you can try to rerun by providing a "
errMsg += "valid value for option '--string' as perhaps the string you "
errMsg += "have chosen does not match "
@@ -629,8 +625,8 @@ def start():
if not conf.tamper:
errMsg += " If you suspect that there is some kind of protection mechanism "
errMsg += "involved (e.g. WAF) maybe you could retry "
errMsg += "with an option '--tamper' (e.g. '--tamper=space2comment')"
errMsg += "involved (e.g. WAF) maybe you could try to use "
errMsg += "option '--tamper' (e.g. '--tamper=space2comment')"
raise SqlmapNotVulnerableException(errMsg.rstrip('.'))
else:
+1 -11
View File
@@ -105,7 +105,7 @@ class Agent(object):
else:
origValue = filter(None, (re.search(_, origValue.split(BOUNDED_INJECTION_MARKER)[0]) for _ in (r"\w+\Z", r"[^\"'><]+\Z", r"[^ ]+\Z")))[0].group(0)
origValue = origValue[origValue.rfind('/') + 1:]
for char in ('?', '=', ':'):
for char in ('?', '=', ':', ','):
if char in origValue:
origValue = origValue[origValue.rfind(char) + 1:]
elif place == PLACE.CUSTOM_POST:
@@ -207,16 +207,6 @@ class Agent(object):
return retVal
def fullPayload(self, query):
if conf.direct:
return self.payloadDirect(query)
query = self.prefixQuery(query)
query = self.suffixQuery(query)
payload = self.payload(newValue=query)
return payload
def prefixQuery(self, expression, prefix=None, where=None, clause=None):
"""
This method defines how the input expression has to be escaped
+8 -6
View File
@@ -14,10 +14,12 @@ import itertools
import os
import sys
import tempfile
import zlib
from lib.core.enums import MKSTEMP_PREFIX
from lib.core.exception import SqlmapSystemException
from lib.core.settings import BIGARRAY_CHUNK_SIZE
from lib.core.settings import BIGARRAY_COMPRESS_LEVEL
DEFAULT_SIZE_OF = sys.getsizeof(object())
@@ -80,8 +82,8 @@ class BigArray(list):
if len(self.chunks[-1]) < 1:
self.chunks.pop()
try:
with open(self.chunks[-1], "rb") as fp:
self.chunks[-1] = pickle.load(fp)
with open(self.chunks[-1], "rb") as f:
self.chunks[-1] = pickle.loads(zlib.decompress(f.read()))
except IOError, ex:
errMsg = "exception occurred while retrieving data "
errMsg += "from a temporary file ('%s')" % ex.message
@@ -101,8 +103,8 @@ class BigArray(list):
handle, filename = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.BIG_ARRAY)
self.filenames.add(filename)
os.close(handle)
with open(filename, "w+b") as fp:
pickle.dump(chunk, fp, pickle.HIGHEST_PROTOCOL)
with open(filename, "w+b") as f:
f.write(zlib.compress(pickle.dumps(chunk, pickle.HIGHEST_PROTOCOL), BIGARRAY_COMPRESS_LEVEL))
return filename
except (OSError, IOError), ex:
errMsg = "exception occurred while storing data "
@@ -119,8 +121,8 @@ class BigArray(list):
if not (self.cache and self.cache.index == index):
try:
with open(self.chunks[index], "rb") as fp:
self.cache = Cache(index, pickle.load(fp), False)
with open(self.chunks[index], "rb") as f:
self.cache = Cache(index, pickle.loads(zlib.decompress(f.read())), False)
except IOError, ex:
errMsg = "exception occurred while retrieving data "
errMsg += "from a temporary file ('%s')" % ex.message
+52 -56
View File
@@ -28,6 +28,7 @@ import sys
import tempfile
import threading
import time
import types
import urllib
import urllib2
import urlparse
@@ -104,7 +105,7 @@ from lib.core.settings import DEFAULT_GET_POST_DELIMITER
from lib.core.settings import DEFAULT_MSSQL_SCHEMA
from lib.core.settings import DEV_EMAIL_ADDRESS
from lib.core.settings import DUMMY_USER_INJECTION
from lib.core.settings import DYNAMICITY_MARK_LENGTH
from lib.core.settings import DYNAMICITY_BOUNDARY_LENGTH
from lib.core.settings import ERROR_PARSING_REGEXES
from lib.core.settings import FILE_PATH_REGEXES
from lib.core.settings import FORCE_COOKIE_EXPIRATION_TIME
@@ -1017,16 +1018,16 @@ def readInput(message, default=None, checkBatch=True, boolean=False):
retVal = default
else:
logging._acquireLock()
if conf.get("beep"):
beep()
dataToStdout("\r%s" % message, forceOutput=True, bold=True)
kb.prependFlag = False
try:
retVal = raw_input() or default
logging._acquireLock()
if conf.get("beep"):
beep()
dataToStdout("\r%s" % message, forceOutput=True, bold=True)
kb.prependFlag = False
retVal = raw_input().strip() or default
retVal = getUnicode(retVal, encoding=sys.stdin.encoding) if retVal else retVal
except:
try:
@@ -1839,8 +1840,7 @@ def getPageWordSet(page):
# only if the page's charset has been successfully identified
if isinstance(page, unicode):
_ = getFilteredPageContent(page)
retVal = set(re.findall(r"\w+", _))
retVal = set(_.group(0) for _ in re.finditer(r"\w+", getFilteredPageContent(page)))
return retVal
@@ -2057,6 +2057,7 @@ def readXmlFile(xmlFile):
return retVal
@cachedmethod
def stdev(values):
"""
Computes standard deviation of a list of numbers.
@@ -2068,19 +2069,10 @@ def stdev(values):
if not values or len(values) < 2:
return None
key = (values[0], values[-1], len(values))
if kb.get("cache") and key in kb.cache.stdev:
retVal = kb.cache.stdev[key]
else:
avg = average(values)
_ = reduce(lambda x, y: x + pow((y or 0) - avg, 2), values, 0.0)
retVal = sqrt(_ / (len(values) - 1))
if kb.get("cache"):
kb.cache.stdev[key] = retVal
return retVal
return sqrt(_ / (len(values) - 1))
def average(values):
"""
@@ -2240,7 +2232,7 @@ def goGoodSamaritan(prevValue, originalCharset):
def getPartRun(alias=True):
"""
Goes through call stack and finds constructs matching conf.dbmsHandler.*.
Returns it or its alias used in txt/common-outputs.txt
Returns it or its alias used in 'txt/common-outputs.txt'
"""
retVal = None
@@ -2498,6 +2490,9 @@ def findLocalPort(ports):
def findMultipartPostBoundary(post):
"""
Finds value for a boundary parameter in given multipart POST body
>>> findMultipartPostBoundary("-----------------------------9051914041544843365972754266\\nContent-Disposition: form-data; name=text\\n\\ndefault")
'9051914041544843365972754266'
"""
retVal = None
@@ -2687,6 +2682,7 @@ def enumValueToNameLookup(type_, value_):
return retVal
@cachedmethod
def extractRegexResult(regex, content, flags=0):
"""
Returns 'result' group value from a possible match with regex on a given
@@ -2779,13 +2775,17 @@ def findDynamicContent(firstPage, secondPage):
"""
This function checks if the provided pages have dynamic content. If they
are dynamic, proper markings will be made
>>> findDynamicContent("Lorem ipsum dolor sit amet, congue tation referrentur ei sed. Ne nec legimus habemus recusabo, natum reque et per. Facer tritani reprehendunt eos id, modus constituam est te. Usu sumo indoctum ad, pri paulo molestiae complectitur no.", "Lorem ipsum dolor sit amet, congue tation referrentur ei sed. Ne nec legimus habemus recusabo, natum reque et per. <script src='ads.js'></script>Facer tritani reprehendunt eos id, modus constituam est te. Usu sumo indoctum ad, pri paulo molestiae complectitur no.")
>>> kb.dynamicMarkings
[('natum reque et per. ', 'Facer tritani repreh')]
"""
if not firstPage or not secondPage:
return
infoMsg = "searching for dynamic content"
logger.info(infoMsg)
singleTimeLogMessage(infoMsg)
blocks = SequenceMatcher(None, firstPage, secondPage).get_matching_blocks()
kb.dynamicMarkings = []
@@ -2794,7 +2794,7 @@ def findDynamicContent(firstPage, secondPage):
for block in blocks[:]:
(_, _, length) = block
if length <= DYNAMICITY_MARK_LENGTH:
if length <= 2 * DYNAMICITY_BOUNDARY_LENGTH:
blocks.remove(block)
# Making of dynamic markings based on prefix/suffix principle
@@ -2812,14 +2812,23 @@ def findDynamicContent(firstPage, secondPage):
if suffix is None and (blocks[i][0] + blocks[i][2] >= len(firstPage)):
continue
prefix = trimAlphaNum(prefix)
suffix = trimAlphaNum(suffix)
if prefix and suffix:
prefix = prefix[-DYNAMICITY_BOUNDARY_LENGTH:]
suffix = suffix[:DYNAMICITY_BOUNDARY_LENGTH]
kb.dynamicMarkings.append((prefix[-DYNAMICITY_MARK_LENGTH / 2:] if prefix else None, suffix[:DYNAMICITY_MARK_LENGTH / 2] if suffix else None))
infix = max(re.search(r"(?s)%s(.+)%s" % (re.escape(prefix), re.escape(suffix)), _) for _ in (firstPage, secondPage)).group(1)
if infix[0].isalnum():
prefix = trimAlphaNum(prefix)
if infix[-1].isalnum():
suffix = trimAlphaNum(suffix)
kb.dynamicMarkings.append((prefix if prefix else None, suffix if suffix else None))
if len(kb.dynamicMarkings) > 0:
infoMsg = "dynamic content marked for removal (%d region%s)" % (len(kb.dynamicMarkings), 's' if len(kb.dynamicMarkings) > 1 else '')
logger.info(infoMsg)
singleTimeLogMessage(infoMsg)
def removeDynamicContent(page):
"""
@@ -3374,6 +3383,9 @@ def createGithubIssue(errMsg, excMsg):
def maskSensitiveData(msg):
"""
Masks sensitive data in the supplied message
>>> maskSensitiveData('python sqlmap.py -u "http://www.test.com/vuln.php?id=1" --banner')
u'python sqlmap.py -u *********************************** --banner'
"""
retVal = getUnicode(msg)
@@ -3402,7 +3414,7 @@ def listToStrValue(value):
'1, 2, 3'
"""
if isinstance(value, (set, tuple)):
if isinstance(value, (set, tuple, types.GeneratorType)):
value = list(value)
if isinstance(value, list):
@@ -3412,22 +3424,6 @@ def listToStrValue(value):
return retVal
def getExceptionFrameLocals():
"""
Returns dictionary with local variable content from frame
where exception has been raised
"""
retVal = {}
if sys.exc_info():
trace = sys.exc_info()[2]
while trace.tb_next:
trace = trace.tb_next
retVal = trace.tb_frame.f_locals
return retVal
def intersect(valueA, valueB, lowerCase=False):
"""
Returns intersection of the array-ized values
@@ -3565,17 +3561,19 @@ def safeSQLIdentificatorNaming(name, isTable=False):
_ = isTable and Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE)
if _:
retVal = re.sub(r"(?i)\A%s\." % DEFAULT_MSSQL_SCHEMA, "", retVal)
retVal = re.sub(r"(?i)\A\[?%s\]?\." % DEFAULT_MSSQL_SCHEMA, "", retVal)
if retVal.upper() in kb.keywords or (retVal or " ")[0].isdigit() or not re.match(r"\A[A-Za-z0-9_@%s\$]+\Z" % ('.' if _ else ""), retVal): # MsSQL is the only DBMS where we automatically prepend schema to table name (dot is normal)
retVal = unsafeSQLIdentificatorNaming(retVal)
if retVal.upper() in kb.keywords or (retVal or " ")[0].isdigit() or not re.match(r"\A[A-Za-z0-9_@%s\$]+\Z" % ("." if _ else ""), retVal): # MsSQL is the only DBMS where we automatically prepend schema to table name (dot is normal)
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS):
retVal = "`%s`" % retVal.strip("`")
retVal = "`%s`" % retVal
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.SQLITE, DBMS.INFORMIX, DBMS.HSQLDB):
retVal = "\"%s\"" % retVal.strip("\"")
retVal = "\"%s\"" % retVal
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE,):
retVal = "\"%s\"" % retVal.strip("\"").upper()
retVal = "\"%s\"" % retVal.upper()
elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE) and ((retVal or " ")[0].isdigit() or not re.match(r"\A\w+\Z", retVal, re.U)):
retVal = "[%s]" % retVal.strip("[]")
retVal = "[%s]" % retVal
if _ and DEFAULT_MSSQL_SCHEMA not in retVal and '.' not in re.sub(r"\[[^]]+\]", "", retVal):
retVal = "%s.%s" % (DEFAULT_MSSQL_SCHEMA, retVal)
@@ -3600,9 +3598,7 @@ def unsafeSQLIdentificatorNaming(name):
retVal = name.replace("[", "").replace("]", "")
if Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE):
prefix = "%s." % DEFAULT_MSSQL_SCHEMA
if retVal.startswith(prefix):
retVal = retVal[len(prefix):]
retVal = re.sub(r"(?i)\A\[?%s\]?\." % DEFAULT_MSSQL_SCHEMA, "", retVal)
return retVal
@@ -4022,7 +4018,7 @@ def checkSameHost(*urls):
elif len(urls) == 1:
return True
else:
return all(urlparse.urlparse(url or "").netloc.split(':')[0] == urlparse.urlparse(urls[0] or "").netloc.split(':')[0] for url in urls[1:])
return all(re.sub(r"(?i)\Awww\.", "", urlparse.urlparse(url or "").netloc.split(':')[0]) == re.sub(r"(?i)\Awww\.", "", urlparse.urlparse(urls[0] or "").netloc.split(':')[0]) for url in urls[1:])
def getHostHeader(url):
"""
+2 -2
View File
@@ -14,11 +14,11 @@ def cachedmethod(f, cache={}):
def _(*args, **kwargs):
try:
key = (f, tuple(args), frozenset(kwargs.items()))
key = hash((f, tuple(args), frozenset(kwargs.items())))
if key not in cache:
cache[key] = f(*args, **kwargs)
except:
key = "".join(str(_) for _ in (f, args, kwargs))
key = hash("".join(str(_) for _ in (f, args, kwargs)))
if key not in cache:
cache[key] = f(*args, **kwargs)
+3 -3
View File
@@ -2097,11 +2097,11 @@ def _useWizardInterface():
choice = readInput(message, default='1')
if choice == '2':
map(lambda x: conf.__setitem__(x, True), WIZARD.INTERMEDIATE)
map(lambda _: conf.__setitem__(_, True), WIZARD.INTERMEDIATE)
elif choice == '3':
map(lambda x: conf.__setitem__(x, True), WIZARD.ALL)
map(lambda _: conf.__setitem__(_, True), WIZARD.ALL)
else:
map(lambda x: conf.__setitem__(x, True), WIZARD.BASIC)
map(lambda _: conf.__setitem__(_, True), WIZARD.BASIC)
logger.debug("muting sqlmap.. it will do the magic for you")
conf.verbose = 0
+10 -7
View File
@@ -19,7 +19,7 @@ from lib.core.enums import DBMS_DIRECTORY_NAME
from lib.core.enums import OS
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
VERSION = "1.1.11.0"
VERSION = "1.1.12.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)
@@ -76,7 +76,7 @@ CHAR_INFERENCE_MARK = "%c"
PRINTABLE_CHAR_REGEX = r"[^\x00-\x1f\x7f-\xff]"
# Regular expression used for extraction of table names (useful for (e.g.) MsAccess)
SELECT_FROM_TABLE_REGEX = r"\bSELECT .+? FROM (?P<result>([\w.]|`[^`<>]+`)+)"
SELECT_FROM_TABLE_REGEX = r"\bSELECT\b.+?\bFROM\s+(?P<result>([\w.]|`[^`<>]+`)+)"
# Regular expression used for recognition of textual content-type
TEXT_CONTENT_TYPE_REGEX = r"(?i)(text|form|message|xml|javascript|ecmascript|json)"
@@ -193,8 +193,8 @@ UNKNOWN_DBMS = "Unknown"
# String used for representation of unknown DBMS version
UNKNOWN_DBMS_VERSION = "Unknown"
# Dynamicity mark length used in dynamicity removal engine
DYNAMICITY_MARK_LENGTH = 32
# Dynamicity boundary length used in dynamicity removal engine
DYNAMICITY_BOUNDARY_LENGTH = 20
# Dummy user prefix used in dictionary attack
DUMMY_USER_PREFIX = "__dummy__"
@@ -301,7 +301,7 @@ BLANK = "<blank>"
CURRENT_DB = "CD"
# Regular expressions used for finding file paths in error messages
FILE_PATH_REGEXES = (r"<b>(?P<result>[^<>]+?)</b> on line \d+", r"(?P<result>[^<>'\"]+?)['\"]? on line \d+", r"(?:[>(\[\s])(?P<result>[A-Za-z]:[\\/][\w. \\/-]*)", r"(?:[>(\[\s])(?P<result>/\w[/\w.-]+)", r"href=['\"]file://(?P<result>/[^'\"]+)")
FILE_PATH_REGEXES = (r"<b>(?P<result>[^<>]+?)</b> on line \d+", r"(?P<result>[^<>'\"]+?)['\"]? on line \d+", r"(?:[>(\[\s])(?P<result>[A-Za-z]:[\\/][\w. \\/-]*)", r"(?:[>(\[\s])(?P<result>/\w[/\w.~-]+)", r"href=['\"]file://(?P<result>/[^'\"]+)")
# Regular expressions used for parsing error messages (--parse-errors)
ERROR_PARSING_REGEXES = (
@@ -479,7 +479,7 @@ PICKLE_REDUCE_WHITELIST = (types.BooleanType, types.DictType, types.FloatType, t
DUMMY_SQL_INJECTION_CHARS = ";()'"
# Simple check against dummy users
DUMMY_USER_INJECTION = r"(?i)[^\w](AND|OR)\s+[^\s]+[=><]|\bUNION\b.+\bSELECT\b|\bSELECT\b.+\bFROM\b|\b(CONCAT|information_schema|SLEEP|DELAY)\b"
DUMMY_USER_INJECTION = r"(?i)[^\w](AND|OR)\s+[^\s]+[=><]|\bUNION\b.+\bSELECT\b|\bSELECT\b.+\bFROM\b|\b(CONCAT|information_schema|SLEEP|DELAY|FLOOR\(RAND)\b"
# Extensions skipped by crawler
CRAWL_EXCLUDE_EXTENSIONS = ("3ds", "3g2", "3gp", "7z", "DS_Store", "a", "aac", "adp", "ai", "aif", "aiff", "apk", "ar", "asf", "au", "avi", "bak", "bin", "bk", "bmp", "btif", "bz2", "cab", "caf", "cgm", "cmx", "cpio", "cr2", "dat", "deb", "djvu", "dll", "dmg", "dmp", "dng", "doc", "docx", "dot", "dotx", "dra", "dsk", "dts", "dtshd", "dvb", "dwg", "dxf", "ear", "ecelp4800", "ecelp7470", "ecelp9600", "egg", "eol", "eot", "epub", "exe", "f4v", "fbs", "fh", "fla", "flac", "fli", "flv", "fpx", "fst", "fvt", "g3", "gif", "gz", "h261", "h263", "h264", "ico", "ief", "image", "img", "ipa", "iso", "jar", "jpeg", "jpg", "jpgv", "jpm", "jxr", "ktx", "lvp", "lz", "lzma", "lzo", "m3u", "m4a", "m4v", "mar", "mdi", "mid", "mj2", "mka", "mkv", "mmr", "mng", "mov", "movie", "mp3", "mp4", "mp4a", "mpeg", "mpg", "mpga", "mxu", "nef", "npx", "o", "oga", "ogg", "ogv", "otf", "pbm", "pcx", "pdf", "pea", "pgm", "pic", "png", "pnm", "ppm", "pps", "ppt", "pptx", "ps", "psd", "pya", "pyc", "pyo", "pyv", "qt", "rar", "ras", "raw", "rgb", "rip", "rlc", "rz", "s3m", "s7z", "scm", "scpt", "sgi", "shar", "sil", "smv", "so", "sub", "swf", "tar", "tbz2", "tga", "tgz", "tif", "tiff", "tlz", "ts", "ttf", "uvh", "uvi", "uvm", "uvp", "uvs", "uvu", "viv", "vob", "war", "wav", "wax", "wbmp", "wdp", "weba", "webm", "webp", "whl", "wm", "wma", "wmv", "wmx", "woff", "woff2", "wvx", "xbm", "xif", "xls", "xlsx", "xlt", "xm", "xpi", "xpm", "xwd", "xz", "z", "zip", "zipx")
@@ -520,6 +520,9 @@ ROTATING_CHARS = ('\\', '|', '|', '/', '-')
# Approximate chunk length (in bytes) used by BigArray objects (only last chunk and cached one are held in memory)
BIGARRAY_CHUNK_SIZE = 1024 * 1024
# Compress (zlib) level used for storing BigArray chunks to disk (0-9)
BIGARRAY_COMPRESS_LEVEL = 9
# Maximum number of socket pre-connects
SOCKET_PRE_CONNECT_QUEUE_SIZE = 3
@@ -639,7 +642,7 @@ VALID_TIME_CHARS_RUN_THRESHOLD = 100
CHECK_ZERO_COLUMNS_THRESHOLD = 10
# Boldify all logger messages containing these "patterns"
BOLD_PATTERNS = ("' injectable", "provided empty", "leftover chars", "might be injectable", "' is vulnerable", "is not injectable", "does not seem to be", "test failed", "test passed", "live test final result", "test shows that", "the back-end DBMS is", "created Github", "blocked by the target server", "protection is involved", "CAPTCHA", "specific response")
BOLD_PATTERNS = ("' injectable", "provided empty", "leftover chars", "might be injectable", "' is vulnerable", "is not injectable", "does not seem to be", "test failed", "test passed", "live test final result", "test shows that", "the back-end DBMS is", "created Github", "blocked by the target server", "protection is involved", "CAPTCHA", "specific response", "NULL connection is supported")
# Generic www root directory names
GENERIC_DOC_ROOT_DIRECTORY_NAMES = ("htdocs", "httpdocs", "public", "wwwroot", "www")
+1 -1
View File
@@ -545,7 +545,7 @@ def _setResultsFile():
if not conf.resultsFP:
conf.resultsFilename = os.path.join(paths.SQLMAP_OUTPUT_PATH, time.strftime(RESULTS_FILE_FORMAT).lower())
try:
conf.resultsFP = openFile(conf.resultsFilename, "w+", UNICODE_ENCODING, buffering=0)
conf.resultsFP = openFile(conf.resultsFilename, "a", UNICODE_ENCODING, buffering=0)
except (OSError, IOError), ex:
try:
warnMsg = "unable to create results file '%s' ('%s'). " % (conf.resultsFilename, getUnicode(ex))
-3
View File
@@ -64,9 +64,6 @@ class _ThreadData(threading.local):
ThreadData = _ThreadData()
def getCurrentThreadUID():
return hash(threading.currentThread())
def readInput(message, default=None, checkBatch=True, boolean=False):
# It will be overwritten by original from lib.core.common
pass
+14 -4
View File
@@ -254,12 +254,22 @@ def decodePage(page, contentEncoding, contentType):
if not page or (conf.nullConnection and len(page) < 2):
return getUnicode(page)
if isinstance(contentEncoding, basestring) and contentEncoding.lower() in ("gzip", "x-gzip", "deflate"):
if isinstance(contentEncoding, basestring) and contentEncoding:
contentEncoding = contentEncoding.lower()
else:
contentEncoding = ""
if isinstance(contentType, basestring) and contentType:
contentType = contentType.lower()
else:
contentType = ""
if contentEncoding in ("gzip", "x-gzip", "deflate"):
if not kb.pageCompress:
return None
try:
if contentEncoding.lower() == "deflate":
if contentEncoding == "deflate":
data = StringIO.StringIO(zlib.decompress(page, -15)) # Reference: http://stackoverflow.com/questions/1089662/python-inflate-and-deflate-implementations
else:
data = gzip.GzipFile("", "rb", 9, StringIO.StringIO(page))
@@ -284,7 +294,7 @@ def decodePage(page, contentEncoding, contentType):
httpCharset, metaCharset = None, None
# Reference: http://stackoverflow.com/questions/1020892/python-urllib2-read-to-unicode
if contentType and (contentType.find("charset=") != -1):
if contentType.find("charset=") != -1:
httpCharset = checkCharEncoding(contentType.split("charset=")[-1])
metaCharset = checkCharEncoding(extractRegexResult(META_CHARSET_REGEX, page))
@@ -300,7 +310,7 @@ def decodePage(page, contentEncoding, contentType):
kb.pageEncoding = conf.encoding
# can't do for all responses because we need to support binary files too
if contentType and not isinstance(page, unicode) and "text/" in contentType.lower():
if not isinstance(page, unicode) and "text/" in contentType:
if kb.heuristicMode:
kb.pageEncoding = kb.pageEncoding or checkCharEncoding(getHeuristicCharEncoding(page))
page = getUnicode(page, kb.pageEncoding)
+2 -2
View File
@@ -49,7 +49,7 @@ def _comparison(page, headers, code, getRatioValue, pageLength):
threadData = getCurrentThreadData()
if kb.testMode:
threadData.lastComparisonHeaders = listToStrValue([_ for _ in headers.headers if not _.startswith("%s:" % URI_HTTP_HEADER)]) if headers else ""
threadData.lastComparisonHeaders = listToStrValue(_ for _ in headers.headers if not _.startswith("%s:" % URI_HTTP_HEADER)) if headers else ""
threadData.lastComparisonPage = page
threadData.lastComparisonCode = code
@@ -57,7 +57,7 @@ def _comparison(page, headers, code, getRatioValue, pageLength):
return None
if any((conf.string, conf.notString, conf.regexp)):
rawResponse = "%s%s" % (listToStrValue([_ for _ in headers.headers if not _.startswith("%s:" % URI_HTTP_HEADER)]) if headers else "", page)
rawResponse = "%s%s" % (listToStrValue(_ for _ in headers.headers if not _.startswith("%s:" % URI_HTTP_HEADER)) if headers else "", page)
# String to match in page when the query is True and/or valid
if conf.string:
+8 -5
View File
@@ -796,6 +796,8 @@ class Connect(object):
raise404 = place != PLACE.URI if raise404 is None else raise404
method = method or conf.method
postUrlEncode = kb.postUrlEncode
value = agent.adjustLateValues(value)
payload = agent.extractPayload(value)
threadData = getCurrentThreadData()
@@ -804,8 +806,8 @@ class Connect(object):
headers = OrderedDict(conf.httpHeaders)
contentType = max(headers[_] if _.upper() == HTTP_HEADER.CONTENT_TYPE.upper() else None for _ in headers.keys())
if (kb.postHint or conf.skipUrlEncode) and kb.postUrlEncode:
kb.postUrlEncode = False
if (kb.postHint or conf.skipUrlEncode) and postUrlEncode:
postUrlEncode = False
conf.httpHeaders = [_ for _ in conf.httpHeaders if _[1] != contentType]
contentType = POST_HINT_CONTENT_TYPES.get(kb.postHint, PLAIN_TEXT_CONTENT_TYPE)
conf.httpHeaders.append((HTTP_HEADER.CONTENT_TYPE, contentType))
@@ -849,7 +851,7 @@ class Connect(object):
value = agent.replacePayload(value, payload)
else:
# GET, POST, URI and Cookie payload needs to be thoroughly URL encoded
if (place in (PLACE.GET, PLACE.URI, PLACE.COOKIE) or place == PLACE.CUSTOM_HEADER and value.split(',')[0] == HTTP_HEADER.COOKIE) and not conf.skipUrlEncode or place in (PLACE.POST, PLACE.CUSTOM_POST) and kb.postUrlEncode:
if (place in (PLACE.GET, PLACE.URI, PLACE.COOKIE) or place == PLACE.CUSTOM_HEADER and value.split(',')[0] == HTTP_HEADER.COOKIE) and not conf.skipUrlEncode or place in (PLACE.POST, PLACE.CUSTOM_POST) and postUrlEncode:
skip = False
if place == PLACE.COOKIE or place == PLACE.CUSTOM_HEADER and value.split(',')[0] == HTTP_HEADER.COOKIE:
@@ -862,6 +864,7 @@ class Connect(object):
if not skip:
payload = urlencode(payload, '%', False, place != PLACE.URI) # spaceplus is handled down below
value = agent.replacePayload(value, payload)
postUrlEncode = False
if conf.hpp:
if not any(conf.url.lower().endswith(_.lower()) for _ in (WEB_API.ASP, WEB_API.ASPX)):
@@ -1129,7 +1132,7 @@ class Connect(object):
found = True
uri = re.sub(regex.replace(r"\A", r"\?"), "\g<1>%s\g<3>" % value.replace('\\', r'\\'), uri)
regex = r"((\A|%s)%s=).+?(%s|\Z)" % (re.escape(conf.cookieDel or DEFAULT_COOKIE_DELIMITER), name, re.escape(conf.cookieDel or DEFAULT_COOKIE_DELIMITER))
regex = r"((\A|%s)%s=).+?(%s|\Z)" % (re.escape(conf.cookieDel or DEFAULT_COOKIE_DELIMITER), re.escape(name), re.escape(conf.cookieDel or DEFAULT_COOKIE_DELIMITER))
if re.search(regex, (cookie or "")):
found = True
cookie = re.sub(regex, "\g<1>%s\g<3>" % value.replace('\\', r'\\'), cookie)
@@ -1148,7 +1151,7 @@ class Connect(object):
if post is not None:
if place not in (PLACE.POST, PLACE.CUSTOM_POST) and hasattr(post, UNENCODED_ORIGINAL_VALUE):
post = getattr(post, UNENCODED_ORIGINAL_VALUE)
elif kb.postUrlEncode:
elif postUrlEncode:
post = urlencode(post, spaceplus=kb.postSpaceToPlus)
if timeBasedCompare and not conf.disableStats:
+3 -3
View File
@@ -266,9 +266,9 @@ class Web:
directories = _
backdoorName = "tmpb%s.%s" % (randomStr(lowercase=True), self.webApi)
backdoorContent = decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "backdoor.%s_" % self.webApi))
backdoorContent = decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "backdoors", "backdoor.%s_" % self.webApi))
stagerContent = decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "stager.%s_" % self.webApi))
stagerContent = decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "stagers", "stager.%s_" % self.webApi))
for directory in directories:
if not directory:
@@ -323,7 +323,7 @@ class Web:
os.close(handle)
with open(filename, "w+b") as f:
_ = decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "stager.%s_" % self.webApi))
_ = decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "stagers", "stager.%s_" % self.webApi))
_ = _.replace("WRITABLE_DIR", utf8encode(directory.replace('/', '\\\\') if Backend.isOs(OS.WINDOWS) else directory))
f.write(_)
+14 -17
View File
@@ -110,7 +110,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
if partialValue:
firstChar = len(partialValue)
elif "LENGTH(" in expression.upper() or "LEN(" in expression.upper():
elif re.search(r"(?i)\b(LENGTH|LEN)\(", expression):
firstChar = 0
elif (kb.fileReadMode or dump) and conf.firstChar is not None and (isinstance(conf.firstChar, int) or (isinstance(conf.firstChar, basestring) and conf.firstChar.isdigit())):
firstChar = int(conf.firstChar) - 1
@@ -121,7 +121,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
else:
firstChar = 0
if "LENGTH(" in expression.upper() or "LEN(" in expression.upper():
if re.search(r"(?i)\b(LENGTH|LEN)\(", expression):
lastChar = 0
elif dump and conf.lastChar is not None and (isinstance(conf.lastChar, int) or (isinstance(conf.lastChar, basestring) and conf.lastChar.isdigit())):
lastChar = int(conf.lastChar)
@@ -343,7 +343,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
if result:
minValue = posValue
if type(charTbl) != xrange:
if not isinstance(charTbl, xrange):
charTbl = charTbl[position:]
else:
# xrange() - extended virtual charset used for memory/space optimization
@@ -351,7 +351,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
else:
maxValue = posValue
if type(charTbl) != xrange:
if not isinstance(charTbl, xrange):
charTbl = charTbl[:position]
else:
charTbl = xrange(charTbl[0], charTbl[position])
@@ -390,7 +390,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
if timeBasedCompare:
if kb.adjustTimeDelay is not ADJUST_TIME_DELAY.DISABLE:
conf.timeSec += 1
warnMsg = "increasing time delay to %d second%s " % (conf.timeSec, 's' if conf.timeSec > 1 else '')
warnMsg = "increasing time delay to %d second%s" % (conf.timeSec, 's' if conf.timeSec > 1 else '')
logger.warn(warnMsg)
if kb.adjustTimeDelay is ADJUST_TIME_DELAY.YES:
@@ -461,18 +461,15 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
threadData = getCurrentThreadData()
while kb.threadContinue:
kb.locks.index.acquire()
with kb.locks.index:
if threadData.shared.index[0] - firstChar >= length:
return
if threadData.shared.index[0] - firstChar >= length:
kb.locks.index.release()
return
threadData.shared.index[0] += 1
currentCharIndex = threadData.shared.index[0]
kb.locks.index.release()
threadData.shared.index[0] += 1
currentCharIndex = threadData.shared.index[0]
if kb.threadContinue:
charStart = time.time()
start = time.time()
val = getChar(currentCharIndex, asciiTbl, not(charsetType is None and conf.charset))
if val is None:
val = INFERENCE_UNKNOWN_CHAR
@@ -485,7 +482,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
if kb.threadContinue:
if showEta:
progress.progress(time.time() - charStart, threadData.shared.index[0])
progress.progress(calculateDeltaSeconds(start), threadData.shared.index[0])
elif conf.verbose >= 1:
startCharIndex = 0
endCharIndex = 0
@@ -553,7 +550,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
while True:
index += 1
charStart = time.time()
start = time.time()
# Common prediction feature (a.k.a. "good samaritan")
# NOTE: to be used only when multi-threading is not set for
@@ -578,7 +575,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
# Did we have luck?
if result:
if showEta:
progress.progress(time.time() - charStart, len(commonValue))
progress.progress(calculateDeltaSeconds(start), len(commonValue))
elif conf.verbose in (1, 2) or conf.api:
dataToStdout(filterControlChars(commonValue[index - 1:]))
+2 -2
View File
@@ -133,7 +133,7 @@ def _oneShotErrorUse(expression, field=None, chunkTest=False):
output = reduce(lambda x, y: x if x is not None else y, (\
extractRegexResult(check, page), \
extractRegexResult(check, threadData.lastHTTPError[2] if wasLastResponseHTTPError() else None), \
extractRegexResult(check, listToStrValue([headers[header] for header in headers if header.lower() != HTTP_HEADER.URI.lower()] if headers else None)), \
extractRegexResult(check, listToStrValue((headers[header] for header in headers if header.lower() != HTTP_HEADER.URI.lower()) if headers else None)), \
extractRegexResult(check, threadData.lastRedirectMsg[1] if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == threadData.lastRequestUID else None)), \
None)
@@ -142,7 +142,7 @@ def _oneShotErrorUse(expression, field=None, chunkTest=False):
else:
trimmed = extractRegexResult(trimcheck, page) \
or extractRegexResult(trimcheck, threadData.lastHTTPError[2] if wasLastResponseHTTPError() else None) \
or extractRegexResult(trimcheck, listToStrValue([headers[header] for header in headers if header.lower() != HTTP_HEADER.URI.lower()] if headers else None)) \
or extractRegexResult(trimcheck, listToStrValue((headers[header] for header in headers if header.lower() != HTTP_HEADER.URI.lower()) if headers else None)) \
or extractRegexResult(trimcheck, threadData.lastRedirectMsg[1] if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == threadData.lastRequestUID else None)
if trimmed:
+1 -1
View File
@@ -278,7 +278,7 @@ def columnExists(columnFile, regex=None):
kb.data.cachedColumns[conf.db] = {conf.tbl: columns}
for _ in map(lambda x: (conf.db, conf.tbl, x[0], x[1]), columns.items()):
for _ in ((conf.db, conf.tbl, item[0], item[1]) for item in columns.items()):
if _ not in kb.brute.columns:
kb.brute.columns.append(_)
+2 -2
View File
@@ -64,14 +64,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 " % getSafeExString(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 " % getSafeExString(ex)
errMsg = "invalid URL detected ('%s'). skipping " % getSafeExString(ex)
errMsg += "URL '%s'" % current
logger.critical(errMsg)
+9 -3
View File
@@ -153,7 +153,7 @@ def mssql_passwd(password, salt, uppercase=False):
"""
binsalt = hexdecode(salt)
unistr = "".join(map(lambda c: ("%s\0" if ord(c) < 256 else "%s") % utf8encode(c), password))
unistr = "".join(("%s\0" if ord(_) < 256 else "%s") % utf8encode(_) for _ in password)
retVal = "0100%s%s" % (salt, sha1(unistr + binsalt).hexdigest())
@@ -171,7 +171,7 @@ def mssql_old_passwd(password, salt, uppercase=True): # prior to version '2005'
"""
binsalt = hexdecode(salt)
unistr = "".join(map(lambda c: ("%s\0" if ord(c) < 256 else "%s") % utf8encode(c), password))
unistr = "".join(("%s\0" if ord(_) < 256 else "%s") % utf8encode(_) for _ in password)
retVal = "0100%s%s%s" % (salt, sha1(unistr + binsalt).hexdigest(), sha1(unistr.upper() + binsalt).hexdigest())
@@ -187,7 +187,7 @@ def mssql_new_passwd(password, salt, uppercase=False):
"""
binsalt = hexdecode(salt)
unistr = "".join(map(lambda c: ("%s\0" if ord(c) < 256 else "%s") % utf8encode(c), password))
unistr = "".join(("%s\0" if ord(_) < 256 else "%s") % utf8encode(_) for _ in password)
retVal = "0200%s%s" % (salt, sha512(unistr + binsalt).hexdigest())
@@ -366,6 +366,12 @@ def unix_md5_passwd(password, salt, magic="$1$", **kwargs):
if isinstance(password, unicode):
password = password.encode(UNICODE_ENCODING)
if isinstance(magic, unicode):
magic = magic.encode(UNICODE_ENCODING)
if isinstance(salt, unicode):
salt = salt.encode(UNICODE_ENCODING)
salt = salt[:8]
ctx = password + magic + salt
final = md5(password + salt + password).digest()
+1 -1
View File
@@ -122,7 +122,7 @@ def _search(dork):
elif choice == '2':
url = "https://www.bing.com/search?q=%s&first=%d" % (urlencode(dork, convall=True), (gpage - 1) * 10 + 1)
regex = BING_REGEX
elif choice == '1':
else:
url = "https://duckduckgo.com/d.js?"
url += "q=%s&p=%d&s=100" % (urlencode(dork, convall=True), gpage)
regex = DUCKDUCKGO_REGEX
+1 -1
View File
@@ -279,7 +279,7 @@ class Filesystem:
self.checkDbmsOs()
if localFile.endswith('_'):
localFile = decloakToTemp(localFile)
localFile = getUnicode(decloakToTemp(localFile))
if conf.direct or isStackingAvailable():
if isStackingAvailable():
+1 -5
View File
@@ -1,8 +1,4 @@
Due to the anti-virus positive detection of shell scripts stored inside
this folder, we needed to somehow circumvent this. As from the plain
sqlmap users perspective nothing has to be done prior to their usage by
sqlmap, but if you want to have access to their original source code use
the decrypt functionality of the ../extra/cloak/cloak.py utility.
Due to the anti-virus positive detection of shell scripts stored inside this folder, we needed to somehow circumvent this. As from the plain sqlmap users perspective nothing has to be done prior to their usage by sqlmap, but if you want to have access to their original source code use the decrypt functionality of the ../extra/cloak/cloak.py utility.
To prepare the original scripts to the cloaked form use this command:
find backdoor.* stager.* -type f -exec python ../extra/cloak/cloak.py -i '{}' \;
+11 -4
View File
@@ -36,7 +36,6 @@ warnings.filterwarnings(action="ignore", category=DeprecationWarning)
from lib.core.data import logger
try:
from lib.controller.controller import start
from lib.core.common import banner
from lib.core.common import checkIntegrity
from lib.core.common import createGithubIssue
@@ -58,15 +57,12 @@ try:
from lib.core.exception import SqlmapUserQuitException
from lib.core.option import initOptions
from lib.core.option import init
from lib.core.profiling import profile
from lib.core.settings import GIT_PAGE
from lib.core.settings import IS_WIN
from lib.core.settings import LEGAL_DISCLAIMER
from lib.core.settings import THREAD_FINALIZATION_TIMEOUT
from lib.core.settings import UNICODE_ENCODING
from lib.core.settings import VERSION
from lib.core.testing import smokeTest
from lib.core.testing import liveTest
from lib.parse.cmdline import cmdLineParser
except KeyboardInterrupt:
errMsg = "user aborted"
@@ -144,13 +140,18 @@ def main():
init()
# Postponed imports (faster start)
if conf.profile:
from lib.core.profiling import profile
profile()
elif conf.smokeTest:
from lib.core.testing import smokeTest
smokeTest()
elif conf.liveTest:
from lib.core.testing import liveTest
liveTest()
else:
from lib.controller.controller import start
try:
start()
except thread.error as ex:
@@ -262,6 +263,12 @@ def main():
logger.error(errMsg)
raise SystemExit
elif all(_ in excMsg for _ in ("twophase", "sqlalchemy")):
errMsg = "please update the 'sqlalchemy' package"
errMsg += "(Reference: https://github.com/apache/incubator-superset/issues/3447)"
logger.error(errMsg)
raise SystemExit
elif "can't start new thread" in excMsg:
errMsg = "there has been a problem while creating new thread instance. "
errMsg += "Please make sure that you are not running too many processes"
+65
View File
@@ -0,0 +1,65 @@
#!/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.HIGHEST
def dependencies():
pass
def tamper(payload, **kwargs):
"""
Replaces instances like 'IFNULL(A, B)' with 'CASE WHEN ISNULL(A) THEN (B) ELSE (A) END'
Requirement:
* MySQL
* SQLite (possibly)
* SAP MaxDB (possibly)
Tested against:
* MySQL 5.0 and 5.5
Notes:
* Useful to bypass very weak and bespoke web application firewalls
that filter the IFNULL() functions
>>> tamper('IFNULL(1, 2)')
'CASE WHEN ISNULL(1) THEN (2) ELSE (1) END'
"""
if payload and payload.find("IFNULL") > -1:
while payload.find("IFNULL(") > -1:
index = payload.find("IFNULL(")
depth = 1
comma, end = None, None
for i in xrange(index + len("IFNULL("), len(payload)):
if depth == 1 and payload[i] == ',':
comma = i
elif depth == 1 and payload[i] == ')':
end = i
break
elif payload[i] == '(':
depth += 1
elif payload[i] == ')':
depth -= 1
if comma and end:
_ = payload[index + len("IFNULL("):comma]
__ = payload[comma + 1:end].lstrip()
newVal = "CASE WHEN ISNULL(%s) THEN (%s) ELSE (%s) END" % (_, __, _)
payload = payload[:index] + newVal + payload[end + 1:]
else:
break
return payload
+37 -34
View File
@@ -21,17 +21,17 @@ f96467fc5cd1d87f52dd7966c8ae6e79 extra/shutils/regressiontest.py
5fb9aaf874daa47ea2b672a22740e56b extra/sqlharvest/__init__.py
1fc7772edce5a01c31f3932b2fc4c1c6 extra/sqlharvest/sqlharvest.py
21bf2b3a7a22b8cd5d96a6457a1b4997 lib/controller/action.py
9eadf57517a6064d462b1f5ba9a3280d lib/controller/checks.py
91c9ef44927b270ea53b6739ff5b2e76 lib/controller/controller.py
beb3207c65d01c1e5d959cd6393cd420 lib/controller/checks.py
2db2666dba713c710d248a62b2c1c1fe lib/controller/controller.py
d2cdb9e832e18a81e936ca3348144b16 lib/controller/handler.py
5fb9aaf874daa47ea2b672a22740e56b lib/controller/__init__.py
3672210ed0043fe094df8615e4c5c0c0 lib/core/agent.py
d55b4b58019d6dbfddd40ec919f9f172 lib/core/bigarray.py
8731cbd68d44f4edbd3b183988f32a40 lib/core/common.py
fd69e56ce20a5a49ce10a7a745022378 lib/core/agent.py
8d9d771f7e67582c56a96a8d0ccbe4fc lib/core/bigarray.py
27d55009305e6409dc17f9c58cb87065 lib/core/common.py
54326d3a690f8b26fe5a5da1a589b369 lib/core/convert.py
90b1b08368ac8a859300e6fa6a8c796e lib/core/data.py
1c14bdbf47b8dba31f73da9ad731a54a lib/core/datatype.py
70d60d7a9518083cfa8900b97c065f7a lib/core/decorators.py
2c16cdbbccbfcfc0ddac2cff876ce9f3 lib/core/decorators.py
d3ed5f9baa074df33390d33164d9d8b5 lib/core/defaults.py
96fe4769b6e3e68635fa82cd59cc49fc lib/core/dicts.py
956be8ca65c7f04f08c6f2dce710b3b2 lib/core/dump.py
@@ -40,18 +40,18 @@ d3ed5f9baa074df33390d33164d9d8b5 lib/core/defaults.py
5fb9aaf874daa47ea2b672a22740e56b lib/core/__init__.py
f872699e948d0692ce11b54781da814c lib/core/log.py
5adb07b2771f26822e94c75c2cb9db0b lib/core/optiondict.py
ec6a778b0e74749b916caead78ba88b7 lib/core/option.py
e1c000db9be27f973569b1a430629037 lib/core/option.py
8764d2d8610fff5f4aef897b2b1f1006 lib/core/profiling.py
2de91262fcc6bd51c987fd2f8a59ff31 lib/core/readlineng.py
760d9df2a27ded29109b390ab202e72d lib/core/replication.py
a2466b62e67f8b31736bac4dac590e51 lib/core/revision.py
02d4762140a72fd44668d3dab5eabda9 lib/core/session.py
b29170b2a9f29588c3930952a99b2e76 lib/core/settings.py
3f8a858155092e17d146cd6021057338 lib/core/settings.py
35bffbad762eb9e03db9e93b1c991103 lib/core/shell.py
a59ec28371ae067a6fdd8f810edbee3d lib/core/subprocessng.py
7c9f2af3c0a8dd89223cfe07b0a0b826 lib/core/target.py
d5a04d672a18f78deb2839c3745ff83c lib/core/target.py
df8f6475a53d83400c1a3967c0a21bd7 lib/core/testing.py
20ae9917fa959ea423d8c28c297b37fe lib/core/threads.py
632538fe50f6b3179e1a5a85e8b79741 lib/core/threads.py
a119989ca03f8c8fbdf7d3035084eb31 lib/core/unescaper.py
e7fb8c09fe7520c32895b859c4edf77a lib/core/update.py
c976dd450b663cb4455cd9efbbcf625b lib/core/wordlist.py
@@ -66,9 +66,9 @@ e07930095e56de11c297d7ac1a1706f2 lib/parse/html.py
d8d9bcf9e7107a5e2cf2dd10f115ac28 lib/parse/payloads.py
2b87577dc6d3609e96fc1e049def5b4f lib/parse/sitemap.py
d2f13a0e2fef5273d419d06e516122e1 lib/request/basicauthhandler.py
669e8cf941bba4a2e987045b3002b8e3 lib/request/basic.py
67bcf2499db566ebf46f9a6122399fe6 lib/request/comparison.py
a253670611499bc159879122e05622de lib/request/connect.py
9ef264b5c0f9e7989b8c2ab91d40400d lib/request/basic.py
28348595147a731677c8bef470c6f57a lib/request/comparison.py
5a2d97c7b672228e695855ff43fb7960 lib/request/connect.py
ad6f76839408d827abfcdc57813f8518 lib/request/direct.py
4853bd0d523646315607a6a9a4c0b745 lib/request/dns.py
effa0c3e4efceaf4932855e8e6677bf7 lib/request/httpshandler.py
@@ -85,33 +85,33 @@ a53a068f7b5651fca1ae8da932ba4d96 lib/takeover/icmpsh.py
ac3f47b2f8d2cd530512405b4a23a9db lib/takeover/metasploit.py
3309f439e0cb68a707dc3a3c807645b0 lib/takeover/registry.py
21b6eff33f5d28c5e167a948976817cb lib/takeover/udf.py
916917ef27d12544fdc68265ba28f70e lib/takeover/web.py
e49d1213f9ae0c0f922c5aef4febe205 lib/takeover/web.py
d3080bf68b4b85ed2c98af5de74e8b73 lib/takeover/xp_cmdshell.py
4ec8685f767dc2419e46380320273ff9 lib/techniques/blind/inference.py
ca47f20b11f58ce60a0ddfcfca242d3f lib/techniques/blind/inference.py
5fb9aaf874daa47ea2b672a22740e56b lib/techniques/blind/__init__.py
5fb9aaf874daa47ea2b672a22740e56b lib/techniques/dns/__init__.py
95331b2826f28db9ff962670391aa7d6 lib/techniques/dns/test.py
82cc907fb335250703072337d8f8cceb lib/techniques/dns/use.py
5fb9aaf874daa47ea2b672a22740e56b lib/techniques/error/__init__.py
e9e3e8ad72a9cd981e76d6debec05185 lib/techniques/error/use.py
5953b814b91e6a03d26f319203b48d01 lib/techniques/error/use.py
5fb9aaf874daa47ea2b672a22740e56b lib/techniques/__init__.py
5fb9aaf874daa47ea2b672a22740e56b lib/techniques/union/__init__.py
fcc3a6ac3b5f7aad86686e5f9adc7a43 lib/techniques/union/test.py
505682f95cb23573dd60bf6d0063a632 lib/techniques/union/use.py
452cb280aa51a4ddf38d94534a6e8d5f lib/utils/api.py
d9d62fa5d7367e7fb23180240c8d03f4 lib/utils/brute.py
95e4eab120640fd9330d569a29a25be4 lib/utils/crawler.py
48c3f8216b64825c50f5304cb4dadd95 lib/utils/brute.py
7e0078da1dff59530d64f9b1e2f68607 lib/utils/crawler.py
a2d2087353fb64a8441c3247ae0ad719 lib/utils/deps.py
b806de9710a02436e576ac9065816021 lib/utils/getch.py
fe3a38f820ae05a95f92ab53e22b46d0 lib/utils/har.py
1bdd3e6483d3d7c4fd6ec59e9526b542 lib/utils/hashdb.py
e0e8a641c28552ca6794a71b5f12a2fb lib/utils/hash.py
193c294d960c310808495a63167eab00 lib/utils/hash.py
f20ae1aa6a8d1d5373ace1f7ed3476a7 lib/utils/htmlentities.py
5fb9aaf874daa47ea2b672a22740e56b lib/utils/__init__.py
06cd61b634ca6142281da699a504cc85 lib/utils/pivotdumptable.py
56c922696bd3d05d7be96e73b0650c4e lib/utils/progress.py
a861c303293e2e6665b02a57f67fc050 lib/utils/purge.py
f6652791bf98a42e3e1532180a0710cf lib/utils/search.py
760290393e35e5f53f15ba46e09d59dd lib/utils/search.py
b6898e77038842c853932a6662c011be lib/utils/sqlalchemy.py
36b95bc7fa2cf4f005a86e516a8cba68 lib/utils/timeout.py
a3b51d28b0824d4d2333a3dd792497ac lib/utils/versioncheck.py
@@ -206,7 +206,7 @@ c811c9267896033a1d206bdec774782b plugins/generic/custom.py
43f19ede05350b42704b55d237f3d715 plugins/generic/databases.py
d769db0ec3586855a8197229c2a27ffa plugins/generic/entries.py
16882f2840da3161ed4dbf4a7ff8fc8b plugins/generic/enumeration.py
c1a3f3c21d17d74298be8c3bf4fa4e66 plugins/generic/filesystem.py
ed82a43b822e265919b6164c628e433c plugins/generic/filesystem.py
c4f4c6754e09a2418a08d1002184f260 plugins/generic/fingerprint.py
5fb9aaf874daa47ea2b672a22740e56b plugins/generic/__init__.py
3e9a5909f250dfefd1e51abbf69d3973 plugins/generic/misc.py
@@ -215,16 +215,16 @@ f65197bb16a0c7b243a322cf89715891 plugins/generic/syntax.py
659b5821b3bfc4c8ef94759bbf968b25 plugins/generic/takeover.py
65524d3fc3373c4ec241a6358f634bbd plugins/generic/users.py
5fb9aaf874daa47ea2b672a22740e56b plugins/__init__.py
b04db3e861edde1f9dd0a3850d5b96c8 shell/backdoor.asp_
158bfa168128393dde8d6ed11fe9a1b8 shell/backdoor.aspx_
1add5a9a67539e7fd1999c8c20a69d15 shell/backdoor.jsp_
09fc3ed6543f4d1885e338b271e5e97a shell/backdoor.php_
0e7aba05423c272f051f31165b0e416d shell/stager.asp_
c3cc8b7727161e64ab59f312c33b541a shell/stager.aspx_
1f7f125f30e0e800beb21e2ebbab18e1 shell/stager.jsp_
01e3505e796edf19aad6a996101c81c9 shell/stager.php_
b04db3e861edde1f9dd0a3850d5b96c8 shell/backdoors/backdoor.asp_
158bfa168128393dde8d6ed11fe9a1b8 shell/backdoors/backdoor.aspx_
1add5a9a67539e7fd1999c8c20a69d15 shell/backdoors/backdoor.jsp_
09fc3ed6543f4d1885e338b271e5e97a shell/backdoors/backdoor.php_
0e7aba05423c272f051f31165b0e416d shell/stagers/stager.asp_
c3cc8b7727161e64ab59f312c33b541a shell/stagers/stager.aspx_
1f7f125f30e0e800beb21e2ebbab18e1 shell/stagers/stager.jsp_
01e3505e796edf19aad6a996101c81c9 shell/stagers/stager.php_
c737efc0afe782c5dcfec9d27e827515 sqlmapapi.py
e1741dbdee31788ee93dea911faa4ebe sqlmap.py
5055a9d152e379fd7d55cbbf06025834 sqlmap.py
ba9bb7b0fbfbd408c24bc99b3c8f0fd9 tamper/apostrophemask.py
aa046ea026a3c72b714e726a2e775cd4 tamper/apostrophenullencode.py
0418d808878bf7cac4a28350116e64d0 tamper/appendnullbyte.py
@@ -244,6 +244,7 @@ e9d64dc52b02ae141bca2b2c69540ccc tamper/concat2concatws.py
573e3304d0dd5977e5a8a93d24fa3f99 tamper/greatest.py
fe4ce7c1d5219fce225048ef8b00a272 tamper/halfversionedmorekeywords.py
458fae54979d388da14c3ca23d532830 tamper/htmlencode.py
3d78732865cd12e5f490470babd289f6 tamper/ifnull2casewhenisnull.py
ccc5edfba7532a27809a80a7606b226f tamper/ifnull2ifisnull.py
6a7e92664dff80fe48b1a6f99fcc71b7 tamper/informationschemacomment.py
5fb9aaf874daa47ea2b672a22740e56b tamper/__init__.py
@@ -391,7 +392,7 @@ ca3ab78d6ed53b7f2c07ed2530d47efd udf/postgresql/windows/32/8.4/lib_postgresqlud
58faaa04de90a44c306e862bbbe0ed83 waf/aws.py
2347b494b91dc50d93d1437e1302f9f1 waf/baidu.py
72fd38a1fa212fb154f74d0c978d489a waf/barracuda.py
02aa8b095f7fabd439a3afda0430ca84 waf/bigip.py
5c55654a7611e767dd2be797716e2d75 waf/bigip.py
5430f2a681071e894fa3c152eebf68e4 waf/binarysec.py
2ce52bac62825acd4456817af6f10b14 waf/blockdos.py
fe60962fc1d80e557b1d602fbe4934dc waf/ciscoacexml.py
@@ -428,11 +429,11 @@ e353eb40d21be9e5ac6ea98f5c71a2f3 waf/radware.py
de671bbe9acee86d5e3a66fd4126b4e3 waf/safedog.py
b03fdbf8f427ab614303a03416970927 waf/secureiis.py
877ea097e56abf01868945a00c2afdea waf/senginx.py
2c24d9e5c80ad51cb74f1c4b124d8974 waf/sitelock.py
2dee94358969c6b8dab8acb2e9560417 waf/sonicwall.py
90f3c0c895d5d564b6614e25549b6355 waf/sitelock.py
664f73359b87bfb684fb49df1e0b1fa4 waf/sonicwall.py
b384581ce833d147690c7c77c9509bdc waf/sophos.py
e9127a67621440fba41e1cd176890851 waf/stingray.py
6c87858fc902d272d5effc9ebb944deb waf/sucuri.py
b9ede1695617c883e4230e6018753ba4 waf/sucuri.py
313245e511fbe1ee6fb5fd344be88240 waf/tencent.py
64c0e9c4c32adfd3c230705a7f17a63a waf/teros.py
9df516cb9793ba7f906dc0597fdd73a0 waf/trafficshield.py
@@ -440,11 +441,13 @@ a4fca90afde376962f09ac10c965b6e7 waf/urlscan.py
2952dadc49a810bde918ae70ca9bb042 waf/uspses.py
e0e9afe5330645bcf63103cf7df6ef56 waf/varnish.py
c6b044f4f29680e0767b36c893b9346b waf/wallarm.py
fe451f569a88c198adda6d22b39c9a4b waf/watchguard.py
dc78bd60735f4c2b2cfc05dc8b148a56 waf/webappsecure.py
755709c2c28da8dc612ce0d277d8ba02 waf/webknight.py
07ca74cd2e76310caacb709c5304999b waf/wordfence.py
d347378166b781e39569eaaa036268d5 waf/yundun.py
c32f8c216fab0a0672f734a48da8d6ff waf/yunsuo.py
fd87445df19ad9e58b5ffff464bd7413 waf/zenedge.py
e87d59af23b7b18cd56c9883e5f02d5c xml/banner/generic.xml
d8925c034263bf1b83e7d8e1c78eec57 xml/banner/mssql.xml
b8b56f4aa34bf65365808919b97119a7 xml/banner/mysql.xml
+2 -1
View File
@@ -16,13 +16,14 @@ def detect(get_page):
retval = False
for vector in WAF_ATTACK_VECTORS:
_, headers, _ = get_page(get=vector)
_, headers, code = get_page(get=vector)
retval = headers.get("X-Cnection", "").lower() == "close"
retval |= headers.get("X-WA-Info") is not None
retval |= re.search(r"\ATS\w{4,}=", headers.get(HTTP_HEADER.SET_COOKIE, ""), re.I) is not None
retval |= re.search(r"BigIP|BIGipServer", headers.get(HTTP_HEADER.SET_COOKIE, ""), re.I) is not None
retval |= re.search(r"BigIP|BIGipServer", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
retval |= re.search(r"\AF5\Z", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
retval &= code >= 400
if retval:
break
+1 -1
View File
@@ -14,7 +14,7 @@ def detect(get_page):
for vector in WAF_ATTACK_VECTORS:
page, _, _ = get_page(get=vector)
retval = "SiteLock Incident ID" in (page or "")
retval |= any(_ in (page or "") for _ in ("SiteLock Incident ID", "sitelock-site-verification", "sitelock_shield_logo"))
if retval:
break
+1
View File
@@ -18,6 +18,7 @@ def detect(get_page):
for vector in WAF_ATTACK_VECTORS:
page, headers, _ = get_page(get=vector)
retval = "This request is blocked by the SonicWALL" in (page or "")
retval |= all(_ in page or "" for _ in ("#shd", "#nsa_banner"))
retval |= re.search(r"Web Site Blocked.+\bnsa_banner", page or "", re.I) is not None
retval |= re.search(r"SonicWALL", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
if retval:
+1
View File
@@ -18,6 +18,7 @@ def detect(get_page):
for vector in WAF_ATTACK_VECTORS:
page, headers, code = get_page(get=vector)
retval = code == 403 and re.search(r"Sucuri/Cloudproxy", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
retval |= "Access Denied - Sucuri Website Firewall" in (page or "")
retval |= "Sucuri WebSite Firewall - CloudProxy - Access Denied" in (page or "")
retval |= re.search(r"Questions\?.+cloudproxy@sucuri\.net", (page or "")) is not None
if retval:
+24
View File
@@ -0,0 +1,24 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import re
from lib.core.enums import HTTP_HEADER
from lib.core.settings import WAF_ATTACK_VECTORS
__product__ = "WatchGuard (WatchGuard Technologies)"
def detect(get_page):
retval = False
for vector in WAF_ATTACK_VECTORS:
_, headers, code = get_page(get=vector)
retval = code >= 400 and re.search(r"\AWatchGuard", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
if retval:
break
return retval
+24
View File
@@ -0,0 +1,24 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import re
from lib.core.enums import HTTP_HEADER
from lib.core.settings import WAF_ATTACK_VECTORS
__product__ = "Zenedge Web Application Firewall (Zenedge)"
def detect(get_page):
retval = False
for vector in WAF_ATTACK_VECTORS:
_, headers, code = get_page(get=vector)
retval = code >= 400 and re.search(r"\AZENEDGE", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
if retval:
break
return retval