Merge branch 'master' of github.com:sqlmapproject/sqlmap

This commit is contained in:
Bernardo Damele 2013-01-09 16:04:29 +00:00
commit 7f4ce4afbb
22 changed files with 229 additions and 221 deletions

View File

@ -113,7 +113,7 @@ def _selectInjection():
if select.isdigit() and int(select) < len(kb.injections) and int(select) >= 0:
index = int(select)
elif select[0] in ( "Q", "q" ):
elif select[0] in ("Q", "q"):
raise SqlmapUserQuitException
else:
errMsg = "invalid choice"

View File

@ -855,13 +855,13 @@ class Agent(object):
else:
query = expression
if ( select and re.search("\A(COUNT|LTRIM)\(", query, re.I) ) or len(query) <= 1:
if (select and re.search("\A(COUNT|LTRIM)\(", query, re.I)) or len(query) <= 1:
return query
if selectDistinctExpr:
lengthExpr = "SELECT %s FROM (%s)" % (lengthQuery % query, expression)
if Backend.getIdentifiedDbms() in ( DBMS.MYSQL, DBMS.PGSQL ):
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL):
lengthExpr += " AS %s" % randomStr(lowercase=True)
elif select:
lengthExpr = expression.replace(query, lengthQuery % query, 1)

View File

@ -14,6 +14,7 @@ import socket
import string
import sys
import threading
import time
import urllib2
import urlparse
@ -135,7 +136,7 @@ from lib.request.httpshandler import HTTPSHandler
from lib.request.rangehandler import HTTPRangeHandler
from lib.request.redirecthandler import SmartRedirectHandler
from lib.request.templates import getPageTemplate
from lib.utils.crawler import Crawler
from lib.utils.crawler import crawl
from lib.utils.deps import checkDependencies
from lib.utils.google import Google
from thirdparty.colorama.initialise import init as coloramainit
@ -307,7 +308,7 @@ def _feedTargetsDict(reqFile, addedTargetUrls):
params = True
# Avoid proxy and connection type related headers
elif key not in ( HTTPHEADER.PROXY_CONNECTION, HTTPHEADER.CONNECTION ):
elif key not in (HTTPHEADER.PROXY_CONNECTION, HTTPHEADER.CONNECTION):
conf.httpHeaders.append((getUnicode(key), getUnicode(value)))
if getPostReq and (params or cookie):
@ -462,8 +463,7 @@ def _setCrawler():
if not conf.crawlDepth:
return
crawler = Crawler()
crawler.getTargetUrls()
crawl(conf.url)
def _setGoogleDorking():
"""
@ -571,15 +571,29 @@ def _findPageForms():
if not conf.forms or conf.crawlDepth:
return
if not checkConnection():
if conf.url and not checkConnection():
return
infoMsg = "searching for forms"
logger.info(infoMsg)
page, _ = Request.queryPage(content=True)
if not conf.bulkFile:
page, _ = Request.queryPage(content=True)
findPageForms(page, conf.url, True, True)
else:
targets = getFileItems(conf.bulkFile)
for i in xrange(len(targets)):
try:
target = targets[i]
page, _, _= Request.getPage(url=target.strip(), crawling=True, raise404=False)
findPageForms(page, target, False, True)
findPageForms(page, conf.url, True, True)
if conf.verbose in (1, 2):
status = '%d/%d links visited (%d%%)' % (i + 1, len(targets), round(100.0 * (i + 1) / len(targets)))
dataToStdout("\r[%s] [INFO] %s" % (time.strftime("%X"), status), True)
except Exception, ex:
errMsg = "problem occured while searching for forms at '%s' ('%s')" % (target, ex)
logger.error(errMsg)
def _setDBMSAuthentication():
"""
@ -1047,11 +1061,11 @@ def _setHTTPAuthentication():
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 += "Basic, Digest or NTLM"
raise SqlmapSyntaxException(errMsg)
elif aTypeLower in ( "basic", "digest" ):
elif aTypeLower in ("basic", "digest"):
regExp = "^(.*?):(.*?)$"
errMsg = "HTTP %s authentication credentials " % aTypeLower
errMsg += "value must be in format username:password"
@ -1712,8 +1726,8 @@ def _saveCmdline():
if value is None:
if datatype == "boolean":
value = "False"
elif datatype in ( "integer", "float" ):
if option in ( "threads", "verbose" ):
elif datatype in ("integer", "float"):
if option in ("threads", "verbose"):
value = "1"
elif option == "timeout":
value = "10"
@ -1836,7 +1850,7 @@ def _setTorHttpProxySettings():
found = None
for port in (DEFAULT_TOR_HTTP_PORTS if not conf.torPort else (conf.torPort, )):
for port in (DEFAULT_TOR_HTTP_PORTS if not conf.torPort else (conf.torPort,)):
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((LOCALHOST, port))
@ -1965,8 +1979,8 @@ def _basicOptionValidation():
errMsg = "maximum number of used threads is %d avoiding possible connection issues" % MAX_NUMBER_OF_THREADS
raise SqlmapSyntaxException(errMsg)
if conf.forms and not conf.url:
errMsg = "switch '--forms' requires usage of option '-u' (--url)"
if conf.forms and not any ((conf.url, conf.bulkFile)):
errMsg = "switch '--forms' requires usage of option '-u' (--url) or '-m'"
raise SqlmapSyntaxException(errMsg)
if conf.requestFile and conf.url:
@ -2009,8 +2023,8 @@ def _basicOptionValidation():
errMsg = "option '--proxy' is incompatible with switch '--ignore-proxy'"
raise SqlmapSyntaxException(errMsg)
if conf.forms and any([conf.logFile, conf.bulkFile, conf.direct, conf.requestFile, conf.googleDork]):
errMsg = "switch '--forms' is compatible only with option '-u' (--url)"
if conf.forms and any([conf.logFile, conf.direct, conf.requestFile, conf.googleDork]):
errMsg = "switch '--forms' is compatible only with options '-u' (--url) and '-m'"
raise SqlmapSyntaxException(errMsg)
if conf.timeSec < 1:

View File

@ -38,7 +38,7 @@ uses_libedit = False
if PLATFORM == 'mac' and _readline:
import commands
(status, result) = commands.getstatusoutput( "otool -L %s | grep libedit" % _readline.__file__ )
(status, result) = commands.getstatusoutput("otool -L %s | grep libedit" % _readline.__file__)
if status == 0 and len(result) > 0:
# We are bound to libedit - new in Leopard

View File

@ -131,43 +131,43 @@ PLATFORM = os.name
PYVERSION = sys.version.split()[0]
# Database management system specific variables
MSSQL_SYSTEM_DBS = ( "Northwind", "master", "model", "msdb", "pubs", "tempdb" )
MYSQL_SYSTEM_DBS = ( "information_schema", "mysql" ) # Before MySQL 5.0 only "mysql"
PGSQL_SYSTEM_DBS = ( "information_schema", "pg_catalog", "pg_toast" )
ORACLE_SYSTEM_DBS = ( "SYSTEM", "SYSAUX", "SYS" ) # These are TABLESPACE_NAME
SQLITE_SYSTEM_DBS = ( "sqlite_master", "sqlite_temp_master" )
ACCESS_SYSTEM_DBS = ( "MSysAccessObjects", "MSysACEs", "MSysObjects", "MSysQueries", "MSysRelationships", "MSysAccessStorage",\
"MSysAccessXML", "MSysModules", "MSysModules2" )
FIREBIRD_SYSTEM_DBS = ( "RDB$BACKUP_HISTORY", "RDB$CHARACTER_SETS", "RDB$CHECK_CONSTRAINTS", "RDB$COLLATIONS", "RDB$DATABASE",\
MSSQL_SYSTEM_DBS = ("Northwind", "master", "model", "msdb", "pubs", "tempdb")
MYSQL_SYSTEM_DBS = ("information_schema", "mysql") # Before MySQL 5.0 only "mysql"
PGSQL_SYSTEM_DBS = ("information_schema", "pg_catalog", "pg_toast")
ORACLE_SYSTEM_DBS = ("SYSTEM", "SYSAUX", "SYS") # These are TABLESPACE_NAME
SQLITE_SYSTEM_DBS = ("sqlite_master", "sqlite_temp_master")
ACCESS_SYSTEM_DBS = ("MSysAccessObjects", "MSysACEs", "MSysObjects", "MSysQueries", "MSysRelationships", "MSysAccessStorage",\
"MSysAccessXML", "MSysModules", "MSysModules2")
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$FORMATS", "RDB$FUNCTIONS", "RDB$FUNCTION_ARGUMENTS", "RDB$GENERATORS", "RDB$INDEX_SEGMENTS", "RDB$INDICES",\
"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$TRIGGER_MESSAGES", "RDB$TYPES", "RDB$USER_PRIVILEGES", "RDB$VIEW_RELATIONS" )
MAXDB_SYSTEM_DBS = ( "SYSINFO", "DOMAIN" )
SYBASE_SYSTEM_DBS = ( "master", "model", "sybsystemdb", "sybsystemprocs" )
DB2_SYSTEM_DBS = ( "NULLID", "SQLJ", "SYSCAT", "SYSFUN", "SYSIBM", "SYSIBMADM", "SYSIBMINTERNAL", "SYSIBMTS",\
"SYSPROC", "SYSPUBLIC", "SYSSTAT", "SYSTOOLS" )
"RDB$TRIGGER_MESSAGES", "RDB$TYPES", "RDB$USER_PRIVILEGES", "RDB$VIEW_RELATIONS")
MAXDB_SYSTEM_DBS = ("SYSINFO", "DOMAIN")
SYBASE_SYSTEM_DBS = ("master", "model", "sybsystemdb", "sybsystemprocs")
DB2_SYSTEM_DBS = ("NULLID", "SQLJ", "SYSCAT", "SYSFUN", "SYSIBM", "SYSIBMADM", "SYSIBMINTERNAL", "SYSIBMTS",\
"SYSPROC", "SYSPUBLIC", "SYSSTAT", "SYSTOOLS")
MSSQL_ALIASES = ( "microsoft sql server", "mssqlserver", "mssql", "ms" )
MYSQL_ALIASES = ( "mysql", "my" )
PGSQL_ALIASES = ( "postgresql", "postgres", "pgsql", "psql", "pg" )
ORACLE_ALIASES = ( "oracle", "orcl", "ora", "or" )
SQLITE_ALIASES = ( "sqlite", "sqlite3" )
ACCESS_ALIASES = ( "msaccess", "access", "jet", "microsoft access" )
FIREBIRD_ALIASES = ( "firebird", "mozilla firebird", "interbase", "ibase", "fb" )
MAXDB_ALIASES = ( "maxdb", "sap maxdb", "sap db" )
SYBASE_ALIASES = ( "sybase", "sybase sql server" )
DB2_ALIASES = ( "db2", "ibm db2", "ibmdb2" )
MSSQL_ALIASES = ("microsoft sql server", "mssqlserver", "mssql", "ms")
MYSQL_ALIASES = ("mysql", "my")
PGSQL_ALIASES = ("postgresql", "postgres", "pgsql", "psql", "pg")
ORACLE_ALIASES = ("oracle", "orcl", "ora", "or")
SQLITE_ALIASES = ("sqlite", "sqlite3")
ACCESS_ALIASES = ("msaccess", "access", "jet", "microsoft access")
FIREBIRD_ALIASES = ("firebird", "mozilla firebird", "interbase", "ibase", "fb")
MAXDB_ALIASES = ("maxdb", "sap maxdb", "sap db")
SYBASE_ALIASES = ("sybase", "sybase sql server")
DB2_ALIASES = ("db2", "ibm db2", "ibmdb2")
DBMS_DIRECTORY_DICT = dict((getattr(DBMS, _), getattr(DBMS_DIRECTORY_NAME, _)) for _ in dir(DBMS) if not _.startswith("_"))
SUPPORTED_DBMS = MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES + SQLITE_ALIASES + ACCESS_ALIASES + FIREBIRD_ALIASES + MAXDB_ALIASES + SYBASE_ALIASES + DB2_ALIASES
SUPPORTED_OS = ( "linux", "windows" )
SUPPORTED_OS = ("linux", "windows")
USER_AGENT_ALIASES = ( "ua", "useragent", "user-agent" )
REFERER_ALIASES = ( "ref", "referer", "referrer" )
HOST_ALIASES = ( "host", )
USER_AGENT_ALIASES = ("ua", "useragent", "user-agent")
REFERER_ALIASES = ("ref", "referer", "referrer")
HOST_ALIASES = ("host",)
# Items displayed in basic help (-h) output
BASIC_HELP_ITEMS = (

View File

@ -73,7 +73,7 @@ def smokeTest():
retVal = False
count += 1
status = '%d/%d (%d%s) ' % (count, length, round(100.0*count/length), '%')
status = '%d/%d (%d%%) ' % (count, length, round(100.0 * count / length))
dataToStdout("\r[%s] [INFO] complete: %s" % (time.strftime("%X"), status))
clearConsoleLine()

View File

@ -39,7 +39,7 @@ class MSSQLBannerHandler(ContentHandler):
def _feedInfo(self, key, value):
value = sanitizeStr(value)
if value in ( None, "None" ):
if value in (None, "None"):
return
self._info[key] = value

View File

@ -29,7 +29,7 @@ class FingerprintHandler(ContentHandler):
def _feedInfo(self, key, value):
value = sanitizeStr(value)
if value in ( None, "None" ):
if value in (None, "None"):
return
if key == "dbmsVersion":

View File

@ -41,7 +41,7 @@ class Abstraction(Web, UDF, Xp_cmdshell):
if self.webBackdoorUrl and not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED):
self.webBackdoorRunCmd(cmd)
elif Backend.getIdentifiedDbms() in ( DBMS.MYSQL, DBMS.PGSQL ):
elif Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL):
self.udfExecCmd(cmd, silent=silent)
elif Backend.isDbms(DBMS.MSSQL):
@ -57,7 +57,7 @@ class Abstraction(Web, UDF, Xp_cmdshell):
if self.webBackdoorUrl and not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED):
retVal = self.webBackdoorRunCmd(cmd)
elif Backend.getIdentifiedDbms() in ( DBMS.MYSQL, DBMS.PGSQL ):
elif Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL):
retVal = self.udfEvalCmd(cmd, first, last)
elif Backend.isDbms(DBMS.MSSQL):
@ -97,7 +97,7 @@ class Abstraction(Web, UDF, Xp_cmdshell):
logger.info(infoMsg)
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 += "user-defined functions for operating system "
infoMsg += "command execution"
@ -136,7 +136,7 @@ class Abstraction(Web, UDF, Xp_cmdshell):
if not command:
continue
if command.lower() in ( "x", "q", "exit", "quit" ):
if command.lower() in ("x", "q", "exit", "quit"):
break
self.runCmd(command)
@ -186,7 +186,7 @@ class Abstraction(Web, UDF, Xp_cmdshell):
warnMsg = "functionality requested probably does not work because "
warnMsg += "the curent session user is not a database administrator"
if not conf.dbmsCred and Backend.getIdentifiedDbms() in ( DBMS.MSSQL, DBMS.PGSQL ):
if not conf.dbmsCred and Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.PGSQL):
warnMsg += ". You can try to use option '--dbms-cred' "
warnMsg += "to execute statements as a DBA user if you "
warnMsg += "were able to extract and crack a DBA "
@ -194,7 +194,7 @@ class Abstraction(Web, UDF, Xp_cmdshell):
logger.warn(warnMsg)
if Backend.getIdentifiedDbms() in ( DBMS.MYSQL, DBMS.PGSQL ):
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL):
self.udfInjectSys()
elif Backend.isDbms(DBMS.MSSQL):
if mandatory:

View File

@ -70,52 +70,52 @@ class Metasploit:
self._msfPayloadsList = {
"windows": {
1: ( "Meterpreter (default)", "windows/meterpreter" ),
2: ( "Shell", "windows/shell" ),
3: ( "VNC", "windows/vncinject" ),
1: ("Meterpreter (default)", "windows/meterpreter"),
2: ("Shell", "windows/shell"),
3: ("VNC", "windows/vncinject"),
},
"linux": {
1: ( "Shell (default)", "linux/x86/shell" ),
2: ( "Meterpreter (beta)", "linux/x86/meterpreter" ),
1: ("Shell (default)", "linux/x86/shell"),
2: ("Meterpreter (beta)", "linux/x86/meterpreter"),
}
}
self._msfConnectionsList = {
"windows": {
1: ( "Reverse TCP: Connect back from the database host to this machine (default)", "reverse_tcp" ),
2: ( "Reverse TCP: Try to connect back from the database host to this machine, on all ports between the specified and 65535", "reverse_tcp_allports" ),
3: ( "Reverse HTTP: Connect back from the database host to this machine tunnelling traffic over HTTP", "reverse_http" ),
4: ( "Reverse HTTPS: Connect back from the database host to this machine tunnelling traffic over HTTPS", "reverse_https" ),
5: ( "Bind TCP: Listen on the database host for a connection", "bind_tcp" )
1: ("Reverse TCP: Connect back from the database host to this machine (default)", "reverse_tcp"),
2: ("Reverse TCP: Try to connect back from the database host to this machine, on all ports between the specified and 65535", "reverse_tcp_allports"),
3: ("Reverse HTTP: Connect back from the database host to this machine tunnelling traffic over HTTP", "reverse_http"),
4: ("Reverse HTTPS: Connect back from the database host to this machine tunnelling traffic over HTTPS", "reverse_https"),
5: ("Bind TCP: Listen on the database host for a connection", "bind_tcp")
},
"linux": {
1: ( "Reverse TCP: Connect back from the database host to this machine (default)", "reverse_tcp" ),
2: ( "Bind TCP: Listen on the database host for a connection", "bind_tcp" ),
1: ("Reverse TCP: Connect back from the database host to this machine (default)", "reverse_tcp"),
2: ("Bind TCP: Listen on the database host for a connection", "bind_tcp"),
}
}
self._msfEncodersList = {
"windows": {
1: ( "No Encoder", "generic/none" ),
2: ( "Alpha2 Alphanumeric Mixedcase Encoder", "x86/alpha_mixed" ),
3: ( "Alpha2 Alphanumeric Uppercase Encoder", "x86/alpha_upper" ),
4: ( "Avoid UTF8/tolower", "x86/avoid_utf8_tolower" ),
5: ( "Call+4 Dword XOR Encoder", "x86/call4_dword_xor" ),
6: ( "Single-byte XOR Countdown Encoder", "x86/countdown" ),
7: ( "Variable-length Fnstenv/mov Dword XOR Encoder", "x86/fnstenv_mov" ),
8: ( "Polymorphic Jump/Call XOR Additive Feedback Encoder", "x86/jmp_call_additive" ),
9: ( "Non-Alpha Encoder", "x86/nonalpha" ),
10: ( "Non-Upper Encoder", "x86/nonupper" ),
11: ( "Polymorphic XOR Additive Feedback Encoder (default)", "x86/shikata_ga_nai" ),
12: ( "Alpha2 Alphanumeric Unicode Mixedcase Encoder", "x86/unicode_mixed" ),
13: ( "Alpha2 Alphanumeric Unicode Uppercase Encoder", "x86/unicode_upper" ),
1: ("No Encoder", "generic/none"),
2: ("Alpha2 Alphanumeric Mixedcase Encoder", "x86/alpha_mixed"),
3: ("Alpha2 Alphanumeric Uppercase Encoder", "x86/alpha_upper"),
4: ("Avoid UTF8/tolower", "x86/avoid_utf8_tolower"),
5: ("Call+4 Dword XOR Encoder", "x86/call4_dword_xor"),
6: ("Single-byte XOR Countdown Encoder", "x86/countdown"),
7: ("Variable-length Fnstenv/mov Dword XOR Encoder", "x86/fnstenv_mov"),
8: ("Polymorphic Jump/Call XOR Additive Feedback Encoder", "x86/jmp_call_additive"),
9: ("Non-Alpha Encoder", "x86/nonalpha"),
10: ("Non-Upper Encoder", "x86/nonupper"),
11: ("Polymorphic XOR Additive Feedback Encoder (default)", "x86/shikata_ga_nai"),
12: ("Alpha2 Alphanumeric Unicode Mixedcase Encoder", "x86/unicode_mixed"),
13: ("Alpha2 Alphanumeric Unicode Uppercase Encoder", "x86/unicode_upper"),
}
}
self._msfSMBPortsList = {
"windows": {
1: ( "139/TCP", "139" ),
2: ( "445/TCP (default)", "445" ),
1: ("139/TCP", "139"),
2: ("445/TCP (default)", "445"),
}
}
@ -608,7 +608,7 @@ class Metasploit:
self._runMsfCliSmbrelay()
if Backend.getIdentifiedDbms() in ( DBMS.MYSQL, DBMS.PGSQL ):
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL):
self.uncPath = "\\\\\\\\%s\\\\%s" % (self.lhostStr, self._randFile)
else:
self.uncPath = "\\\\%s\\%s" % (self.lhostStr, self._randFile)

