mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-12-10 09:49:06 +00:00
Minor code restyling
This commit is contained in:
@@ -60,21 +60,21 @@ class Connector:
|
||||
raise sqlmapFilePathException, errMsg
|
||||
|
||||
def connect(self):
|
||||
errMsg = "'connect' method must be defined "
|
||||
errMsg = "'connect' method must be defined "
|
||||
errMsg += "into the specific DBMS plugin"
|
||||
raise sqlmapUndefinedMethod, errMsg
|
||||
|
||||
def fetchall(self):
|
||||
errMsg = "'fetchall' method must be defined "
|
||||
errMsg = "'fetchall' method must be defined "
|
||||
errMsg += "into the specific DBMS plugin"
|
||||
raise sqlmapUndefinedMethod, errMsg
|
||||
|
||||
def execute(self, query):
|
||||
errMsg = "'execute' method must be defined "
|
||||
errMsg = "'execute' method must be defined "
|
||||
errMsg += "into the specific DBMS plugin"
|
||||
raise sqlmapUndefinedMethod, errMsg
|
||||
|
||||
def select(self, query):
|
||||
errMsg = "'select' method must be defined "
|
||||
errMsg = "'select' method must be defined "
|
||||
errMsg += "into the specific DBMS plugin"
|
||||
raise sqlmapUndefinedMethod, errMsg
|
||||
|
||||
@@ -75,20 +75,20 @@ class Enumeration:
|
||||
|
||||
def __init__(self):
|
||||
kb.data.has_information_schema = False
|
||||
kb.data.banner = None
|
||||
kb.data.currentUser = ""
|
||||
kb.data.currentDb = ""
|
||||
kb.data.cachedUsers = []
|
||||
kb.data.cachedUsersPasswords = {}
|
||||
kb.data.cachedUsersPrivileges = {}
|
||||
kb.data.cachedUsersRoles = {}
|
||||
kb.data.cachedDbs = []
|
||||
kb.data.cachedTables = {}
|
||||
kb.data.cachedColumns = {}
|
||||
kb.data.cachedCounts = {}
|
||||
kb.data.dumpedTable = {}
|
||||
kb.data.processChar = None
|
||||
self.alwaysRetrieveSqlOutput = False
|
||||
kb.data.banner = None
|
||||
kb.data.currentUser = ""
|
||||
kb.data.currentDb = ""
|
||||
kb.data.cachedUsers = []
|
||||
kb.data.cachedUsersPasswords = {}
|
||||
kb.data.cachedUsersPrivileges = {}
|
||||
kb.data.cachedUsersRoles = {}
|
||||
kb.data.cachedDbs = []
|
||||
kb.data.cachedTables = {}
|
||||
kb.data.cachedColumns = {}
|
||||
kb.data.cachedCounts = {}
|
||||
kb.data.dumpedTable = {}
|
||||
kb.data.processChar = None
|
||||
self.alwaysRetrieveSqlOutput = False
|
||||
|
||||
def getBanner(self):
|
||||
if not conf.getBanner:
|
||||
@@ -164,7 +164,7 @@ class Enumeration:
|
||||
|
||||
rootQuery = queries[Backend.getIdentifiedDbms()].users
|
||||
|
||||
condition = ( Backend.getIdentifiedDbms() == DBMS.MSSQL and Backend.isVersionWithin(("2005", "2008")) )
|
||||
condition = ( Backend.getIdentifiedDbms() == DBMS.MSSQL and Backend.isVersionWithin(("2005", "2008")) )
|
||||
condition |= ( Backend.getIdentifiedDbms() == DBMS.MYSQL and not kb.data.has_information_schema )
|
||||
|
||||
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or isTechniqueAvailable(PAYLOAD.TECHNIQUE.ERROR) or conf.direct:
|
||||
@@ -319,7 +319,7 @@ class Enumeration:
|
||||
if not user or user in retrievedUsers:
|
||||
continue
|
||||
|
||||
infoMsg = "fetching number of password hashes "
|
||||
infoMsg = "fetching number of password hashes "
|
||||
infoMsg += "for user '%s'" % user
|
||||
logger.info(infoMsg)
|
||||
|
||||
@@ -330,7 +330,7 @@ class Enumeration:
|
||||
count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=2)
|
||||
|
||||
if not isNumPosStrValue(count):
|
||||
warnMsg = "unable to retrieve the number of password "
|
||||
warnMsg = "unable to retrieve the number of password "
|
||||
warnMsg += "hashes for user '%s'" % user
|
||||
logger.warn(warnMsg)
|
||||
continue
|
||||
@@ -338,7 +338,7 @@ class Enumeration:
|
||||
infoMsg = "fetching password hashes for user '%s'" % user
|
||||
logger.info(infoMsg)
|
||||
|
||||
passwords = []
|
||||
passwords = []
|
||||
|
||||
if Backend.getIdentifiedDbms() == DBMS.ORACLE:
|
||||
plusOne = True
|
||||
@@ -361,14 +361,14 @@ class Enumeration:
|
||||
if passwords:
|
||||
kb.data.cachedUsersPasswords[user] = passwords
|
||||
else:
|
||||
warnMsg = "unable to retrieve the password "
|
||||
warnMsg = "unable to retrieve the password "
|
||||
warnMsg += "hashes for user '%s'" % user
|
||||
logger.warn(warnMsg)
|
||||
|
||||
retrievedUsers.add(user)
|
||||
|
||||
if not kb.data.cachedUsersPasswords:
|
||||
errMsg = "unable to retrieve the password "
|
||||
errMsg = "unable to retrieve the password "
|
||||
errMsg += "hashes for the database users"
|
||||
raise sqlmapNoneDataException, errMsg
|
||||
|
||||
@@ -387,7 +387,7 @@ class Enumeration:
|
||||
def __isAdminFromPrivileges(self, privileges):
|
||||
# In PostgreSQL the usesuper privilege means that the
|
||||
# user is DBA
|
||||
dbaCondition = ( Backend.getIdentifiedDbms() == DBMS.PGSQL and "super" in privileges )
|
||||
dbaCondition = ( Backend.getIdentifiedDbms() == DBMS.PGSQL and "super" in privileges )
|
||||
|
||||
# In Oracle the DBA privilege means that the
|
||||
# user is DBA
|
||||
@@ -424,13 +424,13 @@ class Enumeration:
|
||||
|
||||
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or isTechniqueAvailable(PAYLOAD.TECHNIQUE.ERROR) or conf.direct:
|
||||
if Backend.getIdentifiedDbms() == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
query = rootQuery.inband.query2
|
||||
query = rootQuery.inband.query2
|
||||
condition = rootQuery.inband.condition2
|
||||
elif Backend.getIdentifiedDbms() == DBMS.ORACLE and query2:
|
||||
query = rootQuery.inband.query2
|
||||
query = rootQuery.inband.query2
|
||||
condition = rootQuery.inband.condition2
|
||||
else:
|
||||
query = rootQuery.inband.query
|
||||
query = rootQuery.inband.query
|
||||
condition = rootQuery.inband.condition
|
||||
|
||||
if conf.user:
|
||||
@@ -454,7 +454,7 @@ class Enumeration:
|
||||
|
||||
if values:
|
||||
for value in values:
|
||||
user = None
|
||||
user = None
|
||||
privileges = set()
|
||||
|
||||
for count in xrange(0, len(value)):
|
||||
@@ -528,7 +528,7 @@ class Enumeration:
|
||||
if not user or user in retrievedUsers:
|
||||
continue
|
||||
|
||||
infoMsg = "fetching number of privileges "
|
||||
infoMsg = "fetching number of privileges "
|
||||
infoMsg += "for user '%s'" % user
|
||||
logger.info(infoMsg)
|
||||
|
||||
@@ -554,7 +554,7 @@ class Enumeration:
|
||||
|
||||
return self.getPrivileges(query2=True)
|
||||
|
||||
warnMsg = "unable to retrieve the number of "
|
||||
warnMsg = "unable to retrieve the number of "
|
||||
warnMsg += "privileges for user '%s'" % user
|
||||
logger.warn(warnMsg)
|
||||
continue
|
||||
@@ -634,21 +634,21 @@ class Enumeration:
|
||||
if privileges:
|
||||
kb.data.cachedUsersPrivileges[user] = list(privileges)
|
||||
else:
|
||||
warnMsg = "unable to retrieve the privileges "
|
||||
warnMsg = "unable to retrieve the privileges "
|
||||
warnMsg += "for user '%s'" % user
|
||||
logger.warn(warnMsg)
|
||||
|
||||
retrievedUsers.add(user)
|
||||
|
||||
if not kb.data.cachedUsersPrivileges:
|
||||
errMsg = "unable to retrieve the privileges "
|
||||
errMsg = "unable to retrieve the privileges "
|
||||
errMsg += "for the database users"
|
||||
raise sqlmapNoneDataException, errMsg
|
||||
|
||||
return ( kb.data.cachedUsersPrivileges, areAdmins )
|
||||
|
||||
def getRoles(self, query2=False):
|
||||
warnMsg = "on %s the concept of roles does not " % Backend.getIdentifiedDbms()
|
||||
warnMsg = "on %s the concept of roles does not " % Backend.getIdentifiedDbms()
|
||||
warnMsg += "exist. sqlmap will enumerate privileges instead"
|
||||
logger.warn(warnMsg)
|
||||
|
||||
@@ -656,13 +656,13 @@ class Enumeration:
|
||||
|
||||
def getDbs(self):
|
||||
if Backend.getIdentifiedDbms() == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
warnMsg = "information_schema not available, "
|
||||
warnMsg = "information_schema not available, "
|
||||
warnMsg += "back-end DBMS is MySQL < 5. database "
|
||||
warnMsg += "names will be fetched from 'mysql' database"
|
||||
logger.warn(warnMsg)
|
||||
|
||||
if Backend.getIdentifiedDbms() == DBMS.ORACLE:
|
||||
warnMsg = "schema names are going to be used on Oracle "
|
||||
warnMsg = "schema names are going to be used on Oracle "
|
||||
warnMsg += "for enumeration as the counterpart to database "
|
||||
warnMsg += "names on other DBMSes"
|
||||
logger.warn(warnMsg)
|
||||
@@ -735,7 +735,7 @@ class Enumeration:
|
||||
|
||||
if bruteForce is None:
|
||||
if Backend.getIdentifiedDbms() == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
errMsg = "information_schema not available, "
|
||||
errMsg = "information_schema not available, "
|
||||
errMsg += "back-end DBMS is MySQL < 5.0"
|
||||
logger.error(errMsg)
|
||||
bruteForce = True
|
||||
@@ -747,7 +747,7 @@ class Enumeration:
|
||||
tables = None
|
||||
|
||||
if not tables:
|
||||
errMsg = "cannot retrieve table names, "
|
||||
errMsg = "cannot retrieve table names, "
|
||||
errMsg += "back-end DBMS is Access"
|
||||
logger.error(errMsg)
|
||||
bruteForce = True
|
||||
@@ -854,7 +854,7 @@ class Enumeration:
|
||||
|
||||
continue
|
||||
|
||||
infoMsg = "fetching number of tables for "
|
||||
infoMsg = "fetching number of tables for "
|
||||
infoMsg += "database '%s'" % db
|
||||
logger.info(infoMsg)
|
||||
|
||||
@@ -865,7 +865,7 @@ class Enumeration:
|
||||
count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=2)
|
||||
|
||||
if not isNumPosStrValue(count):
|
||||
warnMsg = "unable to retrieve the number of "
|
||||
warnMsg = "unable to retrieve the number of "
|
||||
warnMsg += "tables for database '%s'" % db
|
||||
logger.warn(warnMsg)
|
||||
continue
|
||||
@@ -896,7 +896,7 @@ class Enumeration:
|
||||
if tables:
|
||||
kb.data.cachedTables[db] = tables
|
||||
else:
|
||||
warnMsg = "unable to retrieve the tables "
|
||||
warnMsg = "unable to retrieve the tables "
|
||||
warnMsg += "for database '%s'" % db
|
||||
logger.warn(warnMsg)
|
||||
|
||||
@@ -940,13 +940,13 @@ class Enumeration:
|
||||
return self.getSchema()
|
||||
|
||||
if Backend.getIdentifiedDbms() == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
errMsg = "information_schema not available, "
|
||||
errMsg = "information_schema not available, "
|
||||
errMsg += "back-end DBMS is MySQL < 5.0"
|
||||
logger.error(errMsg)
|
||||
bruteForce = True
|
||||
|
||||
elif Backend.getIdentifiedDbms() == DBMS.ACCESS:
|
||||
errMsg = "cannot retrieve column names, "
|
||||
errMsg = "cannot retrieve column names, "
|
||||
errMsg += "back-end DBMS is Access"
|
||||
logger.error(errMsg)
|
||||
bruteForce = True
|
||||
@@ -1043,7 +1043,7 @@ class Enumeration:
|
||||
kb.data.cachedColumns[conf.db] = table
|
||||
|
||||
if not kb.data.cachedColumns and not conf.direct:
|
||||
infoMsg = "fetching number of columns "
|
||||
infoMsg = "fetching number of columns "
|
||||
infoMsg += "for table '%s'" % conf.tbl
|
||||
infoMsg += " on database '%s'" % conf.db
|
||||
logger.info(infoMsg)
|
||||
@@ -1074,12 +1074,12 @@ class Enumeration:
|
||||
count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=2)
|
||||
|
||||
if not isNumPosStrValue(count):
|
||||
errMsg = "unable to retrieve the number of columns "
|
||||
errMsg = "unable to retrieve the number of columns "
|
||||
errMsg += "for table '%s' " % conf.tbl
|
||||
errMsg += "on database '%s'" % conf.db
|
||||
raise sqlmapNoneDataException, errMsg
|
||||
|
||||
table = {}
|
||||
table = {}
|
||||
columns = {}
|
||||
|
||||
indexRange = getRange(count)
|
||||
@@ -1355,7 +1355,7 @@ class Enumeration:
|
||||
self.forceDbmsEnum()
|
||||
|
||||
if not conf.db:
|
||||
warnMsg = "missing database parameter, sqlmap is going to "
|
||||
warnMsg = "missing database parameter, sqlmap is going to "
|
||||
warnMsg += "use the current database to dump table "
|
||||
warnMsg += "'%s' entries" % conf.tbl
|
||||
logger.warn(warnMsg)
|
||||
@@ -1383,7 +1383,7 @@ class Enumeration:
|
||||
elif kb.data.cachedColumns and conf.db in kb.data.cachedColumns and conf.tbl in kb.data.cachedColumns[conf.db]:
|
||||
colList = kb.data.cachedColumns[conf.db][conf.tbl].keys()
|
||||
else:
|
||||
errMsg = "missing column names, "
|
||||
errMsg = "missing column names, "
|
||||
errMsg += "can't dump table"
|
||||
raise sqlmapNoneDataException, errMsg
|
||||
|
||||
@@ -1447,7 +1447,7 @@ class Enumeration:
|
||||
entries = [ entries ]
|
||||
|
||||
entriesCount = len(entries)
|
||||
index = 0
|
||||
index = 0
|
||||
|
||||
for column in colList:
|
||||
colLen = len(column)
|
||||
@@ -1591,7 +1591,7 @@ class Enumeration:
|
||||
|
||||
def dumpAll(self):
|
||||
if Backend.getIdentifiedDbms() == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
errMsg = "information_schema not available, "
|
||||
errMsg = "information_schema not available, "
|
||||
errMsg += "back-end DBMS is MySQL < 5.0"
|
||||
raise sqlmapUnsupportedFeatureException, errMsg
|
||||
|
||||
@@ -1603,9 +1603,9 @@ class Enumeration:
|
||||
infoMsg += "dump all entries of this database's tables only. "
|
||||
logger.info(infoMsg)
|
||||
|
||||
conf.tbl = None
|
||||
conf.col = None
|
||||
kb.data.cachedDbs = []
|
||||
conf.tbl = None
|
||||
conf.col = None
|
||||
kb.data.cachedDbs = []
|
||||
kb.data.cachedTables = self.getTables()
|
||||
|
||||
if kb.data.cachedTables:
|
||||
@@ -1763,7 +1763,7 @@ class Enumeration:
|
||||
count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=2)
|
||||
|
||||
if not isNumPosStrValue(count):
|
||||
warnMsg = "no database"
|
||||
warnMsg = "no database"
|
||||
if dbConsider == "1":
|
||||
warnMsg += "s like"
|
||||
warnMsg += " '%s' found" % unsafeSQLIdentificatorNaming(db)
|
||||
@@ -1792,12 +1792,12 @@ class Enumeration:
|
||||
bruteForce = False
|
||||
|
||||
if Backend.getIdentifiedDbms() == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
errMsg = "information_schema not available, "
|
||||
errMsg = "information_schema not available, "
|
||||
errMsg += "back-end DBMS is MySQL < 5.0"
|
||||
bruteForce = True
|
||||
|
||||
elif Backend.getIdentifiedDbms() == DBMS.ACCESS:
|
||||
errMsg = "cannot retrieve table names, "
|
||||
errMsg = "cannot retrieve table names, "
|
||||
errMsg += "back-end DBMS is Access"
|
||||
logger.error(errMsg)
|
||||
bruteForce = True
|
||||
@@ -1878,7 +1878,7 @@ class Enumeration:
|
||||
count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=2)
|
||||
|
||||
if not isNumPosStrValue(count):
|
||||
warnMsg = "no databases have table"
|
||||
warnMsg = "no databases have table"
|
||||
if tblConsider == "1":
|
||||
warnMsg += "s like"
|
||||
warnMsg += " '%s'" % unsafeSQLIdentificatorNaming(tbl)
|
||||
@@ -1947,12 +1947,12 @@ class Enumeration:
|
||||
bruteForce = False
|
||||
|
||||
if Backend.getIdentifiedDbms() == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
errMsg = "information_schema not available, "
|
||||
errMsg = "information_schema not available, "
|
||||
errMsg += "back-end DBMS is MySQL < 5.0"
|
||||
bruteForce = True
|
||||
|
||||
elif Backend.getIdentifiedDbms() == DBMS.ACCESS:
|
||||
errMsg = "cannot retrieve column names, "
|
||||
errMsg = "cannot retrieve column names, "
|
||||
errMsg += "back-end DBMS is Access"
|
||||
logger.error(errMsg)
|
||||
bruteForce = True
|
||||
@@ -2059,7 +2059,7 @@ class Enumeration:
|
||||
count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=2)
|
||||
|
||||
if not isNumPosStrValue(count):
|
||||
warnMsg = "no databases have tables containing column"
|
||||
warnMsg = "no databases have tables containing column"
|
||||
if colConsider == "1":
|
||||
warnMsg += "s like"
|
||||
warnMsg += " '%s'" % column
|
||||
@@ -2186,7 +2186,7 @@ class Enumeration:
|
||||
return output
|
||||
else:
|
||||
if not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) and not conf.direct:
|
||||
warnMsg = "execution of custom SQL queries is only "
|
||||
warnMsg = "execution of custom SQL queries is only "
|
||||
warnMsg += "available when stacked queries are supported"
|
||||
logger.warn(warnMsg)
|
||||
return None
|
||||
@@ -2207,7 +2207,7 @@ class Enumeration:
|
||||
return output
|
||||
|
||||
def sqlShell(self):
|
||||
infoMsg = "calling %s shell. To quit type " % Backend.getIdentifiedDbms()
|
||||
infoMsg = "calling %s shell. To quit type " % Backend.getIdentifiedDbms()
|
||||
infoMsg += "'x' or 'q' and press ENTER"
|
||||
logger.info(infoMsg)
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ class Filesystem:
|
||||
|
||||
def __init__(self):
|
||||
self.fileTblName = "sqlmapfile"
|
||||
self.tblField = "data"
|
||||
self.tblField = "data"
|
||||
|
||||
def __unbase64String(self, base64Str):
|
||||
unbase64Str = "%s\n" % base64Str.decode("base64")
|
||||
@@ -41,7 +41,7 @@ class Filesystem:
|
||||
|
||||
def __unhexString(self, hexStr):
|
||||
if len(hexStr) % 2 != 0:
|
||||
errMsg = "for some reason(s) sqlmap retrieved an odd-length "
|
||||
errMsg = "for some reason(s) sqlmap retrieved an odd-length "
|
||||
errMsg += "hexadecimal string which it is not able to convert "
|
||||
errMsg += "to raw string"
|
||||
logger.error(errMsg)
|
||||
@@ -63,9 +63,9 @@ class Filesystem:
|
||||
"""
|
||||
|
||||
fileLines = []
|
||||
fileSize = len(binaryData)
|
||||
lineAddr = 0x100
|
||||
lineLen = 20
|
||||
fileSize = len(binaryData)
|
||||
lineAddr = 0x100
|
||||
lineLen = 20
|
||||
|
||||
fileLines.append("n %s" % chunkName)
|
||||
fileLines.append("rcx")
|
||||
@@ -79,7 +79,7 @@ class Filesystem:
|
||||
strLineChar = binascii.hexlify(lineChar)
|
||||
|
||||
if not scrString:
|
||||
scrString = "e %x %s" % (lineAddr, strLineChar)
|
||||
scrString = "e %x %s" % (lineAddr, strLineChar)
|
||||
else:
|
||||
scrString += " %s" % strLineChar
|
||||
|
||||
@@ -113,7 +113,7 @@ class Filesystem:
|
||||
dFileSize = inject.getValue(lengthQuery, resumeValue=False, charsetType=2)
|
||||
|
||||
if dFileSize and dFileSize.isdigit():
|
||||
infoMsg = "the file has been successfully written and "
|
||||
infoMsg = "the file has been successfully written and "
|
||||
infoMsg += "its size is %s bytes" % dFileSize
|
||||
|
||||
dFileSize = long(dFileSize)
|
||||
@@ -126,7 +126,7 @@ class Filesystem:
|
||||
|
||||
logger.info(infoMsg)
|
||||
else:
|
||||
warnMsg = "it looks like the file has not been written, this "
|
||||
warnMsg = "it looks like the file has not been written, this "
|
||||
warnMsg += "can occur if the DBMS process' user has no write "
|
||||
warnMsg += "privileges in the destination path"
|
||||
logger.warn(warnMsg)
|
||||
@@ -137,7 +137,7 @@ class Filesystem:
|
||||
back-end DBMS underlying file system
|
||||
"""
|
||||
|
||||
counter = 0
|
||||
counter = 0
|
||||
sqlQueries = []
|
||||
|
||||
for fcEncodedLine in fcEncodedList:
|
||||
@@ -194,23 +194,23 @@ class Filesystem:
|
||||
back-end DBMS underlying file system
|
||||
"""
|
||||
|
||||
randScr = "tmpf%s.scr" % randomStr(lowercase=True)
|
||||
chunkName = randomStr(lowercase=True)
|
||||
fileScrLines = self.__binDataToScr(binaryData, chunkName)
|
||||
randScr = "tmpf%s.scr" % randomStr(lowercase=True)
|
||||
chunkName = randomStr(lowercase=True)
|
||||
fileScrLines = self.__binDataToScr(binaryData, chunkName)
|
||||
forgedScrLines = []
|
||||
cmd = ""
|
||||
charCounter = 0
|
||||
maxLen = 512
|
||||
cmd = ""
|
||||
charCounter = 0
|
||||
maxLen = 512
|
||||
|
||||
logger.debug("generating binary file %s\%s, please wait.." % (tmpPath, chunkName))
|
||||
|
||||
for scrLine in fileScrLines:
|
||||
forgedScrLine = "echo %s " % scrLine
|
||||
forgedScrLine = "echo %s " % scrLine
|
||||
forgedScrLine += ">> \"%s\%s\"" % (tmpPath, randScr)
|
||||
forgedScrLines.append(forgedScrLine)
|
||||
|
||||
for forgedScrLine in forgedScrLines:
|
||||
cmd += "%s & " % forgedScrLine
|
||||
cmd += "%s & " % forgedScrLine
|
||||
charCounter += len(forgedScrLine)
|
||||
|
||||
if charCounter >= maxLen:
|
||||
@@ -230,31 +230,31 @@ class Filesystem:
|
||||
return chunkName
|
||||
|
||||
def askCheckWrittenFile(self, wFile, dFile, fileType):
|
||||
message = "do you want confirmation that the file '%s' " % dFile
|
||||
message = "do you want confirmation that the file '%s' " % dFile
|
||||
message += "has been successfully written on the back-end DBMS "
|
||||
message += "file system? [Y/n] "
|
||||
output = readInput(message, default="Y")
|
||||
output = readInput(message, default="Y")
|
||||
|
||||
if not output or output in ("y", "Y"):
|
||||
self.__checkWrittenFile(wFile, dFile, fileType)
|
||||
|
||||
def unionReadFile(self, rFile):
|
||||
errMsg = "'unionReadFile' method must be defined "
|
||||
errMsg = "'unionReadFile' method must be defined "
|
||||
errMsg += "into the specific DBMS plugin"
|
||||
raise sqlmapUndefinedMethod, errMsg
|
||||
|
||||
def stackedReadFile(self, rFile):
|
||||
errMsg = "'stackedReadFile' method must be defined "
|
||||
errMsg = "'stackedReadFile' method must be defined "
|
||||
errMsg += "into the specific DBMS plugin"
|
||||
raise sqlmapUndefinedMethod, errMsg
|
||||
|
||||
def unionWriteFile(self, wFile, dFile, fileType, confirm=True):
|
||||
errMsg = "'unionWriteFile' method must be defined "
|
||||
errMsg = "'unionWriteFile' method must be defined "
|
||||
errMsg += "into the specific DBMS plugin"
|
||||
raise sqlmapUndefinedMethod, errMsg
|
||||
|
||||
def stackedWriteFile(self, wFile, dFile, fileType, confirm=True):
|
||||
errMsg = "'stackedWriteFile' method must be defined "
|
||||
errMsg = "'stackedWriteFile' method must be defined "
|
||||
errMsg += "into the specific DBMS plugin"
|
||||
raise sqlmapUndefinedMethod, errMsg
|
||||
|
||||
@@ -265,7 +265,7 @@ class Filesystem:
|
||||
|
||||
if conf.direct or isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED):
|
||||
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED):
|
||||
debugMsg = "going to read the file with stacked query SQL "
|
||||
debugMsg = "going to read the file with stacked query SQL "
|
||||
debugMsg += "injection technique"
|
||||
logger.debug(debugMsg)
|
||||
|
||||
@@ -312,7 +312,7 @@ class Filesystem:
|
||||
|
||||
if conf.direct or isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED):
|
||||
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED):
|
||||
debugMsg = "going to upload the %s file with " % fileType
|
||||
debugMsg = "going to upload the %s file with " % fileType
|
||||
debugMsg += "stacked query SQL injection technique"
|
||||
logger.debug(debugMsg)
|
||||
|
||||
|
||||
@@ -23,17 +23,17 @@ class Fingerprint:
|
||||
Backend.forceDbms(dbms)
|
||||
|
||||
def getFingerprint(self):
|
||||
errMsg = "'getFingerprint' method must be defined "
|
||||
errMsg = "'getFingerprint' method must be defined "
|
||||
errMsg += "into the specific DBMS plugin"
|
||||
raise sqlmapUndefinedMethod, errMsg
|
||||
|
||||
def checkDbms(self):
|
||||
errMsg = "'checkDbms' method must be defined "
|
||||
errMsg = "'checkDbms' method must be defined "
|
||||
errMsg += "into the specific DBMS plugin"
|
||||
raise sqlmapUndefinedMethod, errMsg
|
||||
|
||||
def checkDbmsOs(self, detailed=False):
|
||||
errMsg = "'checkDbmsOs' method must be defined "
|
||||
errMsg = "'checkDbmsOs' method must be defined "
|
||||
errMsg += "into the specific DBMS plugin"
|
||||
raise sqlmapUndefinedMethod, errMsg
|
||||
|
||||
|
||||
@@ -130,13 +130,13 @@ class Miscellaneous:
|
||||
|
||||
for udf, inpRet in udfDict.items():
|
||||
message = "do you want to remove UDF '%s'? [Y/n] " % udf
|
||||
output = readInput(message, default="Y")
|
||||
output = readInput(message, default="Y")
|
||||
|
||||
if not output or output in ("y", "Y"):
|
||||
dropStr = "DROP FUNCTION %s" % udf
|
||||
|
||||
if Backend.getIdentifiedDbms() == DBMS.PGSQL:
|
||||
inp = ", ".join(i for i in inpRet["input"])
|
||||
inp = ", ".join(i for i in inpRet["input"])
|
||||
dropStr += "(%s)" % inp
|
||||
|
||||
logger.debug("removing UDF '%s'" % udf)
|
||||
|
||||
@@ -19,12 +19,12 @@ class Syntax:
|
||||
|
||||
@staticmethod
|
||||
def unescape(expression, quote=True):
|
||||
errMsg = "'unescape' method must be defined "
|
||||
errMsg = "'unescape' method must be defined "
|
||||
errMsg += "into the specific DBMS plugin"
|
||||
raise sqlmapUndefinedMethod, errMsg
|
||||
|
||||
@staticmethod
|
||||
def escape(expression):
|
||||
errMsg = "'escape' method must be defined "
|
||||
errMsg = "'escape' method must be defined "
|
||||
errMsg += "into the specific DBMS plugin"
|
||||
raise sqlmapUndefinedMethod, errMsg
|
||||
|
||||
@@ -52,7 +52,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||
|
||||
web = True
|
||||
else:
|
||||
errMsg = "unable to execute operating system commands via "
|
||||
errMsg = "unable to execute operating system commands via "
|
||||
errMsg += "the back-end DBMS"
|
||||
raise sqlmapNotVulnerableException(errMsg)
|
||||
|
||||
@@ -73,7 +73,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||
|
||||
web = True
|
||||
else:
|
||||
errMsg = "unable to prompt for an interactive operating "
|
||||
errMsg = "unable to prompt for an interactive operating "
|
||||
errMsg += "system shell via the back-end DBMS because "
|
||||
errMsg += "stacked queries SQL injection is not supported"
|
||||
raise sqlmapNotVulnerableException(errMsg)
|
||||
@@ -91,7 +91,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||
|
||||
self.checkDbmsOs()
|
||||
|
||||
msg = "how do you want to establish the tunnel?"
|
||||
msg = "how do you want to establish the tunnel?"
|
||||
msg += "\n[1] TCP: Metasploit Framework (default)"
|
||||
|
||||
if Backend.isOs(OS.WINDOWS):
|
||||
@@ -129,7 +129,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||
isAdmin = runningAsAdmin()
|
||||
|
||||
if isAdmin is not True:
|
||||
errMsg = "you need to run sqlmap as an administrator "
|
||||
errMsg = "you need to run sqlmap as an administrator "
|
||||
errMsg += "if you want to establish an out-of-band ICMP "
|
||||
errMsg += "tunnel because icmpsh uses raw sockets to "
|
||||
errMsg += "sniff and craft ICMP packets"
|
||||
@@ -139,7 +139,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||
from impacket import ImpactDecoder
|
||||
from impacket import ImpactPacket
|
||||
except ImportError, _:
|
||||
errMsg = "sqlmap requires 'impacket' third-party library "
|
||||
errMsg = "sqlmap requires 'impacket' third-party library "
|
||||
errMsg += "in order to run icmpsh master. Download from "
|
||||
errMsg += "http://oss.coresecurity.com/projects/impacket.html"
|
||||
raise sqlmapMissingDependence, errMsg
|
||||
@@ -170,7 +170,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||
|
||||
if tunnel == 1:
|
||||
if Backend.getIdentifiedDbms() in ( DBMS.MYSQL, DBMS.PGSQL ):
|
||||
msg = "how do you want to execute the Metasploit shellcode "
|
||||
msg = "how do you want to execute the Metasploit shellcode "
|
||||
msg += "on the back-end database underlying operating system?"
|
||||
msg += "\n[1] Via UDF 'sys_bineval' (in-memory way, anti-forensics, default)"
|
||||
msg += "\n[2] Via shellcodeexec (file system way)"
|
||||
@@ -202,7 +202,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||
|
||||
if Backend.isOs(OS.WINDOWS) and conf.privEsc:
|
||||
if Backend.getIdentifiedDbms() == DBMS.MYSQL:
|
||||
debugMsg = "by default MySQL on Windows runs as SYSTEM "
|
||||
debugMsg = "by default MySQL on Windows runs as SYSTEM "
|
||||
debugMsg += "user, no need to privilege escalate"
|
||||
logger.debug(debugMsg)
|
||||
|
||||
@@ -211,7 +211,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||
# system is not Windows
|
||||
conf.privEsc = False
|
||||
|
||||
warnMsg = "sqlmap does not implement any operating system "
|
||||
warnMsg = "sqlmap does not implement any operating system "
|
||||
warnMsg += "user privilege escalation technique when the "
|
||||
warnMsg += "back-end DBMS underlying system is not Windows"
|
||||
logger.warn(warnMsg)
|
||||
@@ -233,7 +233,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||
# system is not Windows
|
||||
conf.privEsc = False
|
||||
|
||||
warnMsg = "sqlmap does not implement any operating system "
|
||||
warnMsg = "sqlmap does not implement any operating system "
|
||||
warnMsg += "user privilege escalation technique when the "
|
||||
warnMsg += "back-end DBMS underlying system is not Windows"
|
||||
logger.warn(warnMsg)
|
||||
@@ -262,26 +262,26 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||
self.checkDbmsOs()
|
||||
|
||||
if not Backend.isOs(OS.WINDOWS):
|
||||
errMsg = "the back-end DBMS underlying operating system is "
|
||||
errMsg = "the back-end DBMS underlying operating system is "
|
||||
errMsg += "not Windows: it is not possible to perform the SMB "
|
||||
errMsg += "relay attack"
|
||||
raise sqlmapUnsupportedDBMSException(errMsg)
|
||||
|
||||
if not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) and not conf.direct:
|
||||
if Backend.getIdentifiedDbms() in ( DBMS.PGSQL, DBMS.MSSQL ):
|
||||
errMsg = "on this back-end DBMS it is only possible to "
|
||||
errMsg = "on this back-end DBMS it is only possible to "
|
||||
errMsg += "perform the SMB relay attack if stacked "
|
||||
errMsg += "queries are supported"
|
||||
raise sqlmapUnsupportedDBMSException(errMsg)
|
||||
|
||||
elif Backend.getIdentifiedDbms() == DBMS.MYSQL:
|
||||
debugMsg = "since stacked queries are not supported, "
|
||||
debugMsg = "since stacked queries are not supported, "
|
||||
debugMsg += "sqlmap is going to perform the SMB relay "
|
||||
debugMsg += "attack via inference blind SQL injection"
|
||||
logger.debug(debugMsg)
|
||||
|
||||
printWarn = True
|
||||
warnMsg = "it is unlikely that this attack will be successful "
|
||||
warnMsg = "it is unlikely that this attack will be successful "
|
||||
|
||||
if Backend.getIdentifiedDbms() == DBMS.MYSQL:
|
||||
warnMsg += "because by default MySQL on Windows runs as "
|
||||
@@ -313,13 +313,13 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||
return
|
||||
|
||||
if not Backend.getIdentifiedDbms() == DBMS.MSSQL or not Backend.isVersionWithin(("2000", "2005")):
|
||||
errMsg = "the back-end DBMS must be Microsoft SQL Server "
|
||||
errMsg = "the back-end DBMS must be Microsoft SQL Server "
|
||||
errMsg += "2000 or 2005 to be able to exploit the heap-based "
|
||||
errMsg += "buffer overflow in the 'sp_replwritetovarbin' "
|
||||
errMsg += "stored procedure (MS09-004)"
|
||||
raise sqlmapUnsupportedDBMSException(errMsg)
|
||||
|
||||
infoMsg = "going to exploit the Microsoft SQL Server %s " % Backend.getVersion()
|
||||
infoMsg = "going to exploit the Microsoft SQL Server %s " % Backend.getVersion()
|
||||
infoMsg += "'sp_replwritetovarbin' stored procedure heap-based "
|
||||
infoMsg += "buffer overflow (MS09-004)"
|
||||
logger.info(infoMsg)
|
||||
@@ -330,7 +330,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||
self.bof()
|
||||
|
||||
def uncPathRequest(self):
|
||||
errMsg = "'uncPathRequest' method must be defined "
|
||||
errMsg = "'uncPathRequest' method must be defined "
|
||||
errMsg += "into the specific DBMS plugin"
|
||||
raise sqlmapUndefinedMethod, errMsg
|
||||
|
||||
@@ -341,7 +341,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||
self.checkDbmsOs()
|
||||
|
||||
if not Backend.isOs(OS.WINDOWS):
|
||||
errMsg = "the back-end DBMS underlying operating system is "
|
||||
errMsg = "the back-end DBMS underlying operating system is "
|
||||
errMsg += "not Windows"
|
||||
raise sqlmapUnsupportedDBMSException(errMsg)
|
||||
|
||||
@@ -353,15 +353,15 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||
|
||||
if not conf.regKey:
|
||||
default = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion"
|
||||
msg = "which registry key do you want to read? [%s] " % default
|
||||
regKey = readInput(msg, default=default)
|
||||
msg = "which registry key do you want to read? [%s] " % default
|
||||
regKey = readInput(msg, default=default)
|
||||
else:
|
||||
regKey = conf.regKey
|
||||
|
||||
if not conf.regVal:
|
||||
default = "ProductName"
|
||||
msg = "which registry key value do you want to read? [%s] " % default
|
||||
regVal = readInput(msg, default=default)
|
||||
msg = "which registry key value do you want to read? [%s] " % default
|
||||
regVal = readInput(msg, default=default)
|
||||
else:
|
||||
regVal = conf.regVal
|
||||
|
||||
@@ -376,7 +376,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||
errMsg = "missing mandatory option"
|
||||
|
||||
if not conf.regKey:
|
||||
msg = "which registry key do you want to write? "
|
||||
msg = "which registry key do you want to write? "
|
||||
regKey = readInput(msg)
|
||||
|
||||
if not regKey:
|
||||
@@ -385,7 +385,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||
regKey = conf.regKey
|
||||
|
||||
if not conf.regVal:
|
||||
msg = "which registry key value do you want to write? "
|
||||
msg = "which registry key value do you want to write? "
|
||||
regVal = readInput(msg)
|
||||
|
||||
if not regVal:
|
||||
@@ -394,7 +394,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||
regVal = conf.regVal
|
||||
|
||||
if not conf.regData:
|
||||
msg = "which registry key value data do you want to write? "
|
||||
msg = "which registry key value data do you want to write? "
|
||||
regData = readInput(msg)
|
||||
|
||||
if not regData:
|
||||
@@ -404,13 +404,13 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||
|
||||
if not conf.regType:
|
||||
default = "REG_SZ"
|
||||
msg = "which registry key value data-type is it? "
|
||||
msg += "[%s] " % default
|
||||
msg = "which registry key value data-type is it? "
|
||||
msg += "[%s] " % default
|
||||
regType = readInput(msg, default=default)
|
||||
else:
|
||||
regType = conf.regType
|
||||
|
||||
infoMsg = "adding Windows registry path '%s\%s' " % (regKey, regVal)
|
||||
infoMsg = "adding Windows registry path '%s\%s' " % (regKey, regVal)
|
||||
infoMsg += "with data '%s'. " % regData
|
||||
infoMsg += "This will work only if the user running the database "
|
||||
infoMsg += "process has privileges to modify the Windows registry."
|
||||
@@ -424,7 +424,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||
errMsg = "missing mandatory option"
|
||||
|
||||
if not conf.regKey:
|
||||
msg = "which registry key do you want to delete? "
|
||||
msg = "which registry key do you want to delete? "
|
||||
regKey = readInput(msg)
|
||||
|
||||
if not regKey:
|
||||
@@ -433,7 +433,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||
regKey = conf.regKey
|
||||
|
||||
if not conf.regVal:
|
||||
msg = "which registry key value do you want to delete? "
|
||||
msg = "which registry key value do you want to delete? "
|
||||
regVal = readInput(msg)
|
||||
|
||||
if not regVal:
|
||||
@@ -441,14 +441,14 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||
else:
|
||||
regVal = conf.regVal
|
||||
|
||||
message = "are you sure that you want to delete the Windows "
|
||||
message = "are you sure that you want to delete the Windows "
|
||||
message += "registry path '%s\%s? [y/N] " % (regKey, regVal)
|
||||
output = readInput(message, default="N")
|
||||
output = readInput(message, default="N")
|
||||
|
||||
if output and output[0] not in ( "Y", "y" ):
|
||||
return
|
||||
|
||||
infoMsg = "deleting Windows registry path '%s\%s'. " % (regKey, regVal)
|
||||
infoMsg = "deleting Windows registry path '%s\%s'. " % (regKey, regVal)
|
||||
infoMsg += "This will work only if the user running the database "
|
||||
infoMsg += "process has privileges to modify the Windows registry."
|
||||
logger.info(infoMsg)
|
||||
|
||||
Reference in New Issue
Block a user