Merge branch 'master' of github.com:sqlmapproject/sqlmap

This commit is contained in:
Bernardo Damele 2013-02-03 11:31:12 +00:00
commit bd1ea13b8d
16 changed files with 100 additions and 343 deletions

View File

@ -85,6 +85,24 @@ def checkSqlInjection(place, parameter, value):
if kb.endDetection:
break
if conf.dbms is None:
if not injection.dbms and PAYLOAD.TECHNIQUE.BOOLEAN in injection.data:
if not Backend.getIdentifiedDbms() and not kb.heuristicDbms:
kb.heuristicDbms = heuristicCheckDbms(injection) or UNKNOWN_DBMS
if not conf.testFilter and (Backend.getErrorParsedDBMSes() or kb.heuristicDbms) not in ([], None, UNKNOWN_DBMS):
if kb.reduceTests is None and Backend.getErrorParsedDBMSes():
msg = "heuristic (parsing) test showed that the "
msg += "back-end DBMS could be '%s'. " % (Format.getErrorParsedDBMSes() if Backend.getErrorParsedDBMSes() else kb.heuristicDbms)
msg += "Do you want to skip test payloads specific for other DBMSes? [Y/n]"
kb.reduceTests = [] if readInput(msg, default='Y').upper() != 'Y' else (Backend.getErrorParsedDBMSes() or [kb.heuristicDbms])
if kb.extendTests is None:
_ = (Format.getErrorParsedDBMSes() if Backend.getErrorParsedDBMSes() else kb.heuristicDbms)
msg = "do you want to include all tests for '%s' " % _
msg += "ignoring provided level (%d) and risk (%s)? [Y/n]" % (conf.level, conf.risk)
kb.extendTests = [] if readInput(msg, default='Y').upper() != 'Y' else (Backend.getErrorParsedDBMSes() or [kb.heuristicDbms])
title = test.title
stype = test.stype
clause = test.clause
@ -143,15 +161,24 @@ def checkSqlInjection(place, parameter, value):
logger.debug(debugMsg)
continue
# Skip DBMS-specific test if it does not match either the
# previously identified or the user's provided DBMS (either
# from program switch or from parsed error message(s))
if "details" in test and "dbms" in test.details:
dbms = test.details.dbms
else:
dbms = None
# Skip tests if title is not included by the given filter
if conf.testFilter:
if not any(re.search(conf.testFilter, str(item), re.I) for item in (test.title, test.vector,\
test.details.dbms if "details" in test and "dbms" in test.details else "")):
if not any(re.search(conf.testFilter, str(item), re.I) for item in (test.title, test.vector, dbms)):
debugMsg = "skipping test '%s' because " % title
debugMsg += "its name/vector/dbms is not included by the given filter"
logger.debug(debugMsg)
continue
else:
if not (kb.extendTests and intersect(dbms, kb.extendTests)):
# Skip test if the risk is higher than the provided (or default)
# value
# Parse test's <risk>
@ -170,14 +197,6 @@ def checkSqlInjection(place, parameter, value):
logger.debug(debugMsg)
continue
# Skip DBMS-specific test if it does not match either the
# previously identified or the user's provided DBMS (either
# from program switch or from parsed error message(s))
if "details" in test and "dbms" in test.details:
dbms = test.details.dbms
else:
dbms = None
if dbms is not None:
if injection.dbms is not None and not intersect(injection.dbms, dbms):
debugMsg = "skipping test '%s' because " % title
@ -192,17 +211,7 @@ def checkSqlInjection(place, parameter, value):
logger.debug(debugMsg)
continue
if conf.dbms is None and len(Backend.getErrorParsedDBMSes()) > 0 and not intersect(dbms, Backend.getErrorParsedDBMSes()) and kb.skipOthersDbms is None:
msg = "parsed error message(s) showed that the "
msg += "back-end DBMS could be %s. " % Format.getErrorParsedDBMSes()
msg += "Do you want to skip test payloads specific for other DBMSes? [Y/n]"
if readInput(msg, default="Y") in ("y", "Y"):
kb.skipOthersDbms = Backend.getErrorParsedDBMSes()
else:
kb.skipOthersDbms = []
if kb.skipOthersDbms and not intersect(dbms, kb.skipOthersDbms):
if kb.reduceTests and not intersect(dbms, kb.reduceTests):
debugMsg = "skipping test '%s' because " % title
debugMsg += "the parsed error message(s) showed "
debugMsg += "that the back-end DBMS could be "
@ -444,10 +453,7 @@ def checkSqlInjection(place, parameter, value):
configUnion(test.request.char, test.request.columns)
if not Backend.getIdentifiedDbms():
if not kb.heuristicDbms:
kb.heuristicDbms = heuristicCheckDbms(injection) or UNKNOWN_DBMS
if kb.heuristicDbms == UNKNOWN_DBMS:
if kb.heuristicDbms in (None, UNKNOWN_DBMS):
warnMsg = "using unescaped version of the test "
warnMsg += "because of zero knowledge of the "
warnMsg += "back-end DBMS. You can try to "
@ -556,8 +562,8 @@ def checkSqlInjection(place, parameter, value):
warnMsg = "user aborted during detection phase"
logger.warn(warnMsg)
message = "How do you want to proceed? [(S)kip current test/(e)nd detection phase/(n)ext parameter/(q)uit]"
choice = readInput(message, default="S", checkBatch=False)
msg = "How do you want to proceed? [(S)kip current test/(e)nd detection phase/(n)ext parameter/(q)uit]"
choice = readInput(msg, default="S", checkBatch=False)
if choice[0] in ("s", "S"):
pass
@ -594,24 +600,23 @@ def checkSqlInjection(place, parameter, value):
def heuristicCheckDbms(injection):
retVal = None
if not Backend.getIdentifiedDbms() and len(injection.data) == 1 and PAYLOAD.TECHNIQUE.BOOLEAN in injection.data:
pushValue(kb.injection)
kb.injection = injection
randStr1, randStr2 = randomStr(), randomStr()
pushValue(kb.injection)
kb.injection = injection
randStr1, randStr2 = randomStr(), randomStr()
for dbms in getPublicTypeMembers(DBMS, True):
Backend.forceDbms(dbms)
for dbms in getPublicTypeMembers(DBMS, True):
Backend.forceDbms(dbms)
if checkBooleanExpression("(SELECT '%s'%s)='%s'" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), randStr1)):
if not checkBooleanExpression("(SELECT '%s'%s)='%s'" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), randStr2)):
retVal = dbms
break
if checkBooleanExpression("(SELECT '%s'%s)='%s'" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), randStr1)):
if not checkBooleanExpression("(SELECT '%s'%s)='%s'" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), randStr2)):
retVal = dbms
break
Backend.flushForcedDbms()
kb.injection = popValue()
Backend.flushForcedDbms()
kb.injection = popValue()
if retVal:
infoMsg = "heuristic test showed that the back-end DBMS "
infoMsg = "heuristic (extended) test shows that the back-end DBMS " # not as important as "parsing" counter-part (because of false-positives)
infoMsg += "could be '%s' " % retVal
logger.info(infoMsg)
@ -725,7 +730,7 @@ def heuristicCheckSqlInjection(place, parameter):
parseFilePaths(page)
result = wasLastResponseDBMSError()
infoMsg = "heuristic test shows that %s " % place
infoMsg = "heuristic (parsing) test shows that %s " % place
infoMsg += "parameter '%s' might " % parameter
def _(page):
@ -758,7 +763,7 @@ def heuristicCheckSqlInjection(place, parameter):
kb.ignoreCasted = readInput(message, default='Y' if conf.multipleTargets else 'N').upper() != 'N'
elif result:
infoMsg += "be injectable (possible DBMS: %s)" % (Format.getErrorParsedDBMSes() or UNKNOWN_DBMS)
infoMsg += "be injectable (possible DBMS: '%s')" % (Format.getErrorParsedDBMSes() or UNKNOWN_DBMS)
logger.info(infoMsg)
else:

