diff --git a/lib/techniques/blind/inference.py b/lib/techniques/blind/inference.py index c8dc5399d..7e4868f57 100644 --- a/lib/techniques/blind/inference.py +++ b/lib/techniques/blind/inference.py @@ -46,6 +46,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None finalValue = "" asciiTbl = getCharset(charsetType) timeBasedCompare = (kb.technique in (PAYLOAD.TECHNIQUE.TIME, PAYLOAD.TECHNIQUE.STACKED)) + dbms = kb.dbms if kb.dbms else kb.misc.testedDbms # Set kb.partRun in case "common prediction" feature (a.k.a. "good # samaritan") is used @@ -117,7 +118,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None hintlock.release() if hintValue is not None and len(hintValue) >= idx: - if kb.dbms in (DBMS.SQLITE, DBMS.ACCESS, DBMS.MAXDB): + if dbms in (DBMS.SQLITE, DBMS.ACCESS, DBMS.MAXDB): posValue = hintValue[idx-1] else: posValue = ord(hintValue[idx-1]) @@ -169,7 +170,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None position = (len(charTbl) >> 1) posValue = charTbl[position] - if kb.dbms in (DBMS.SQLITE, DBMS.MAXDB): + if dbms in (DBMS.SQLITE, DBMS.MAXDB): pushValue(posValue) posValue = chr(posValue) if posValue < 128 else unichr(posValue) @@ -178,7 +179,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None queriesCount[0] += 1 result = Request.queryPage(forgedPayload, timeBasedCompare=timeBasedCompare) - if kb.dbms in (DBMS.SQLITE, DBMS.MAXDB): + if dbms in (DBMS.SQLITE, DBMS.MAXDB): posValue = popValue() if result: @@ -465,7 +466,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None # check it via equal against the substring-query output if commonPattern is not None: # Substring-query containing equals commonPattern - subquery = queries[kb.dbms].substring.query % (expressionUnescaped, 1, len(commonPattern)) + subquery = queries[dbms].substring.query % (expressionUnescaped, 1, len(commonPattern)) testValue = unescaper.unescape("'%s'" % commonPattern) if "'" not in commonPattern else unescaper.unescape("%s" % commonPattern, quote=False) query = agent.prefixQuery(safeStringFormat("AND (%s) = %s", (subquery, testValue))) query = agent.suffixQuery(query) diff --git a/plugins/dbms/access/fingerprint.py b/plugins/dbms/access/fingerprint.py index d5a01eeb5..c02f66a4d 100644 --- a/plugins/dbms/access/fingerprint.py +++ b/plugins/dbms/access/fingerprint.py @@ -22,6 +22,7 @@ from lib.core.data import logger from lib.core.enums import DBMS from lib.core.session import setDbms from lib.core.settings import ACCESS_ALIASES +from lib.request import inject from lib.request.connect import Connect as Request from plugins.generic.fingerprint import Fingerprint as GenericFingerprint @@ -40,10 +41,7 @@ class Fingerprint(GenericFingerprint): elif kb.dbmsVersion[0] in ("2002-2003", "2007"): table = "MSysAccessStorage" if table: - query = agent.prefixQuery("AND EXISTS(SELECT CURDIR() FROM %s)" % table) - query = agent.suffixQuery(query) - payload = agent.payload(newValue=query) - result = Request.queryPage(payload) + result = inject.checkBooleanExpression("EXISTS(SELECT CURDIR() FROM %s)" % table) retVal = "not sandboxed" if result else "sandboxed" return retVal @@ -70,10 +68,7 @@ class Fingerprint(GenericFingerprint): negate = True table = table[1:] randInt = randomInt() - query = agent.prefixQuery("AND EXISTS(SELECT * FROM %s WHERE %d=%d)" % (table, randInt, randInt)) - query = agent.suffixQuery(query) - payload = agent.payload(newValue=query) - result = Request.queryPage(payload) + result = inject.checkBooleanExpression("EXISTS(SELECT * FROM %s WHERE %d=%d)" % (table, randInt, randInt)) if result is None: result = False if negate: @@ -94,13 +89,10 @@ class Fingerprint(GenericFingerprint): randInt = randomInt() randStr = randomStr() - query = agent.prefixQuery("AND EXISTS(SELECT * FROM %s.%s WHERE %d=%d)" % (randStr, randStr, randInt, randInt)) - query = agent.suffixQuery(query) - payload = agent.payload(newValue=query) - page = Request.queryPage(payload, content=True) + _ = inject.checkBooleanExpression("EXISTS(SELECT * FROM %s.%s WHERE %d=%d)" % (randStr, randStr, randInt, randInt)) if wasLastRequestDBMSError(): - match = re.search("Could not find file\s+'([^']+?)'", page[0]) + match = re.search("Could not find file\s+'([^']+?)'", kb.lastErrorPage[1]) if match: retVal = match.group(1).rstrip("%s.mdb" % randStr) @@ -161,15 +153,13 @@ class Fingerprint(GenericFingerprint): logMsg = "testing Microsoft Access" logger.info(logMsg) - payload = agent.fullPayload("AND VAL(CVAR(1))=1") - result = Request.queryPage(payload) + result = inject.checkBooleanExpression("VAL(CVAR(1))=1") if result: logMsg = "confirming Microsoft Access" logger.info(logMsg) - payload = agent.fullPayload("AND IIF(ATN(2)>0,1,0) BETWEEN 2 AND 0") - result = Request.queryPage(payload) + result = inject.checkBooleanExpression("IIF(ATN(2)>0,1,0) BETWEEN 2 AND 0") if not result: warnMsg = "the back-end DBMS is not Microsoft Access" diff --git a/plugins/dbms/firebird/fingerprint.py b/plugins/dbms/firebird/fingerprint.py index f9ce93916..d46446a45 100644 --- a/plugins/dbms/firebird/fingerprint.py +++ b/plugins/dbms/firebird/fingerprint.py @@ -22,6 +22,7 @@ from lib.core.data import logger from lib.core.enums import DBMS from lib.core.session import setDbms from lib.core.settings import FIREBIRD_ALIASES +from lib.request import inject from lib.request.connect import Connect as Request from plugins.generic.fingerprint import Fingerprint as GenericFingerprint @@ -72,18 +73,17 @@ class Fingerprint(GenericFingerprint): def __sysTablesCheck(self): retVal = None table = ( - ("1.0", ["AND EXISTS(SELECT CURRENT_USER FROM RDB$DATABASE)"]), - ("1.5", ["AND NULLIF(%d,%d) IS NULL", "AND EXISTS(SELECT CURRENT_TRANSACTION FROM RDB$DATABASE)"]), - ("2.0", ["AND EXISTS(SELECT CURRENT_TIME(0) FROM RDB$DATABASE)", "AND BIT_LENGTH(%d)>0", "AND CHAR_LENGTH(%d)>0"]), - ("2.1", ["AND BIN_XOR(%d,%d)=0", "AND PI()>0.%d", "AND RAND()<1.%d", "AND FLOOR(1.%d)>=0"]) + ("1.0", ["EXISTS(SELECT CURRENT_USER FROM RDB$DATABASE)"]), + ("1.5", ["NULLIF(%d,%d) IS NULL", "EXISTS(SELECT CURRENT_TRANSACTION FROM RDB$DATABASE)"]), + ("2.0", ["EXISTS(SELECT CURRENT_TIME(0) FROM RDB$DATABASE)", "BIT_LENGTH(%d)>0", "CHAR_LENGTH(%d)>0"]), + ("2.1", ["BIN_XOR(%d,%d)=0", "PI()>0.%d", "RAND()<1.%d", "FLOOR(1.%d)>=0"]) ) for i in xrange(len(table)): version, checks = table[i] failed = False check = checks[randomRange(0,len(checks)-1)].replace("%d", getUnicode(randomRange(1,100))) - payload = agent.fullPayload(check) - result = Request.queryPage(payload) + result = inject.checkBooleanExpression(check) if result: retVal = version else: @@ -97,8 +97,7 @@ class Fingerprint(GenericFingerprint): def __dialectCheck(self): retVal = None if kb.dbms: - payload = agent.fullPayload("AND EXISTS(SELECT CURRENT_DATE FROM RDB$DATABASE)") - result = Request.queryPage(payload) + result = inject.checkBooleanExpression("EXISTS(SELECT CURRENT_DATE FROM RDB$DATABASE)") retVal = "dialect 3" if result else "dialect 1" return retVal @@ -115,16 +114,13 @@ class Fingerprint(GenericFingerprint): logger.info(logMsg) randInt = randomInt() - - payload = agent.fullPayload("AND EXISTS(SELECT * FROM RDB$DATABASE WHERE %d=%d)" % (randInt, randInt)) - result = Request.queryPage(payload) + result = inject.checkBooleanExpression("EXISTS(SELECT * FROM RDB$DATABASE WHERE %d=%d)" % (randInt, randInt)) if result: logMsg = "confirming Firebird" logger.info(logMsg) - payload = agent.fullPayload("AND EXISTS(SELECT CURRENT_USER FROM RDB$DATABASE)") - result = Request.queryPage(payload) + result = inject.checkBooleanExpression("EXISTS(SELECT CURRENT_USER FROM RDB$DATABASE)") if not result: warnMsg = "the back-end DBMS is not Firebird" diff --git a/plugins/dbms/maxdb/fingerprint.py b/plugins/dbms/maxdb/fingerprint.py index 9bc89bfc1..e053a7073 100644 --- a/plugins/dbms/maxdb/fingerprint.py +++ b/plugins/dbms/maxdb/fingerprint.py @@ -22,6 +22,7 @@ from lib.core.data import logger from lib.core.enums import DBMS from lib.core.session import setDbms from lib.core.settings import MAXDB_ALIASES +from lib.request import inject from lib.request.connect import Connect as Request from plugins.generic.fingerprint import Fingerprint as GenericFingerprint @@ -48,19 +49,13 @@ class Fingerprint(GenericFingerprint): minor, major = None, None for version in [6, 7]: - query = agent.prefixQuery("AND (SELECT MAJORVERSION FROM SYSINFO.VERSION)=%d" % version) - query = agent.suffixQuery(query) - payload = agent.payload(newValue=query) - result = Request.queryPage(payload) + result = inject.checkBooleanExpression("(SELECT MAJORVERSION FROM SYSINFO.VERSION)=%d" % version) if result: major = version for version in xrange(0, 10): - query = agent.prefixQuery("AND (SELECT MINORVERSION FROM SYSINFO.VERSION)=%d" % version) - query = agent.suffixQuery(query) - payload = agent.payload(newValue=query) - result = Request.queryPage(payload) + result = inject.checkBooleanExpression("(SELECT MINORVERSION FROM SYSINFO.VERSION)=%d" % version) if result: minor = version @@ -117,16 +112,13 @@ class Fingerprint(GenericFingerprint): logger.info(logMsg) randInt = randomInt() - - payload = agent.fullPayload("AND NOROUND(%d)=%d" % (randInt, randInt)) - result = Request.queryPage(payload) + result = inject.checkBooleanExpression("NOROUND(%d)=%d" % (randInt, randInt)) if result: logMsg = "confirming SAP MaxDB" logger.info(logMsg) - payload = agent.fullPayload("AND MAPCHAR(NULL,1,DEFAULTMAP) IS NULL") - result = Request.queryPage(payload) + result = inject.checkBooleanExpression("MAPCHAR(NULL,1,DEFAULTMAP) IS NULL") if not result: warnMsg = "the back-end DBMS is not SAP MaxDB" diff --git a/plugins/dbms/sqlite/fingerprint.py b/plugins/dbms/sqlite/fingerprint.py index 8f36a6787..567793620 100644 --- a/plugins/dbms/sqlite/fingerprint.py +++ b/plugins/dbms/sqlite/fingerprint.py @@ -80,15 +80,13 @@ class Fingerprint(GenericFingerprint): logMsg = "testing SQLite" logger.info(logMsg) - payload = agent.fullPayload("AND LAST_INSERT_ROWID()=LAST_INSERT_ROWID()") - result = Request.queryPage(payload) + result = inject.checkBooleanExpression("LAST_INSERT_ROWID()=LAST_INSERT_ROWID()") if result: logMsg = "confirming SQLite" logger.info(logMsg) - payload = agent.fullPayload("AND SQLITE_VERSION()=SQLITE_VERSION()") - result = Request.queryPage(payload) + result = inject.checkBooleanExpression("SQLITE_VERSION()=SQLITE_VERSION()") if not result: warnMsg = "the back-end DBMS is not SQLite" diff --git a/plugins/dbms/sybase/fingerprint.py b/plugins/dbms/sybase/fingerprint.py index 913d0b7ba..8b87e799a 100644 --- a/plugins/dbms/sybase/fingerprint.py +++ b/plugins/dbms/sybase/fingerprint.py @@ -81,15 +81,13 @@ class Fingerprint(GenericFingerprint): if conf.direct: result = True else: - payload = agent.fullPayload("AND tempdb_id()=tempdb_id()") - result = Request.queryPage(payload) + result = inject.checkBooleanExpression("tempdb_id()=tempdb_id()") if result: logMsg = "confirming Sybase" logger.info(logMsg) - payload = agent.fullPayload("AND suser_id()=suser_id()") - result = Request.queryPage(payload) + result = inject.checkBooleanExpression("suser_id()=suser_id()") if not result: warnMsg = "the back-end DBMS is not Sybase" @@ -105,10 +103,7 @@ class Fingerprint(GenericFingerprint): return True for version in range(12, 16): - randInt = randomInt() - query = "AND @@VERSION_NUMBER/1000=%d" % version - payload = agent.fullPayload(query) - result = Request.queryPage(payload) + result = inject.checkBooleanExpression("@@VERSION_NUMBER/1000=%d" % version) if result: kb.dbmsVersion = ["%d" % version] break