diff --git a/lib/core/option.py b/lib/core/option.py index ce6029fa8..1f6e88574 100644 --- a/lib/core/option.py +++ b/lib/core/option.py @@ -77,7 +77,6 @@ from lib.core.exception import sqlmapSyntaxException from lib.core.exception import sqlmapUnsupportedDBMSException from lib.core.exception import sqlmapUserQuitException from lib.core.optiondict import optDict -from lib.request.dns import DNSServer from lib.core.settings import CODECS_LIST_PAGE from lib.core.settings import DEFAULT_GET_POST_DELIMITER from lib.core.settings import DEFAULT_PAGE_ENCODING @@ -116,6 +115,7 @@ from lib.core.update import update from lib.parse.configfile import configFileParser from lib.parse.payloads import loadPayloads from lib.request.connect import Connect as Request +from lib.request.dns import DNSServer from lib.request.proxy import ProxyHTTPSHandler from lib.request.basicauthhandler import SmartHTTPBasicAuthHandler from lib.request.certhandler import HTTPSCertAuthHandler @@ -1719,7 +1719,7 @@ def __setDNSServer(): if not conf.dnsDomain: return - infoMsg = "making DNS server instance" + infoMsg = "setting up DNS server instance" logger.info(infoMsg) isAdmin = runningAsAdmin() @@ -1730,7 +1730,7 @@ def __setDNSServer(): else: errMsg = "you need to run sqlmap as an administrator " errMsg += "if you want to perform a DNS data exfiltration attack " - errMsg += "as it will need to listen on privileged TCP port 53 " + errMsg += "as it will need to listen on privileged UDP port 53 " errMsg += "for incoming address resolution attempts" raise sqlmapMissingPrivileges, errMsg diff --git a/lib/core/settings.py b/lib/core/settings.py index ae3e4f499..6d55b7739 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -194,12 +194,12 @@ REFERER_ALIASES = ( "ref", "referer", "referrer" ) HOST_ALIASES = ( "host", ) FROM_DUMMY_TABLE = { - DBMS.ORACLE: " FROM DUAL", - DBMS.ACCESS: " FROM MSysAccessObjects", - DBMS.FIREBIRD: " FROM RDB$DATABASE", - DBMS.MAXDB: " FROM VERSIONS", - DBMS.DB2: " FROM SYSIBM.SYSDUMMY1" - } + DBMS.ORACLE: " FROM DUAL", + DBMS.ACCESS: " FROM MSysAccessObjects", + DBMS.FIREBIRD: " FROM RDB$DATABASE", + DBMS.MAXDB: " FROM VERSIONS", + DBMS.DB2: " FROM SYSIBM.SYSDUMMY1" + } SQL_STATEMENTS = { "SQL SELECT statement": ( diff --git a/lib/request/dns.py b/lib/request/dns.py index 4cbd45d4b..427b456c8 100644 --- a/lib/request/dns.py +++ b/lib/request/dns.py @@ -90,14 +90,18 @@ if __name__ == "__main__": try: server = DNSServer() server.run() + while server._running: while True: _ = server.pop() + if _ is None: break else: print "[i] %s" % _ + time.sleep(1) + except socket.error, ex: if 'Permission' in str(ex): print "[x] Please run with sudo/Administrator privileges" diff --git a/lib/request/inject.py b/lib/request/inject.py index a59a7e8ce..1dee26941 100644 --- a/lib/request/inject.py +++ b/lib/request/inject.py @@ -85,11 +85,15 @@ def __goDns(payload, expression): if conf.dnsDomain and kb.dnsTest is not False: if kb.dnsTest is None: + logger.info("testing for data retrieval through DNS channel") + randInt = randomInt() kb.dnsTest = dnsUse(payload, "SELECT %d%s" % (randInt, FROM_DUMMY_TABLE.get(Backend.getIdentifiedDbms(), ""))) == 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" diff --git a/lib/techniques/dns/use.py b/lib/techniques/dns/use.py index 124e7bc97..8fe74d86c 100644 --- a/lib/techniques/dns/use.py +++ b/lib/techniques/dns/use.py @@ -53,6 +53,7 @@ def dnsUse(payload, expression): if conf.dnsDomain and Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.ORACLE): output = hashDBRetrieve(expression, checkConf=True) + if output and PARTIAL_VALUE_MARKER in output or kb.dnsTest is None: output = None @@ -79,14 +80,17 @@ def dnsUse(payload, expression): forgedPayload = agent.payload(newValue=query) else: forgedPayload = safeStringFormat(payload, (expressionUnescaped, randomInt(1), randomInt(3))) + Request.queryPage(forgedPayload, content=False, noteResponseTime=False, raise404=False) _ = conf.dnsServer.pop(prefix, suffix) + if _: _ = extractRegexResult("%s\.(?P.+)\.%s" % (prefix, suffix), _, re.I) _ = decodeHexValue(_) output = (output or "") + _ offset += len(_) + if len(_) < chunk_length: break else: @@ -96,8 +100,10 @@ def dnsUse(payload, expression): if output is not None: retVal = output + if kb.dnsTest is not None: dataToStdout("[%s] [INFO] %s: %s\r\n" % (time.strftime("%X"), "retrieved" if count > 0 else "resumed", safecharencode(output))) + if count > 0: hashDBWrite(expression, output)