View File

@ -426,6 +426,10 @@ class Agent(object):
fieldsMinMaxstr = re.search(r"(?:MIN|MAX)\(([^\(\)]+)\)", query, re.I)
fieldsNoSelect = query
_ = zeroDepthSearch(query, " FROM ")
if not _:
fieldsSelectFrom = None
if fieldsSubstr:
fieldsToCastStr = query
elif fieldsMinMaxstr:
@ -441,7 +445,6 @@ class Agent(object):
elif fieldsSelectCase:
fieldsToCastStr = fieldsSelectCase.groups()[0]
elif fieldsSelectFrom:
_ = zeroDepthSearch(query, " FROM ")
fieldsToCastStr = query[:unArrayizeValue(_)] if _ else query
fieldsToCastStr = re.sub(r"\ASELECT%s\s+" % prefixRegex, "", fieldsToCastStr)
elif fieldsSelect:
@ -888,23 +891,17 @@ class Agent(object):
lengthQuery = queries[Backend.getIdentifiedDbms()].length.query
select = re.search("\ASELECT\s+", expression, re.I)
selectTopExpr = re.search("\ASELECT\s+TOP\s+[\d]+\s+(.+?)\s+FROM", expression, re.I)
selectDistinctExpr = re.search("\ASELECT\s+DISTINCT\((.+?)\)\s+FROM", expression, re.I)
selectFromExpr = re.search("\ASELECT\s+(.+?)\s+FROM", expression, re.I)
selectExpr = re.search("\ASELECT\s+(.+)$", expression, re.I)
_, _, _, _, _, _, fieldsStr, _ = self.getFields(expression)
if any((selectTopExpr, selectDistinctExpr, selectFromExpr, selectExpr)):
if any((selectTopExpr, selectFromExpr, selectExpr)):
query = fieldsStr
else:
query = expression
if selectDistinctExpr:
lengthExpr = "SELECT %s FROM (%s)" % (lengthQuery % query, expression)
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL):
lengthExpr += " AS %s" % randomStr(lowercase=True)
elif select:
if select:
lengthExpr = expression.replace(query, lengthQuery % query, 1)
else:
lengthExpr = lengthQuery % expression