View File

@ -112,7 +112,7 @@ class UDF:
return output
def udfCheckNeeded(self):
if ( not conf.rFile or ( conf.rFile and not Backend.isDbms(DBMS.PGSQL) ) ) and "sys_fileread" in self.sysUdfs:
if (not conf.rFile or (conf.rFile and not Backend.isDbms(DBMS.PGSQL))) and "sys_fileread" in self.sysUdfs:
self.sysUdfs.pop("sys_fileread")
if not conf.osPwn:
@ -164,7 +164,7 @@ class UDF:
self.udfInjectCore(self.sysUdfs)
def udfInjectCustom(self):
if Backend.getIdentifiedDbms() not in ( DBMS.MYSQL, DBMS.PGSQL ):
if Backend.getIdentifiedDbms() not in (DBMS.MYSQL, DBMS.PGSQL):
errMsg = "UDF injection feature is not yet implemented on %s" % Backend.getIdentifiedDbms()
raise SqlmapUnsupportedFeatureException(errMsg)
@ -300,10 +300,10 @@ class UDF:
msg += "functions now? [Y/n/q] "
choice = readInput(msg, default="Y")
if choice[0] in ( "n", "N" ):
if choice[0] in ("n", "N"):
self.cleanup(udfDict=self.udfs)
return
elif choice[0] in ( "q", "Q" ):
elif choice[0] in ("q", "Q"):
self.cleanup(udfDict=self.udfs)
raise SqlmapUserQuitException
@ -320,7 +320,7 @@ class UDF:
while True:
choice = readInput(msg)
if choice and choice[0] in ( "q", "Q" ):
if choice and choice[0] in ("q", "Q"):
break
elif isinstance(choice, basestring) and choice.isdigit() and int(choice) > 0 and int(choice) <= len(udfList):
choice = int(choice)