View File

@ -974,7 +974,6 @@ def setPaths():
paths.SMALL_DICT = os.path.join(paths.SQLMAP_TXT_PATH, "smalldict.txt")
paths.USER_AGENTS = os.path.join(paths.SQLMAP_TXT_PATH, "user-agents.txt")
paths.WORDLIST = os.path.join(paths.SQLMAP_TXT_PATH, "wordlist.zip")
paths.PHPIDS_RULES_XML = os.path.join(paths.SQLMAP_XML_PATH, "phpids_rules.xml")
paths.ERRORS_XML = os.path.join(paths.SQLMAP_XML_PATH, "errors.xml")
paths.PAYLOADS_XML = os.path.join(paths.SQLMAP_XML_PATH, "payloads.xml")
paths.INJECTIONS_XML = os.path.join(paths.SQLMAP_XML_PATH, "injections.xml")
@ -1376,6 +1375,8 @@ def safeStringFormat(format_, params):
if isinstance(params, basestring):
retVal = retVal.replace("%s", params)
elif not isListLike(params):
retVal = retVal.replace("%s", str(params))
else:
count, index = 0, 0
while index != -1:

View File

@ -205,6 +205,7 @@ POST_HINT_CONTENT_TYPES = {
DEPRECATED_OPTIONS = {
"--replicate": "use '--dump-format=SQLITE' instead",
"--no-unescape": "use '--no-escape' instead",
"--check-payload": None,
}
DUMP_DATA_PREPROCESS = {

View File

@ -324,6 +324,10 @@ def _feedTargetsDict(reqFile, addedTargetUrls):
scheme = "https"
port = port or "443"
if not host:
errMsg = "invalid format of a request file"
raise SqlmapSyntaxException, errMsg
if not url.startswith("http"):
url = "%s://%s:%s%s" % (scheme or "http", host, port or "80", url)
scheme = None
@ -1521,6 +1525,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.dynamicParameter = False
kb.endDetection = False
kb.explicitSettings = set()
kb.extendTests = None
kb.errorIsNone = True
kb.fileReadMode = False
kb.forcedDbms = None
@ -1548,12 +1553,6 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.multiThreadMode = False
kb.negativeLogic = False
kb.nullConnection = None
kb.pageCompress = True
kb.pageTemplate = None
kb.pageTemplates = dict()
kb.postHint = None
kb.previousMethod = None
kb.processUserMarks = None
kb.orderByColumns = None
kb.originalCode = None
kb.originalPage = None
@ -1566,12 +1565,19 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.osVersion = None
kb.osSP = None
kb.pageCompress = True
kb.pageTemplate = None
kb.pageTemplates = dict()
kb.pageEncoding = DEFAULT_PAGE_ENCODING
kb.pageStable = None
kb.partRun = None
kb.permissionFlag = False
kb.postHint = None
kb.postSpaceToPlus = False
kb.prependFlag = False
kb.processResponseCounter = 0
kb.previousMethod = None
kb.processUserMarks = None
kb.proxyAuthHeader = None
kb.queryCounter = 0
kb.redirectChoice = None
@ -1584,8 +1590,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.resumeValues = True
kb.safeCharEncode = False
kb.singleLogFlags = set()
kb.skipOthersDbms = None
kb.postSpaceToPlus = False
kb.reduceTests = None
kb.stickyDBMS = False
kb.stickyLevel = None
kb.suppressResumeInfo = False

View File

@ -195,7 +195,6 @@ optDict = {
"alert": "string",
"answers": "string",
"beep": "boolean",
"checkPayload": "boolean",
"checkWaf": "boolean",
"cleanup": "boolean",
"dependencies": "boolean",

View File

@ -466,7 +466,7 @@ VALID_TIME_CHARS_RUN_THRESHOLD = 100
CHECK_ZERO_COLUMNS_THRESHOLD = 10
# Boldify all logger messages containing these "patterns"
BOLD_PATTERNS = ("' injectable", "might be injectable", "' is vulnerable", "is not injectable", "test failed", "test passed", "live test final result", "heuristic test showed")
BOLD_PATTERNS = ("' injectable", "might be injectable", "' is vulnerable", "is not injectable", "test failed", "test passed", "live test final result", "test shows that")
# Generic www root directory names
GENERIC_DOC_ROOT_DIRECTORY_NAMES = ("htdocs", "wwwroot", "www")

View File

@ -612,10 +612,6 @@ def cmdLineParser():
miscellaneous.add_option("--beep", dest="beep", action="store_true",
help="Make a beep sound when SQL injection is found")
miscellaneous.add_option("--check-payload", dest="checkPayload",
action="store_true",
help="Offline WAF/IPS/IDS payload detection testing")
miscellaneous.add_option("--check-waf", dest="checkWaf",
action="store_true",
help="Check for existence of WAF/IPS/IDS protection")

View File

@ -256,8 +256,7 @@ def decodePage(page, contentEncoding, contentType):
def processResponse(page, responseHeaders):
kb.processResponseCounter += 1
if not kb.dumpTable:
parseResponse(page, responseHeaders if kb.processResponseCounter < PARSE_HEADERS_LIMIT else None)
parseResponse(page, responseHeaders if kb.processResponseCounter < PARSE_HEADERS_LIMIT else None)
if conf.parseErrors:
msg = extractErrorMessage(page)

View File

@ -79,7 +79,6 @@ from lib.request.basic import processResponse
from lib.request.direct import direct
from lib.request.comparison import comparison
from lib.request.methodrequest import MethodRequest
from lib.utils.checkpayload import checkPayload
from thirdparty.socks.socks import ProxyError
from thirdparty.multipart import multipartpost
@ -658,9 +657,6 @@ class Connect(object):
if place:
value = agent.removePayloadDelimiters(value)
if conf.checkPayload:
checkPayload(value)
if PLACE.GET in conf.parameters:
get = conf.parameters[PLACE.GET] if place != PLACE.GET or not value else value

View File

@ -25,6 +25,7 @@ from lib.core.common import isTechniqueAvailable
from lib.core.common import parseUnionPage
from lib.core.common import popValue
from lib.core.common import pushValue
from lib.core.common import randomStr
from lib.core.common import readInput
from lib.core.common import singleTimeWarnMessage
from lib.core.data import conf
@ -76,6 +77,13 @@ def _goInference(payload, expression, charsetType=None, firstChar=None, lastChar
if not (timeBasedCompare and kb.dnsTest):
if (conf.eta or conf.threads > 1) and Backend.getIdentifiedDbms() and not re.search("(COUNT|LTRIM)\(", expression, re.I) and not timeBasedCompare:
if field and re.search("\ASELECT\s+DISTINCT\((.+?)\)\s+FROM", expression, re.I):
expression = "SELECT %s FROM (%s)" % (field, expression)
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL):
expression += " AS %s" % randomStr(lowercase=True)
if field and conf.hexConvert:
nulledCastedField = agent.nullAndCastField(field)
injExpression = expression.replace(field, nulledCastedField, 1)

View File

@ -1,56 +0,0 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2013 sqlmap developers (http://sqlmap.org/)
See the file 'doc/COPYING' for copying permission
"""
import re
from lib.core.common import readXmlFile
from lib.core.common import urldecode
from lib.core.data import paths
from lib.core.data import logger
rules = None
def _adjustGrammar(string):
string = re.sub('\ADetects', 'Detected', string)
string = re.sub('\Afinds', 'Found', string)
string = re.sub('attempts\Z', 'attempt', string)
string = re.sub('injections\Z', 'injection', string)
string = re.sub('attacks\Z', 'attack', string)
return string
def checkPayload(payload):
"""
This method checks if the generated payload is detectable by the
PHPIDS filter rules
"""
if not payload:
return
global rules
detected = False
payload = urldecode(payload, convall=True)
if not rules:
xmlrules = readXmlFile(paths.PHPIDS_RULES_XML)
rules = []
for xmlrule in xmlrules.getElementsByTagName("filter"):
rule = "(?i)%s" % xmlrule.getElementsByTagName('rule')[0].childNodes[0].nodeValue
desc = _adjustGrammar(xmlrule.getElementsByTagName('description')[0].childNodes[0].nodeValue)
rules.append((rule, desc))
if payload:
for rule, desc in rules:
if re.search(rule, payload):
detected = True
logger.warn("highly probable IDS/IPS detection: '%s: %s'" % (desc, payload))
if not detected:
logger.warn("payload '%s' possibly gone undetected" % payload)

View File

@ -534,8 +534,13 @@ class Search:
for index in indexRange:
query = rootQuery.blind.query2
query = query % db
query += " AND %s" % colQuery
if query.endswith("'%s')"):
query = query[:-1] + " AND %s)" % colQuery
else:
query += " AND %s" % colQuery
query = safeStringFormat(query, db)
query += whereTblsQuery
query = agent.limitQuery(index, query)

View File

@ -2231,9 +2231,9 @@ Formats:
<risk>2</risk>
<clause>0</clause>
<where>1</where>
<vector>; SELECT (CASE WHEN ([INFERENCE]) THEN (LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]0000000))))) ELSE [RANDNUM] END)</vector>
<vector>; SELECT (CASE WHEN ([INFERENCE]) THEN (LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]00000000/2))))) ELSE [RANDNUM] END)</vector>
<request>
<payload>; SELECT LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]0000000))))</payload>
<payload>; SELECT LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]00000000/2))))</payload>
<comment>--</comment>
</request>
<response>
@ -2580,9 +2580,9 @@ Formats:
<risk>2</risk>
<clause>1</clause>
<where>1</where>
<vector>AND [RANDNUM]=(CASE WHEN ([INFERENCE]) THEN (LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]0000000))))) ELSE [RANDNUM] END)</vector>
<vector>AND [RANDNUM]=(CASE WHEN ([INFERENCE]) THEN (LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]00000000/2))))) ELSE [RANDNUM] END)</vector>
<request>
<payload>AND [RANDNUM]=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]0000000))))</payload>
<payload>AND [RANDNUM]=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]00000000/2))))</payload>
</request>
<response>
<time>[DELAYED]</time>
@ -2600,9 +2600,9 @@ Formats:
<risk>2</risk>
<clause>1</clause>
<where>1</where>
<vector>AND [RANDNUM]=(CASE WHEN ([INFERENCE]) THEN (LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]0000000))))) ELSE [RANDNUM] END)</vector>
<vector>AND [RANDNUM]=(CASE WHEN ([INFERENCE]) THEN (LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]00000000/2))))) ELSE [RANDNUM] END)</vector>
<request>
<payload>AND [RANDNUM]=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]0000000))))</payload>
<payload>AND [RANDNUM]=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]00000000/2))))</payload>
<comment>--</comment>
</request>
<response>
@ -2881,9 +2881,9 @@ Formats:
<risk>3</risk>
<clause>1</clause>
<where>2</where>
<vector>OR [RANDNUM]=(CASE WHEN ([INFERENCE]) THEN (LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]0000000))))) ELSE [RANDNUM] END)</vector>
<vector>OR [RANDNUM]=(CASE WHEN ([INFERENCE]) THEN (LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]00000000/2))))) ELSE [RANDNUM] END)</vector>
<request>
<payload>OR [RANDNUM]=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]0000000))))</payload>
<payload>OR [RANDNUM]=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]00000000/2))))</payload>
</request>
<response>
<time>[DELAYED]</time>
@ -3178,9 +3178,9 @@ Formats:
<risk>2</risk>
<clause>1,2,3</clause>
<where>3</where>
<vector>(SELECT (CASE WHEN ([INFERENCE]) THEN (LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]0000000))))) ELSE [RANDNUM] END))</vector>
<vector>(SELECT (CASE WHEN ([INFERENCE]) THEN (LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]00000000/2))))) ELSE [RANDNUM] END))</vector>
<request>
<payload>(SELECT LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]0000000)))))</payload>
<payload>(SELECT LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]00000000/2)))))</payload>
</request>
<response>
<time>[DELAYED]</time>

View File

@ -1,199 +0,0 @@
<filters>
<filter>
<id>40</id>
<rule><![CDATA[(?:\)\s*when\s*\d+\s*then)|(?:"\s*(?:#|--|{))|(?:\/\*!\s?\d+)|(?:ch(?:a)?r\s*\(\s*\d)|(?:(?:(n?and|x?or|not)\s+|\|\||\&\&)\s*\w+\()]]></rule>
<description>Detects MySQL comments, conditions and ch(a)r injections</description>
<tags>
<tag>sqli</tag>
<tag>id</tag>
<tag>lfi</tag>
</tags>
<impact>6</impact>
</filter>
<filter>
<id>41</id>
<rule><![CDATA[(?:[\s()]case\s*\()|(?:\)\s*like\s*\()|(?:having\s*[^\s]+\s*[^\w\s])|(?:if\s?\([\d\w]\s*[=<>~])]]></rule>
<description>Detects conditional SQL injection attempts</description>
<tags>
<tag>sqli</tag>
<tag>id</tag>
<tag>lfi</tag>
</tags>
<impact>6</impact>
</filter>
<filter>
<id>42</id>
<rule><![CDATA[(?:"\s*or\s*\d)|(?:\\x(?:23|27|3d))|(?:^.?"$)|(?:^.*\\".+(?<!\\)")|(?:(?:^["\\]*(?:[\d"]+|[^"]+"))+\s*(?:n?and|x?or|not|\|\||\&\&)\s*[\w"[+&!@(),.-])|(?:[^\w\s]\w+\s*[|-]\s*"\s*\w)|(?:@\w+\s+(and|or)\s*["\d]+)|(?:@[\w-]+\s(and|or)\s*[^\w\s])|(?:[^\w\s:]\s*\d\W+[^\w\s]\s*".)]]></rule>
<description>Detects classic SQL injection probings 1/2</description>
<tags>
<tag>sqli</tag>
<tag>id</tag>
<tag>lfi</tag>
</tags>
<impact>6</impact>
</filter>
<filter>
<id>43</id>
<rule><![CDATA[(?:"\s*\*.+(?:or|id)\W*"\d)|(?:\^")|(?:^[\w\s"-]+(?<=and\s)(?<=or\s)(?<=xor\s)(?<=nand\s)(?<=not\s)(?<=\|\|)(?<=\&\&)\w+\()|(?:"[\s\d]*[^\w\s]+\W*\d\W*.*["\d])|(?:"\s*[^\w\s?]+\s*[^\w\s]+\s*")|(?:"\s*[^\w\s]+\s*[\W\d].*(?:#|--))|(?:".*\*\s*\d)|(?:"\s*or\s[\w-]+.*\d)|(?:[()*<>%+-][\w-]+[^\w\s]+"[^,])]]></rule>
<description>Detects classic SQL injection probings 2/2</description>
<tags>
<tag>sqli</tag>
<tag>id</tag>
<tag>lfi</tag>
</tags>
<impact>6</impact>
</filter>
<filter>
<id>44</id>
<rule><![CDATA[(?:\d"\s+"\s+\d)|(?:^admin\s*"|(\/\*)+"+\s?(?:--|#|\/\*|{)?)|(?:"\s*or[\w\s-]+\s*[+<>=(),-]\s*[\d"])|(?:"\s*[^\w\s]?=\s*")|(?:"\W*[+=]+\W*")|(?:"\s*[!=|][\d\s!=+-]+.*["(].*$)|(?:"\s*[!=|][\d\s!=]+.*\d+$)|(?:"\s*like\W+[\w"(])|(?:\sis\s*0\W)|(?:where\s[\s\w\.,-]+\s=)|(?:"[<>~]+")]]></rule>
<description>Detects basic SQL authentication bypass attempts 1/3</description>
<tags>
<tag>sqli</tag>
<tag>id</tag>
<tag>lfi</tag>
</tags>
<impact>7</impact>
</filter>
<filter>
<id>45</id>
<rule><![CDATA[(?:union\s*(?:all|distinct|[(!@]+)?\s*[([]*\s*select)|(?:\w+\s+like\s+\")|(?:like\s*"\%)|(?:"\s*like\W*["\d])|(?:"\s*(?:n?and|x?or|not |\|\||\&\&)\s+[\s\w]+=\s*\w+\s*having)|(?:"\s*\*\s*\w+\W+")|(?:"\s*[^?\w\s=.,;)(]+\s*[(@"]*\s*\w+\W+\w)|(?:select\s*[\[\]()\s\w\.,-]+from)]]></rule>
<description>Detects basic SQL authentication bypass attempts 2/3</description>
<tags>
<tag>sqli</tag>
<tag>id</tag>
<tag>lfi</tag>
</tags>
<impact>7</impact>
</filter>
<filter>
<id>46</id>
<rule><![CDATA[(?:in\s*\(+\s*select)|(?:(?:n?and|x?or|not |\|\||\&\&)\s+[\s\w+]+(?:regexp\s*\(|sounds\s+like\s*"|[=\d]+x))|("\s*\d\s*(?:--|#))|(?:"[%&<>^=]+\d\s*(=|or))|(?:"\W+[\w+-]+\s*=\s*\d\W+")|(?:"\s*is\s*\d.+"?\w)|(?:"\|?[\w-]{3,}[^\w\s.,]+")|(?:"\s*is\s*[\d.]+\s*\W.*")]]></rule>
<description>Detects basic SQL authentication bypass attempts 3/3</description>
<tags>
<tag>sqli</tag>
<tag>id</tag>
<tag>lfi</tag>
</tags>
<impact>7</impact>
</filter>
<filter>
<id>47</id>
<rule><![CDATA[(?:[\d\W]\s+as\s*["\w]+\s*from)|(?:^[\W\d]+\s*(?:union|select|create|rename|truncate|load|alter|delete|update|insert|desc))|(?:(?:select|create|rename|truncate|load|alter|delete|update|insert|desc)\s+(?:concat|char|load_file)\s?\(?)|(?:end\s*\);)|("\s+regexp\W)|(?:[\s(]load_file\s*\()]]></rule>
<description>Detects concatenated basic SQL injection and SQLLFI attempts</description>
<tags>
<tag>sqli</tag>
<tag>id</tag>
<tag>lfi</tag>
</tags>
<impact>5</impact>
</filter>
<filter>
<id>48</id>
<rule><![CDATA[(?:\d+\s*or\s*\d+\s*[\-+])|(?:\/\w+;?\s+(?:having|and|or|select))|(?:\d\s+group\s+by.+\()|(?:(?:;|#|--)\s*(?:drop|alter))|(?:(?:;|#|--)\s*(?:update|insert)\s*\w{2,})|(?:[^\w]SET\s*@\w+)|(?:(?:n?and|x?or|not |\|\||\&\&)[\s(]+\w+[\s)]*[!=+]+[\s\d]*["=()])]]></rule>
<description>Detects chained SQL injection attempts 1/2</description>
<tags>
<tag>sqli</tag>
<tag>id</tag>
</tags>
<impact>6</impact>
</filter>
<filter>
<id>49</id>
<rule><![CDATA[(?:"\s+and\s*=\W)|(?:\(\s*select\s*\w+\s*\()|(?:\*\/from)|(?:\+\s*\d+\s*\+\s*@)|(?:\w"\s*(?:[-+=|@]+\s*)+[\d(])|(?:coalesce\s*\(|@@\w+\s*[^\w\s])|(?:\W!+"\w)|(?:";\s*(?:if|while|begin))|(?:"[\s\d]+=\s*\d)|(?:order\s+by\s+if\w*\s*\()|(?:[\s(]+case\d*\W.+[tw]hen[\s(])]]></rule>
<description>Detects chained SQL injection attempts 2/2</description>
<tags>
<tag>sqli</tag>
<tag>id</tag>
</tags>
<impact>6</impact>
</filter>
<filter>
<id>50</id>
<rule><![CDATA[(?:(select|;)\s+(?:benchmark|if|sleep)\s*?\(\s*\(?\s*\w+)]]></rule>
<description>Detects SQL benchmark and sleep injection attempts including conditional queries</description>
<tags>
<tag>sqli</tag>
<tag>id</tag>
</tags>
<impact>4</impact>
</filter>
<filter>
<id>51</id>
<rule><![CDATA[(?:create\s+function\s+\w+\s+returns)|(?:;\s*(?:select|create|rename|truncate|load|alter|delete|update|insert|desc)\s*[\[(]?\w{2,})]]></rule>
<description>Detects MySQL UDF injection and other data/structure manipulation attempts</description>
<tags>
<tag>sqli</tag>
<tag>id</tag>
</tags>
<impact>6</impact>
</filter>
<filter>
<id>52</id>
<rule><![CDATA[(?:alter\s*\w+.*character\s+set\s+\w+)|(";\s*waitfor\s+time\s+")|(?:";.*:\s*goto)]]></rule>
<description>Detects MySQL charset switch and MSSQL DoS attempts</description>
<tags>
<tag>sqli</tag>
<tag>id</tag>
</tags>
<impact>6</impact>
</filter>
<filter>
<id>53</id>
<rule><![CDATA[(?:procedure\s+analyse\s*\()|(?:;\s*(declare|open)\s+[\w-]+)|(?:create\s+(procedure|function)\s*\w+\s*\(\s*\)\s*-)|(?:declare[^\w]+[@#]\s*\w+)|(exec\s*\(\s*@)]]></rule>
<description>Detects MySQL and PostgreSQL stored procedure/function injections</description>
<tags>
<tag>sqli</tag>
<tag>id</tag>
</tags>
<impact>7</impact>
</filter>
<filter>
<id>54</id>
<rule><![CDATA[(?:select\s*pg_sleep)|(?:waitfor\s*delay\s?"+\s?\d)|(?:;\s*shutdown\s*(?:;|--|#|\/\*|{))]]></rule>
<description>Detects Postgres pg_sleep injection, waitfor delay attacks and database shutdown attempts</description>
<tags>
<tag>sqli</tag>
<tag>id</tag>
</tags>
<impact>5</impact>
</filter>
<filter>
<id>55</id>
<rule><![CDATA[(?:\sexec\s+xp_cmdshell)|(?:"\s*!\s*["\w])|(?:from\s+information_schema\W)|(?:(?:(?:current_)?user|database|schema|connection_id)\s*\([^\)]*)|(?:";?\s*(?:select|union|having)\s*[^\s])|(?:\wiif\s*\()|(?:exec\s+master\.)|(?:union select @)|(?:union[\w(\s]*select)|(?:select.*\w?user\()|(?:into[\s+]+(?:dump|out)file\s*")]]></rule>
<description>Detects MSSQL code execution and information gathering attempts</description>
<tags>
<tag>sqli</tag>
<tag>id</tag>
</tags>
<impact>5</impact>
</filter>
<filter>
<id>56</id>
<rule><![CDATA[(?:merge.*using\s*\()|(execute\s*immediate\s*")|(?:\W+\d*\s*having\s*[^\s])|(?:match\s*[\w(),+-]+\s*against\s*\()]]></rule>
<description>Detects MATCH AGAINST, MERGE, EXECUTE IMMEDIATE and HAVING injections</description>
<tags>
<tag>sqli</tag>
<tag>id</tag>
</tags>
<impact>5</impact>
</filter>
<filter>
<id>57</id>
<rule><![CDATA[(?:select\s*\*\s*from)|((?:select|create|rename|truncate|load|alter|delete|update|insert|desc)\s*\(\s*space\s*\()]]></rule>
<description>Detects MySQL comment-/space-obfuscated injections</description>
<tags>
<tag>sqli</tag>
<tag>id</tag>
</tags>
<impact>5</impact>
</filter>
<filter>
<id>70</id>
<rule><![CDATA[(?:\[\$(?:ne|eq|lte?|gte?|n?in|mod|all|size|exists|type|slice|or)\])]]></rule>
<description>finds basic MongoDB SQL injection attempts</description>
<tags>
<tag>sqli</tag>
</tags>
<impact>4</impact>
</filter>
</filters>

View File

@ -344,10 +344,10 @@
<!-- Microsoft Access -->
<dbms value="Microsoft Access">
<cast query="CVAR(%s)"/>
<length query="LEN(%s)"/>
<cast query="RTRIM(CVAR(%s))"/>
<length query="LEN(RTRIM(CVAR(%s)))"/>
<isnull query="IIF(LEN(%s)=0,' ',%s)"/>
<delimiter query=","/>
<delimiter query="&amp;"/>
<limit query="TOP %d"/>
<limitregexp query="\s+TOP\s+([\d]+)"/>
<limitgroupstart query="1"/>