View File

@ -86,20 +86,20 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
firstChar = len(partialValue)
elif "LENGTH(" in expression.upper() or "LEN(" in expression.upper():
firstChar = 0
elif dump and conf.firstChar is not None and ( isinstance(conf.firstChar, int) or ( isinstance(conf.firstChar, basestring) and conf.firstChar.isdigit() ) ):
elif dump and conf.firstChar is not None and (isinstance(conf.firstChar, int) or (isinstance(conf.firstChar, basestring) and conf.firstChar.isdigit())):
firstChar = int(conf.firstChar) - 1
elif firstChar is None:
firstChar = 0
elif ( isinstance(firstChar, basestring) and firstChar.isdigit() ) or isinstance(firstChar, int):
elif (isinstance(firstChar, basestring) and firstChar.isdigit()) or isinstance(firstChar, int):
firstChar = int(firstChar) - 1
if "LENGTH(" in expression.upper() or "LEN(" in expression.upper():
lastChar = 0
elif dump and conf.lastChar is not None and ( isinstance(conf.lastChar, int) or ( isinstance(conf.lastChar, basestring) and conf.lastChar.isdigit() ) ):
elif dump and conf.lastChar is not None and (isinstance(conf.lastChar, int) or (isinstance(conf.lastChar, basestring) and conf.lastChar.isdigit())):
lastChar = int(conf.lastChar)
elif lastChar in ( None, "0" ):
elif lastChar in (None, "0"):
lastChar = 0
elif ( isinstance(lastChar, basestring) and lastChar.isdigit() ) or isinstance(lastChar, int):
elif (isinstance(lastChar, basestring) and lastChar.isdigit()) or isinstance(lastChar, int):
lastChar = int(lastChar)
if Backend.getDbms():
@ -332,7 +332,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
return None
def etaProgressUpdate(charTime, index):
if len(progressTime) <= ( (length * 3) / 100 ):
if len(progressTime) <= ((length * 3) / 100):
eta = 0
else:
midTime = sum(progressTime) / len(progressTime)
@ -412,7 +412,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
if conf.verbose in (1, 2) and not showEta:
_ = count - firstChar
output += '_' * (min(length, conf.progressWidth) - len(output))
status = ' %d/%d (%d%s)' % (_, length, round(100.0 * _ / length), '%')
status = ' %d/%d (%d%%)' % (_, length, round(100.0 * _ / length))
output += status if _ != length else " " * len(status)
dataToStdout("\r[%s] [INFO] retrieved: %s" % (time.strftime("%X"), filterControlChars(output)))
@ -507,7 +507,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
else:
val = getChar(index, asciiTbl)
if val is None or ( lastChar > 0 and index > lastChar ):
if val is None or (lastChar > 0 and index > lastChar):
finalValue = partialValue
break
@ -545,7 +545,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
if conf.verbose in (1, 2) or showEta:
dataToStdout("\n")
if ( conf.verbose in ( 1, 2 ) and showEta ) or conf.verbose >= 3:
if (conf.verbose in (1, 2) and showEta) or conf.verbose >= 3:
infoMsg = "retrieved: %s" % filterControlChars(finalValue)
logger.info(infoMsg)

View File

@ -101,7 +101,7 @@ def tableExists(tableFile, regex=None):
dataToStdout(infoMsg, True)
if conf.verbose in (1, 2):
status = '%d/%d items (%d%s)' % (threadData.shared.count, threadData.shared.limit, round(100.0*threadData.shared.count/threadData.shared.limit), '%')
status = '%d/%d items (%d%%)' % (threadData.shared.count, threadData.shared.limit, round(100.0 * threadData.shared.count / threadData.shared.limit))
dataToStdout("\r[%s] [INFO] tried %s" % (time.strftime("%X"), status), True)
kb.locks.io.release()
@ -192,7 +192,7 @@ def columnExists(columnFile, regex=None):
dataToStdout(infoMsg, True)
if conf.verbose in (1, 2):
status = '%d/%d items (%d%s)' % (threadData.shared.count, threadData.shared.limit, round(100.0*threadData.shared.count/threadData.shared.limit), '%')
status = '%d/%d items (%d%%)' % (threadData.shared.count, threadData.shared.limit, round(100.0 * threadData.shared.count / threadData.shared.limit))
dataToStdout("\r[%s] [INFO] tried %s" % (time.strftime("%X"), status), True)
kb.locks.io.release()

View File

@ -99,7 +99,7 @@ def _oneShotErrorUse(expression, field=None):
# Parse the returned page to get the exact error-based
# SQL injection output
output = reduce(lambda x, y: x if x is not None else y, ( \
output = reduce(lambda x, y: x if x is not None else y, (\
extractRegexResult(check, page, re.DOTALL | re.IGNORECASE), \
extractRegexResult(check, listToStrValue(headers.headers \
if headers else None), re.DOTALL | re.IGNORECASE), \

View File

@ -76,7 +76,7 @@ def _oneShotUnionUse(expression, unpack=True, limited=False):
# Parse the returned page to get the exact union-based
# SQL injection output
def _(regex):
return reduce(lambda x, y: x if x is not None else y, ( \
return reduce(lambda x, y: x if x is not None else y, (\
extractRegexResult(regex, removeReflectiveValues(page, payload), re.DOTALL | re.IGNORECASE), \
extractRegexResult(regex, removeReflectiveValues(listToStrValue(headers.headers \
if headers else None), payload, True), re.DOTALL | re.IGNORECASE)), \

View File

@ -25,116 +25,110 @@ from lib.request.connect import Connect as Request
from thirdparty.beautifulsoup.beautifulsoup import BeautifulSoup
from thirdparty.oset.pyoset import oset
class Crawler(object):
"""
This class defines methods used to perform crawling (command
line option '--crawl'
"""
def crawl(target):
try:
threadData = getCurrentThreadData()
threadData.shared.value = oset()
def getTargetUrls(self):
try:
def crawlThread():
threadData = getCurrentThreadData()
threadData.shared.value = oset()
def crawlThread():
threadData = getCurrentThreadData()
while kb.threadContinue:
with kb.locks.limit:
if threadData.shared.unprocessed:
current = threadData.shared.unprocessed.pop()
else:
break
content = None
try:
if current:
content = Request.getPage(url=current, crawling=True, raise404=False)[0]
except SqlmapConnectionException, e:
errMsg = "connection exception detected (%s). skipping " % e
errMsg += "url '%s'" % current
logger.critical(errMsg)
except httplib.InvalidURL, e:
errMsg = "invalid url detected (%s). skipping " % e
errMsg += "url '%s'" % current
logger.critical(errMsg)
if not kb.threadContinue:
while kb.threadContinue:
with kb.locks.limit:
if threadData.shared.unprocessed:
current = threadData.shared.unprocessed.pop()
else:
break
if isinstance(content, unicode):
try:
match = re.search(r"(?si)<html[^>]*>(.+)</html>", content)
if match:
content = "<html>%s</html>" % match.group(1)
content = None
try:
if current:
content = Request.getPage(url=current, crawling=True, raise404=False)[0]
except SqlmapConnectionException, e:
errMsg = "connection exception detected (%s). skipping " % e
errMsg += "url '%s'" % current
logger.critical(errMsg)
except httplib.InvalidURL, e:
errMsg = "invalid url detected (%s). skipping " % e
errMsg += "url '%s'" % current
logger.critical(errMsg)
soup = BeautifulSoup(content)
tags = soup('a')
if not tags:
tags = re.finditer(r'(?si)<a[^>]+href="(?P<href>[^>"]+)"', content)
for tag in tags:
href = tag.get("href") if hasattr(tag, "get") else tag.group("href")
if href:
url = urlparse.urljoin(conf.url, href)
# flag to know if we are dealing with the same target host
_ = reduce(lambda x, y: x == y, map(lambda x: urlparse.urlparse(x).netloc.split(':')[0], (url, conf.url)))
if conf.scope:
if not re.search(conf.scope, url, re.I):
continue
elif not _:
continue
if url.split('.')[-1].lower() not in CRAWL_EXCLUDE_EXTENSIONS:
with kb.locks.value:
threadData.shared.deeper.add(url)
if re.search(r"(.*?)\?(.+)", url):
threadData.shared.value.add(url)
except UnicodeEncodeError: # for non-HTML files
pass
finally:
if conf.forms:
findPageForms(content, current, False, True)
if conf.verbose in (1, 2):
threadData.shared.count += 1
status = '%d/%d links visited (%d%s)' % (threadData.shared.count, threadData.shared.length, round(100.0*threadData.shared.count/threadData.shared.length), '%')
dataToStdout("\r[%s] [INFO] %s" % (time.strftime("%X"), status), True)
threadData.shared.deeper = set()
threadData.shared.unprocessed = set([conf.url])
logger.info("starting crawler")
for i in xrange(conf.crawlDepth):
if i > 0 and conf.threads == 1:
singleTimeWarnMessage("running in a single-thread mode. This could take a while.")
threadData.shared.count = 0
threadData.shared.length = len(threadData.shared.unprocessed)
numThreads = min(conf.threads, len(threadData.shared.unprocessed))
logger.info("searching for links with depth %d" % (i + 1))
runThreads(numThreads, crawlThread)
clearConsoleLine(True)
if threadData.shared.deeper:
threadData.shared.unprocessed = set(threadData.shared.deeper)
else:
if not kb.threadContinue:
break
except KeyboardInterrupt:
warnMsg = "user aborted during crawling. sqlmap "
warnMsg += "will use partial list"
logger.warn(warnMsg)
if isinstance(content, unicode):
try:
match = re.search(r"(?si)<html[^>]*>(.+)</html>", content)
if match:
content = "<html>%s</html>" % match.group(1)
finally:
soup = BeautifulSoup(content)
tags = soup('a')
if not tags:
tags = re.finditer(r'(?si)<a[^>]+href="(?P<href>[^>"]+)"', content)
for tag in tags:
href = tag.get("href") if hasattr(tag, "get") else tag.group("href")
if href:
url = urlparse.urljoin(target, href)
# flag to know if we are dealing with the same target host
_ = reduce(lambda x, y: x == y, map(lambda x: urlparse.urlparse(x).netloc.split(':')[0], (url, target)))
if conf.scope:
if not re.search(conf.scope, url, re.I):
continue
elif not _:
continue
if url.split('.')[-1].lower() not in CRAWL_EXCLUDE_EXTENSIONS:
with kb.locks.value:
threadData.shared.deeper.add(url)
if re.search(r"(.*?)\?(.+)", url):
threadData.shared.value.add(url)
except UnicodeEncodeError: # for non-HTML files
pass
finally:
if conf.forms:
findPageForms(content, current, False, True)
if conf.verbose in (1, 2):
threadData.shared.count += 1
status = '%d/%d links visited (%d%%)' % (threadData.shared.count, threadData.shared.length, round(100.0 * threadData.shared.count / threadData.shared.length))
dataToStdout("\r[%s] [INFO] %s" % (time.strftime("%X"), status), True)
threadData.shared.deeper = set()
threadData.shared.unprocessed = set([target])
logger.info("starting crawler")
for i in xrange(conf.crawlDepth):
if i > 0 and conf.threads == 1:
singleTimeWarnMessage("running in a single-thread mode. This could take a while.")
threadData.shared.count = 0
threadData.shared.length = len(threadData.shared.unprocessed)
numThreads = min(conf.threads, len(threadData.shared.unprocessed))
logger.info("searching for links with depth %d" % (i + 1))
runThreads(numThreads, crawlThread)
clearConsoleLine(True)
if not threadData.shared.value:
warnMsg = "no usable links found (with GET parameters)"
logger.warn(warnMsg)
if threadData.shared.deeper:
threadData.shared.unprocessed = set(threadData.shared.deeper)
else:
for url in threadData.shared.value:
kb.targets.add(( url, None, None, None ))
break
except KeyboardInterrupt:
warnMsg = "user aborted during crawling. sqlmap "
warnMsg += "will use partial list"
logger.warn(warnMsg)
finally:
clearConsoleLine(True)
if not threadData.shared.value:
warnMsg = "no usable links found (with GET parameters)"
logger.warn(warnMsg)
else:
for url in threadData.shared.value:
kb.targets.add((url, None, None, None))

View File

@ -59,7 +59,7 @@ class Enumeration(GenericEnumeration):
kb.data.cachedUsersPrivileges[user] = None
return ( kb.data.cachedUsersPrivileges, areAdmins )
return (kb.data.cachedUsersPrivileges, areAdmins)
def getTables(self):
if len(kb.data.cachedTables) > 0:

View File

@ -72,7 +72,7 @@ class Filesystem(GenericFilesystem):
logger.debug("generating chunk file %s\%s from debug script %s" % (tmpPath, chunkName, randScr))
commands = ( "cd %s" % tmpPath, "debug < %s" % randScr, "del /F /Q %s" % randScr )
commands = ("cd %s" % tmpPath, "debug < %s" % randScr, "del /F /Q %s" % randScr)
complComm = " & ".join(command for command in commands)
self.execCmd(complComm)
@ -183,9 +183,9 @@ class Filesystem(GenericFilesystem):
logger.debug("converting the file utilizing PowerShell EncodedCommand")
commands = ( "cd %s" % tmpPath,
commands = ("cd %s" % tmpPath,
"powershell -EncodedCommand %s" % psString,
"del /F /Q %s" % randFilePath )
"del /F /Q %s" % randFilePath)
complComm = " & ".join(command for command in commands)
self.execCmd(complComm)
@ -319,9 +319,9 @@ class Filesystem(GenericFilesystem):
self.xpCmdshellWriteFile(vbs, tmpPath, randVbs)
commands = ( "cd %s" % tmpPath, "cscript //nologo %s" % randVbs,
commands = ("cd %s" % tmpPath, "cscript //nologo %s" % randVbs,
"del /F /Q %s" % randVbs,
"del /F /Q %s" % randFile )
"del /F /Q %s" % randFile)
complComm = " & ".join(command for command in commands)
self.execCmd(complComm)

View File

@ -92,9 +92,9 @@ class Fingerprint(GenericFingerprint):
infoMsg = "confirming %s" % DBMS.MSSQL
logger.info(infoMsg)
for version, check in ( ("2000", "HOST_NAME()=HOST_NAME()"), \
for version, check in (("2000", "HOST_NAME()=HOST_NAME()"), \
("2005", "XACT_STATE()=XACT_STATE()"), \
("2008", "SYSDATETIME()=SYSDATETIME()") ):
("2008", "SYSDATETIME()=SYSDATETIME()")):
result = inject.checkBooleanExpression(check)
if result:

View File

@ -155,7 +155,7 @@ class Fingerprint(GenericFingerprint):
# Windows executables should always have ' Visual C++' or ' mingw'
# patterns within the banner
osWindows = ( " Visual C++", "mingw" )
osWindows = (" Visual C++", "mingw")
for osPattern in osWindows:
query = "(SELECT LENGTH(%s) FROM %s WHERE %s " % (self.tblField, self.fileTblName, self.tblField)

View File

@ -77,7 +77,7 @@ class Enumeration(GenericEnumeration):
kb.data.cachedUsersPrivileges[user] = None
return ( kb.data.cachedUsersPrivileges, areAdmins )
return (kb.data.cachedUsersPrivileges, areAdmins)
def getDbs(self):
if len(kb.data.cachedDbs) > 0:

View File

@ -94,7 +94,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
msg = "how do you want to establish the tunnel?"
msg += "\n[1] TCP: Metasploit Framework (default)"
msg += "\n[2] ICMP: icmpsh - ICMP tunneling"
valids = ( 1, 2 )
valids = (1, 2)
while True:
tunnel = readInput(msg, default=1)
@ -150,7 +150,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
errMsg += "is unlikely to receive commands sent from you"
logger.error(errMsg)
if Backend.getIdentifiedDbms() in ( DBMS.MYSQL, DBMS.PGSQL ):
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL):
self.sysUdfs.pop("sys_bineval")
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) or conf.direct:
@ -160,7 +160,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
self.initEnv(web=web)
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 += "on the back-end database underlying operating system?"
msg += "\n[1] Via UDF 'sys_bineval' (in-memory way, anti-forensics, default)"
@ -169,11 +169,11 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
while True:
choice = readInput(msg, default=1)
if isinstance(choice, basestring) and choice.isdigit() and int(choice) in ( 1, 2 ):
if isinstance(choice, basestring) and choice.isdigit() and int(choice) in (1, 2):
choice = int(choice)
break
elif isinstance(choice, int) and choice in ( 1, 2 ):
elif isinstance(choice, int) and choice in (1, 2):
break
else:
@ -251,7 +251,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
raise SqlmapUnsupportedDBMSException(errMsg)
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 += "perform the SMB relay attack if stacked "
errMsg += "queries are supported"
@ -438,7 +438,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
message += "registry path '%s\%s? [y/N] " % (regKey, regVal)
output = readInput(message, default="N")
if output and output[0] not in ( "Y", "y" ):
if output and output[0] not in ("Y", "y"):
return
infoMsg = "deleting Windows registry path '%s\%s'. " % (regKey, regVal)