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

This commit is contained in:
Bernardo Damele 2013-01-11 13:31:49 +00:00
commit 675e4a026b
132 changed files with 359 additions and 322 deletions

0
_sqlmap.py Executable file → Normal file
View File

View File

@ -560,6 +560,7 @@ Kyprianos Vasilopoulos, <kyprianos.vasilopoulos@gmail.com>
Vlado Velichkovski, <ketejadam@hotmail.com> Vlado Velichkovski, <ketejadam@hotmail.com>
* for reporting considerable amount of bugs * for reporting considerable amount of bugs
* for suggesting an enhancement
Johnny Venter, <johnny.venter@zoho.com> Johnny Venter, <johnny.venter@zoho.com>
* for reporting a couple of bugs * for reporting a couple of bugs

0
extra/beep/__init__.py Executable file → Normal file
View File

View File

@ -24,7 +24,7 @@ def beep():
_linux_wav_play(BEEP_WAV_FILENAME) _linux_wav_play(BEEP_WAV_FILENAME)
else: else:
_speaker_beep() _speaker_beep()
except Exception: except:
_speaker_beep() _speaker_beep()
def _speaker_beep(): def _speaker_beep():

0
extra/cloak/__init__.py Executable file → Normal file
View File

0
extra/cloak/cloak.py Executable file → Normal file
View File

0
extra/dbgtool/dbgtool.py Executable file → Normal file
View File

0
extra/icmpsh/icmpsh_m.py Executable file → Normal file
View File

0
extra/safe2bin/README.txt Executable file → Normal file
View File

0
extra/safe2bin/safe2bin.py Executable file → Normal file
View File

0
extra/shutils/pyflakes.sh Executable file → Normal file
View File

View File

@ -18,15 +18,15 @@ def check(module):
if module[-3:] == ".py": if module[-3:] == ".py":
print "CHECKING ", module print "CHECKING ", module
pout = os.popen('pylint --rcfile=/dev/null %s'% module, 'r') pout = os.popen("pylint --rcfile=/dev/null %s" % module, 'r')
for line in pout: for line in pout:
if re.match("E....:.", line): if re.match("E....:.", line):
print line print line
if __RATING__ and "Your code has been rated at" in line: if __RATING__ and "Your code has been rated at" in line:
print line print line
score = re.findall("\d.\d\d", line)[0] score = re.findall("\d.\d\d", line)[0]
total += float(score) total += float(score)
count += 1 count += 1
if __name__ == "__main__": if __name__ == "__main__":
try: try:
@ -46,5 +46,5 @@ if __name__ == "__main__":
if __RATING__: if __RATING__:
print "==" * 50 print "==" * 50
print "%d modules found"% count print "%d modules found" % count
print "AVERAGE SCORE = %.02f"% (total / count) print "AVERAGE SCORE = %.02f" % (total / count)

0
extra/sqlharvest/__init__.py Executable file → Normal file
View File

View File

@ -20,7 +20,7 @@ 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=([^"]+?)&amp;q=' REGEX_URLS = r';u=([^"]+?)&amp;q='
REGEX_RESULT = r'(?i)CREATE TABLE\s*(/\*.*\*/)?\s*(IF NOT EXISTS)?\s*(?P<result>[^\(;]+)' REGEX_RESULT = r'(?i)CREATE TABLE\s*(/\*.*\*/)?\s*(IF NOT EXISTS)?\s*(?P<result>[^\(;]+)'
@ -33,7 +33,7 @@ def main():
opener.addheaders = [("User-Agent", USER_AGENT)] opener.addheaders = [("User-Agent", USER_AGENT)]
conn = opener.open(SEARCH_URL) conn = opener.open(SEARCH_URL)
page = conn.read() #set initial cookie values page = conn.read() # set initial cookie values
config = ConfigParser.ConfigParser() config = ConfigParser.ConfigParser()
config.read(CONFIG_FILE) config.read(CONFIG_FILE)
@ -43,7 +43,7 @@ def main():
if not config.has_option("options", "index"): if not config.has_option("options", "index"):
config.set("options", "index", "0") config.set("options", "index", "0")
i = int(config.get("options", "index")) i = int(config.get("options", "index"))
try: try:
with open(TABLES_FILE, 'r') as f: with open(TABLES_FILE, 'r') as f:
@ -82,7 +82,7 @@ def main():
break break
sys.stdout.write("\n---------------\n") sys.stdout.write("\n---------------\n")
sys.stdout.write("Result page #%d\n" % (i+1)) sys.stdout.write("Result page #%d\n" % (i + 1))
sys.stdout.write("---------------\n") sys.stdout.write("---------------\n")
for sqlfile in files: for sqlfile in files:

View File

@ -294,7 +294,7 @@ def start():
if conf.forms: if conf.forms:
message = "[#%d] form:\n%s %s" % (hostCount, conf.method or HTTPMETHOD.GET, targetUrl) message = "[#%d] form:\n%s %s" % (hostCount, conf.method or HTTPMETHOD.GET, targetUrl)
else: else:
message = "url %d:\n%s %s%s" % (hostCount, conf.method or HTTPMETHOD.GET, targetUrl, " (PageRank: %s)" % get_pagerank(targetUrl) if conf.googleDork and conf.pageRank else "") message = "url %d:\n%s %s%s" % (hostCount, conf.method or HTTPMETHOD.GET, targetUrl, " (PageRank: %s)" % get_pagerank(targetUrl) if conf.googleDork and conf.pageRank else "")
if conf.cookie: if conf.cookie:
message += "\nCookie: %s" % conf.cookie message += "\nCookie: %s" % conf.cookie
@ -319,7 +319,7 @@ def start():
elif conf.method == HTTPMETHOD.GET: elif conf.method == HTTPMETHOD.GET:
if targetUrl.find("?") > -1: if targetUrl.find("?") > -1:
firstPart = targetUrl[:targetUrl.find("?")] firstPart = targetUrl[:targetUrl.find("?")]
secondPart = targetUrl[targetUrl.find("?")+1:] secondPart = targetUrl[targetUrl.find("?") + 1:]
message = "Edit GET data [default: %s]: " % secondPart message = "Edit GET data [default: %s]: " % secondPart
test = readInput(message, default=secondPart) test = readInput(message, default=secondPart)
test = _randomFillBlankFields(test) test = _randomFillBlankFields(test)
@ -603,7 +603,7 @@ def start():
showHttpErrorCodes() showHttpErrorCodes()
if kb.maxConnectionsFlag: if kb.maxConnectionsFlag:
warnMsg = "it appears that the target " warnMsg = "it appears that the target "
warnMsg += "has a maximum connections " warnMsg += "has a maximum connections "
warnMsg += "constraint" warnMsg += "constraint"
logger.warn(warnMsg) logger.warn(warnMsg)
@ -612,7 +612,7 @@ def start():
logger.info("fetched data logged to text files under '%s'" % conf.outputPath) logger.info("fetched data logged to text files under '%s'" % conf.outputPath)
if conf.multipleTargets and conf.resultsFilename: if conf.multipleTargets and conf.resultsFilename:
infoMsg = "you can find results of scanning in multiple targets " infoMsg = "you can find results of scanning in multiple targets "
infoMsg += "mode inside the CSV file '%s'" % conf.resultsFilename infoMsg += "mode inside the CSV file '%s'" % conf.resultsFilename
logger.info(infoMsg) logger.info(infoMsg)

View File

@ -56,7 +56,7 @@ def setHandler():
("Firebird", FIREBIRD_ALIASES, FirebirdMap, FirebirdConn), ("Firebird", FIREBIRD_ALIASES, FirebirdMap, FirebirdConn),
("SAP MaxDB", MAXDB_ALIASES, MaxDBMap, MaxDBConn), ("SAP MaxDB", MAXDB_ALIASES, MaxDBMap, MaxDBConn),
("Sybase", SYBASE_ALIASES, SybaseMap, SybaseConn), ("Sybase", SYBASE_ALIASES, SybaseMap, SybaseConn),
("IBM DB2", DB2_ALIASES, DB2Map, DB2Conn) ("IBM DB2", DB2_ALIASES, DB2Map, DB2Conn),
] ]
_ = max(_ if (Backend.getIdentifiedDbms() or "").lower() in _[1] else None for _ in items) _ = max(_ if (Backend.getIdentifiedDbms() or "").lower() in _[1] else None for _ in items)

View File

@ -166,9 +166,9 @@ class Agent(object):
# after the prefix or it is in GROUP BY / ORDER BY (<clause>) # after the prefix or it is in GROUP BY / ORDER BY (<clause>)
elif kb.technique == PAYLOAD.TECHNIQUE.STACKED: elif kb.technique == PAYLOAD.TECHNIQUE.STACKED:
query = kb.injection.prefix query = kb.injection.prefix
elif kb.injection.clause == [2, 3] or kb.injection.clause == [ 2 ] or kb.injection.clause == [ 3 ]: elif kb.injection.clause == [2, 3] or kb.injection.clause == [2] or kb.injection.clause == [3]:
query = kb.injection.prefix query = kb.injection.prefix
elif clause == [2, 3] or clause == [ 2 ] or clause == [ 3 ]: elif clause == [2, 3] or clause == [2] or clause == [3]:
query = prefix query = prefix
# In any other case prepend with the full prefix # In any other case prepend with the full prefix
@ -223,7 +223,7 @@ class Agent(object):
_ = ( _ = (
("[DELIMITER_START]", kb.chars.start), ("[DELIMITER_STOP]", kb.chars.stop),\ ("[DELIMITER_START]", kb.chars.start), ("[DELIMITER_STOP]", kb.chars.stop),\
("[AT_REPLACE]", kb.chars.at), ("[SPACE_REPLACE]", kb.chars.space), ("[DOLLAR_REPLACE]", kb.chars.dollar),\ ("[AT_REPLACE]", kb.chars.at), ("[SPACE_REPLACE]", kb.chars.space), ("[DOLLAR_REPLACE]", kb.chars.dollar),\
("[HASH_REPLACE]", kb.chars.hash_) ("[HASH_REPLACE]", kb.chars.hash_),
) )
payload = reduce(lambda x, y: x.replace(y[0], y[1]), _, payload) payload = reduce(lambda x, y: x.replace(y[0], y[1]), _, payload)
@ -376,7 +376,18 @@ class Agent(object):
nulledCastedConcatFields = fields nulledCastedConcatFields = fields
else: else:
fields = fields.replace(", ", ',') fields = fields.replace(", ", ',')
fieldsSplitted = fields.split(',') commas = [0, len(fields)]
depth = 0
for index in xrange(len(fields)):
char = fields[index]
if char == '(':
depth += 1
elif char == ')':
depth -= 1
elif depth == 0 and char == ',':
commas.append(index)
commas = sorted(commas)
fieldsSplitted = [fields[x:y] for (x, y) in zip(commas, commas[1:])]
dbmsDelimiter = queries[Backend.getIdentifiedDbms()].delimiter.query dbmsDelimiter = queries[Backend.getIdentifiedDbms()].delimiter.query
nulledCastedFields = [] nulledCastedFields = []
@ -758,7 +769,7 @@ class Agent(object):
limitStr = queries[Backend.getIdentifiedDbms()].limit.query limitStr = queries[Backend.getIdentifiedDbms()].limit.query
fromIndex = limitedQuery.index(" FROM ") fromIndex = limitedQuery.index(" FROM ")
untilFrom = limitedQuery[:fromIndex] untilFrom = limitedQuery[:fromIndex]
fromFrom = limitedQuery[fromIndex+1:] fromFrom = limitedQuery[fromIndex + 1:]
orderBy = False orderBy = False
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE): if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE):
@ -766,7 +777,7 @@ class Agent(object):
limitedQuery += " %s" % limitStr limitedQuery += " %s" % limitStr
elif Backend.isDbms(DBMS.FIREBIRD): elif Backend.isDbms(DBMS.FIREBIRD):
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num+1, num+1) limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num + 1, num + 1)
limitedQuery += " %s" % limitStr limitedQuery += " %s" % limitStr
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2): elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2):

View File

@ -20,7 +20,6 @@ import random
import re import re
import socket import socket
import string import string
import struct
import sys import sys
import tempfile import tempfile
import time import time
@ -561,7 +560,7 @@ def paramToDict(place, parameters=None):
elif len(conf.testParameter) != len(testableParameters.keys()): elif len(conf.testParameter) != len(testableParameters.keys()):
for parameter in conf.testParameter: for parameter in conf.testParameter:
if parameter not in testableParameters: if parameter not in testableParameters:
warnMsg = "provided parameter '%s' " % parameter warnMsg = "provided parameter '%s' " % parameter
warnMsg += "is not inside the %s" % place warnMsg += "is not inside the %s" % place
logger.warn(warnMsg) logger.warn(warnMsg)
@ -1012,8 +1011,8 @@ def parseTargetDirect():
conf.hostname = "localhost" conf.hostname = "localhost"
conf.port = 0 conf.port = 0
elif not remote: elif not remote:
errMsg = "missing remote connection details" errMsg = "missing remote connection details"
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
if dbmsName in (DBMS.MSSQL, DBMS.SYBASE): if dbmsName in (DBMS.MSSQL, DBMS.SYBASE):
import _mssql import _mssql
@ -1068,10 +1067,10 @@ def parseTargetUrl():
conf.url = conf.url.replace('?', URI_QUESTION_MARKER) conf.url = conf.url.replace('?', URI_QUESTION_MARKER)
urlSplit = urlparse.urlsplit(conf.url) urlSplit = urlparse.urlsplit(conf.url)
hostnamePort = urlSplit[1].split(":") if not re.search("\[.+\]", urlSplit[1]) else filter(None, (re.search("\[.+\]", urlSplit[1]).group(0), re.search("\](:(?P<port>\d+))?", urlSplit[1]).group("port"))) hostnamePort = urlSplit.netloc.split(":") if not re.search("\[.+\]", urlSplit.netloc) else filter(None, (re.search("\[.+\]", urlSplit.netloc).group(0), re.search("\](:(?P<port>\d+))?", urlSplit.netloc).group("port")))
conf.scheme = urlSplit[0].strip().lower() if not conf.forceSSL else "https" conf.scheme = urlSplit.scheme.strip().lower() if not conf.forceSSL else "https"
conf.path = urlSplit[2].strip() conf.path = urlSplit.path.strip()
conf.hostname = hostnamePort[0].strip() conf.hostname = hostnamePort[0].strip()
conf.ipv6 = conf.hostname != conf.hostname.strip("[]") conf.ipv6 = conf.hostname != conf.hostname.strip("[]")
@ -1097,8 +1096,8 @@ def parseTargetUrl():
else: else:
conf.port = 80 conf.port = 80
if urlSplit[3]: if urlSplit.query:
conf.parameters[PLACE.GET] = urldecode(urlSplit[3]) if urlSplit[3] and urlencode(DEFAULT_GET_POST_DELIMITER, None) not in urlSplit[3] else urlSplit[3] conf.parameters[PLACE.GET] = urldecode(urlSplit.query) if urlSplit.query and urlencode(DEFAULT_GET_POST_DELIMITER, None) not in urlSplit.query else urlSplit.query
conf.url = getUnicode("%s://%s:%d%s" % (conf.scheme, ("[%s]" % conf.hostname) if conf.ipv6 else conf.hostname, conf.port, conf.path)) conf.url = getUnicode("%s://%s:%d%s" % (conf.scheme, ("[%s]" % conf.hostname) if conf.ipv6 else conf.hostname, conf.port, conf.path))
conf.url = conf.url.replace(URI_QUESTION_MARKER, '?') conf.url = conf.url.replace(URI_QUESTION_MARKER, '?')
@ -1490,7 +1489,7 @@ def getConsoleWidth(default=80):
if os.getenv("COLUMNS", "").isdigit(): if os.getenv("COLUMNS", "").isdigit():
width = int(os.getenv("COLUMNS")) width = int(os.getenv("COLUMNS"))
else: else:
output=execute('stty size', shell=True, stdout=PIPE, stderr=PIPE).stdout.read() output = execute("stty size", shell=True, stdout=PIPE, stderr=PIPE).stdout.read()
items = output.split() items = output.split()
if len(items) == 2 and items[1].isdigit(): if len(items) == 2 and items[1].isdigit():
@ -2979,7 +2978,7 @@ def isAdminFromPrivileges(privileges):
# In Firebird there is no specific privilege that means # In Firebird there is no specific privilege that means
# that the user is DBA # that the user is DBA
# TODO: confirm # TODO: confirm
retVal |= (Backend.isDbms(DBMS.FIREBIRD) and "SELECT" in privileges and "INSERT" in privileges and "UPDATE" in privileges and "DELETE" in privileges and "REFERENCES" in privileges and "EXECUTE" in privileges) retVal |= (Backend.isDbms(DBMS.FIREBIRD) and all(_ in privileges for _ in ("SELECT", "INSERT", "UPDATE", "DELETE", "REFERENCES", "EXECUTE")))
return retVal return retVal
@ -3193,7 +3192,7 @@ def decodeHexValue(value):
try: try:
retVal = applyFunctionRecursively(value, _) retVal = applyFunctionRecursively(value, _)
except Exception: except:
singleTimeWarnMessage("there was a problem decoding value '%s' from expected hexadecimal form" % value) singleTimeWarnMessage("there was a problem decoding value '%s' from expected hexadecimal form" % value)
return retVal return retVal

View File

@ -54,8 +54,8 @@ def md5hash(value):
return md5.new(value).hexdigest() return md5.new(value).hexdigest()
def orddecode(value): def orddecode(value):
packedString = struct.pack("!"+"I" * len(value), *value) packedString = struct.pack("!" + "I" * len(value), *value)
return "".join(chr(char) for char in struct.unpack("!"+"I"*(len(packedString)/4), packedString)) return "".join(chr(char) for char in struct.unpack("!" + "I" * (len(packedString) / 4), packedString))
def ordencode(value): def ordencode(value):
return tuple(ord(char) for char in value) return tuple(ord(char) for char in value)

View File

@ -7,22 +7,22 @@ See the file 'doc/COPYING' for copying permission
from lib.core.datatype import AttribDict from lib.core.datatype import AttribDict
_defaults = { _defaults = {
"csvDel": ",", "csvDel": ",",
"timeSec": 5, "timeSec": 5,
"googlePage": 1, "googlePage": 1,
"cpuThrottle": 5, "cpuThrottle": 5,
"verbose": 1, "verbose": 1,
"delay": 0, "delay": 0,
"timeout": 30, "timeout": 30,
"retries": 3, "retries": 3,
"saFreq": 0, "saFreq": 0,
"threads": 1, "threads": 1,
"level": 1, "level": 1,
"risk": 1, "risk": 1,
"dumpFormat": "CSV", "dumpFormat": "CSV",
"tech": "BEUSTQ", "tech": "BEUSTQ",
"torType": "HTTP" "torType": "HTTP",
} }
defaults = AttribDict(_defaults) defaults = AttribDict(_defaults)

View File

@ -34,7 +34,7 @@ FIREBIRD_TYPES = {
"12": "DATE", "12": "DATE",
"13": "TIME", "13": "TIME",
"35": "TIMESTAMP", "35": "TIMESTAMP",
"37": "VARCHAR" "37": "VARCHAR",
} }
SYBASE_TYPES = { SYBASE_TYPES = {
@ -69,38 +69,38 @@ SYBASE_TYPES = {
} }
MYSQL_PRIVS = { MYSQL_PRIVS = {
1:"select_priv", 1: "select_priv",
2:"insert_priv", 2: "insert_priv",
3:"update_priv", 3: "update_priv",
4:"delete_priv", 4: "delete_priv",
5:"create_priv", 5: "create_priv",
6:"drop_priv", 6: "drop_priv",
7:"reload_priv", 7: "reload_priv",
8:"shutdown_priv", 8: "shutdown_priv",
9:"process_priv", 9: "process_priv",
10:"file_priv", 10: "file_priv",
11:"grant_priv", 11: "grant_priv",
12:"references_priv", 12: "references_priv",
13:"index_priv", 13: "index_priv",
14:"alter_priv", 14: "alter_priv",
15:"show_db_priv", 15: "show_db_priv",
16:"super_priv", 16: "super_priv",
17:"create_tmp_table_priv", 17: "create_tmp_table_priv",
18:"lock_tables_priv", 18: "lock_tables_priv",
19:"execute_priv", 19: "execute_priv",
20:"repl_slave_priv", 20: "repl_slave_priv",
21:"repl_client_priv", 21: "repl_client_priv",
22:"create_view_priv", 22: "create_view_priv",
23:"show_view_priv", 23: "show_view_priv",
24:"create_routine_priv", 24: "create_routine_priv",
25:"alter_routine_priv", 25: "alter_routine_priv",
26:"create_user_priv", 26: "create_user_priv",
} }
PGSQL_PRIVS = { PGSQL_PRIVS = {
1:"createdb", 1: "createdb",
2:"super", 2: "super",
3:"catupd", 3: "catupd",
} }
FIREBIRD_PRIVS = { FIREBIRD_PRIVS = {
@ -109,7 +109,7 @@ FIREBIRD_PRIVS = {
"U": "UPDATE", "U": "UPDATE",
"D": "DELETE", "D": "DELETE",
"R": "REFERENCES", "R": "REFERENCES",
"E": "EXECUTE" "E": "EXECUTE",
} }
DB2_PRIVS = { DB2_PRIVS = {
@ -120,7 +120,7 @@ DB2_PRIVS = {
5: "INSERTAUTH", 5: "INSERTAUTH",
6: "REFAUTH", 6: "REFAUTH",
7: "SELECTAUTH", 7: "SELECTAUTH",
8: "UPDATEAUTH" 8: "UPDATEAUTH",
} }
DUMP_REPLACEMENTS = {" ": NULL, "": BLANK} DUMP_REPLACEMENTS = {" ": NULL, "": BLANK}
@ -135,7 +135,7 @@ DBMS_DICT = {
DBMS.FIREBIRD: (FIREBIRD_ALIASES, "python-kinterbasdb", "http://kinterbasdb.sourceforge.net/"), DBMS.FIREBIRD: (FIREBIRD_ALIASES, "python-kinterbasdb", "http://kinterbasdb.sourceforge.net/"),
DBMS.MAXDB: (MAXDB_ALIASES, None, None), DBMS.MAXDB: (MAXDB_ALIASES, None, None),
DBMS.SYBASE: (SYBASE_ALIASES, "python-pymssql", "http://pymssql.sourceforge.net/"), DBMS.SYBASE: (SYBASE_ALIASES, "python-pymssql", "http://pymssql.sourceforge.net/"),
DBMS.DB2: (DB2_ALIASES, "python ibm-db", "http://code.google.com/p/ibm-db/") DBMS.DB2: (DB2_ALIASES, "python ibm-db", "http://code.google.com/p/ibm-db/"),
} }
FROM_DUMMY_TABLE = { FROM_DUMMY_TABLE = {
@ -143,11 +143,11 @@ FROM_DUMMY_TABLE = {
DBMS.ACCESS: " FROM MSysAccessObjects", DBMS.ACCESS: " FROM MSysAccessObjects",
DBMS.FIREBIRD: " FROM RDB$DATABASE", DBMS.FIREBIRD: " FROM RDB$DATABASE",
DBMS.MAXDB: " FROM VERSIONS", DBMS.MAXDB: " FROM VERSIONS",
DBMS.DB2: " FROM SYSIBM.SYSDUMMY1" DBMS.DB2: " FROM SYSIBM.SYSDUMMY1",
} }
SQL_STATEMENTS = { SQL_STATEMENTS = {
"SQL SELECT statement": ( "SQL SELECT statement": (
"select ", "select ",
"show ", "show ",
" top ", " top ",
@ -162,44 +162,46 @@ SQL_STATEMENTS = {
" offset ", " offset ",
" union all ", " union all ",
" rownum as ", " rownum as ",
"(case ", ), "(case ", ),
"SQL data definition": ( "SQL data definition": (
"create ", "create ",
"declare ", "declare ",
"drop ", "drop ",
"truncate ", "truncate ",
"alter ", ), "alter ", ),
"SQL data manipulation": ( "SQL data manipulation": (
"bulk ", "bulk ",
"insert ", "insert ",
"update ", "update ",
"delete ", "delete ",
"merge ", "merge ",
"load ", ), "load ", ),
"SQL data control": ( "SQL data control": (
"grant ", "grant ",
"revoke ", ), "revoke ", ),
"SQL data execution": ( "SQL data execution": (
"exec ", "exec ",
"execute ", ), "execute ", ),
"SQL transaction": ( "SQL transaction": (
"start transaction ", "start transaction ",
"begin work ", "begin work ",
"begin transaction ", "begin transaction ",
"commit ", "commit ",
"rollback ", ), "rollback ", ),
} }
POST_HINT_CONTENT_TYPES = { POST_HINT_CONTENT_TYPES = {
POST_HINT.JSON: "application/json", POST_HINT.JSON: "application/json",
POST_HINT.MULTIPART: "multipart/form-data", POST_HINT.MULTIPART: "multipart/form-data",
POST_HINT.SOAP: "application/soap+xml", POST_HINT.SOAP: "application/soap+xml",
POST_HINT.XML: "application/xml" POST_HINT.XML: "application/xml",
} }
DEPRECATED_HINTS = {"--replicate": "use '--dump-format=SQLITE' instead"} DEPRECATED_HINTS = {
"--replicate": "use '--dump-format=SQLITE' instead",
}

View File

@ -119,13 +119,13 @@ class Dump(object):
if elements: if elements:
self._write("") self._write("")
def banner(self,data): def banner(self, data):
self.string("banner", data) self.string("banner", data)
def currentUser(self,data): def currentUser(self, data):
self.string("current user", data) self.string("current user", data)
def currentDb(self,data): def currentDb(self, data):
if Backend.isDbms(DBMS.MAXDB): if Backend.isDbms(DBMS.MAXDB):
self.string("current database (no practical usage on %s)" % Backend.getIdentifiedDbms(), data) self.string("current database (no practical usage on %s)" % Backend.getIdentifiedDbms(), data)
elif Backend.isDbms(DBMS.ORACLE): elif Backend.isDbms(DBMS.ORACLE):
@ -133,13 +133,13 @@ class Dump(object):
else: else:
self.string("current database", data) self.string("current database", data)
def hostname(self,data): def hostname(self, data):
self.string("hostname", data) self.string("hostname", data)
def dba(self,data): def dba(self, data):
self.string("current user is DBA", data) self.string("current user is DBA", data)
def users(self,users): def users(self, users):
self.lister("database management system users", users) self.lister("database management system users", users)
def userSettings(self, header, userSettings, subHeader): def userSettings(self, header, userSettings, subHeader):
@ -176,7 +176,7 @@ class Dump(object):
self.singleString("") self.singleString("")
def dbs(self,dbs): def dbs(self, dbs):
self.lister("available databases", dbs) self.lister("available databases", dbs)
def dbTables(self, dbTables): def dbTables(self, dbTables):
@ -329,7 +329,6 @@ class Dump(object):
def dbTableValues(self, tableValues): def dbTableValues(self, tableValues):
replication = None replication = None
rtable = None rtable = None
documentNode, tableNode, bodyNode, headNode, rowNode = (0,) * 5
dumpFP = None dumpFP = None
if tableValues is None: if tableValues is None:

View File

@ -178,7 +178,7 @@ class PAYLOAD:
3: "UNION query", 3: "UNION query",
4: "stacked queries", 4: "stacked queries",
5: "AND/OR time-based blind", 5: "AND/OR time-based blind",
6: "inline query" 6: "inline query",
} }
PARAMETER = { PARAMETER = {
@ -186,14 +186,14 @@ class PAYLOAD:
2: "Single quoted string", 2: "Single quoted string",
3: "LIKE single quoted string", 3: "LIKE single quoted string",
4: "Double quoted string", 4: "Double quoted string",
5: "LIKE double quoted string" 5: "LIKE double quoted string",
} }
RISK = { RISK = {
0: "No risk", 0: "No risk",
1: "Low risk", 1: "Low risk",
2: "Medium risk", 2: "Medium risk",
3: "High risk" 3: "High risk",
} }
CLAUSE = { CLAUSE = {
@ -205,7 +205,7 @@ class PAYLOAD:
5: "OFFSET", 5: "OFFSET",
6: "TOP", 6: "TOP",
7: "Table name", 7: "Table name",
8: "Column name" 8: "Column name",
} }
class METHOD: class METHOD:

View File

@ -244,7 +244,7 @@ def _feedTargetsDict(reqFile, addedTargetUrls):
else: else:
scheme, port = None, None scheme, port = None, None
if not re.search (r"^[\n]*(GET|POST).*?\sHTTP\/", request, re.I | re.M): if not re.search(r"^[\n]*(GET|POST).*?\sHTTP\/", request, re.I | re.M):
continue continue
if re.search(r"^[\n]*(GET|POST).*?\.(%s)\sHTTP\/" % "|".join(CRAWL_EXCLUDE_EXTENSIONS), request, re.I | re.M): if re.search(r"^[\n]*(GET|POST).*?\.(%s)\sHTTP\/" % "|".join(CRAWL_EXCLUDE_EXTENSIONS), request, re.I | re.M):
@ -272,7 +272,7 @@ def _feedTargetsDict(reqFile, addedTargetUrls):
index = 5 index = 5
url = line[index:line.index(" HTTP/")] url = line[index:line.index(" HTTP/")]
method = line[:index-1] method = line[:index - 1]
if "?" in line and "=" in line: if "?" in line and "=" in line:
params = True params = True
@ -353,6 +353,7 @@ def _loadQueries():
class DictObject(object): class DictObject(object):
def __init__(self): def __init__(self):
self.__dict__ = {} self.__dict__ = {}
def __contains__(self, name): def __contains__(self, name):
return name in self.__dict__ return name in self.__dict__
@ -486,7 +487,7 @@ def _setGoogleDorking():
infoMsg = "first request to Google to get the session cookie" infoMsg = "first request to Google to get the session cookie"
logger.info(infoMsg) logger.info(infoMsg)
handlers = [ proxyHandler ] handlers = [proxyHandler]
# Reference: http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html # Reference: http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html
if conf.keepAlive: if conf.keepAlive:
@ -587,7 +588,7 @@ def _findPageForms():
for i in xrange(len(targets)): for i in xrange(len(targets)):
try: try:
target = targets[i] target = targets[i]
page, _, _= Request.getPage(url=target.strip(), crawling=True, raise404=False) page, _, _ = Request.getPage(url=target.strip(), crawling=True, raise404=False)
findPageForms(page, target, False, True) findPageForms(page, target, False, True)
if conf.verbose in (1, 2): if conf.verbose in (1, 2):
@ -638,7 +639,7 @@ def _setMetasploit():
_ = ConnectRegistry(None, HKEY_LOCAL_MACHINE) _ = ConnectRegistry(None, HKEY_LOCAL_MACHINE)
_ = OpenKey(_, key) _ = OpenKey(_, key)
retVal = QueryValueEx(_, value)[0] retVal = QueryValueEx(_, value)[0]
except Exception: except:
logger.debug("unable to identify Metasploit installation path via registry key") logger.debug("unable to identify Metasploit installation path via registry key")
return retVal return retVal
@ -749,7 +750,7 @@ def _setOS():
def _setTechnique(): def _setTechnique():
validTechniques = sorted(getPublicTypeMembers(PAYLOAD.TECHNIQUE), key=lambda x: x[1]) validTechniques = sorted(getPublicTypeMembers(PAYLOAD.TECHNIQUE), key=lambda x: x[1])
validLetters = map(lambda x: x[0][0].upper(), validTechniques) validLetters = [_[0][0].upper() for _ in validTechniques]
if conf.tech and isinstance(conf.tech, basestring): if conf.tech and isinstance(conf.tech, basestring):
_ = [] _ = []
@ -930,9 +931,9 @@ def _setHTTPProxy():
logger.debug(debugMsg) logger.debug(debugMsg)
proxySplit = urlparse.urlsplit(conf.proxy) proxySplit = urlparse.urlsplit(conf.proxy)
hostnamePort = proxySplit[1].split(":") hostnamePort = proxySplit.netloc.split(":")
scheme = proxySplit[0].upper() scheme = proxySplit.scheme.upper()
hostname = hostnamePort[0] hostname = hostnamePort[0]
port = None port = None
username = None username = None
@ -942,7 +943,7 @@ def _setHTTPProxy():
try: try:
port = int(hostnamePort[1]) port = int(hostnamePort[1])
except: except:
pass #drops into the next check block pass # drops into the next check block
if not all((scheme, hasattr(PROXY_TYPE, scheme), hostname, port)): if not all((scheme, hasattr(PROXY_TYPE, scheme), hostname, port)):
errMsg = "proxy value must be in format '(%s)://url:port'" % "|".join(_[0].lower() for _ in getPublicTypeMembers(PROXY_TYPE)) errMsg = "proxy value must be in format '(%s)://url:port'" % "|".join(_[0].lower() for _ in getPublicTypeMembers(PROXY_TYPE))
@ -1005,8 +1006,8 @@ def _setPrefixSuffix():
boundary = AttribDict() boundary = AttribDict()
boundary.level = 1 boundary.level = 1
boundary.clause = [ 0 ] boundary.clause = [0]
boundary.where = [ 1, 2, 3 ] boundary.where = [1, 2, 3]
boundary.prefix = conf.prefix boundary.prefix = conf.prefix
boundary.suffix = conf.suffix boundary.suffix = conf.suffix
@ -1024,7 +1025,7 @@ def _setPrefixSuffix():
# user who provides --prefix/--suffix does not want other boundaries # user who provides --prefix/--suffix does not want other boundaries
# to be tested for # to be tested for
conf.boundaries = [ boundary ] conf.boundaries = [boundary]
def _setAuthCred(): def _setAuthCred():
""" """
@ -1247,7 +1248,7 @@ def _setHTTPUserAgent():
if count == 1: if count == 1:
userAgent = kb.userAgents[0] userAgent = kb.userAgents[0]
else: else:
userAgent = kb.userAgents[randomRange(stop=count-1)] userAgent = kb.userAgents[randomRange(stop=count - 1)]
userAgent = sanitizeStr(userAgent) userAgent = sanitizeStr(userAgent)
conf.httpHeaders.append((HTTPHEADER.USER_AGENT, userAgent)) conf.httpHeaders.append((HTTPHEADER.USER_AGENT, userAgent))
@ -1373,8 +1374,9 @@ def _cleanupOptions():
conf.data = re.sub(INJECT_HERE_MARK.replace(" ", r"[^A-Za-z]*"), CUSTOM_INJECTION_MARK_CHAR, conf.data, re.I) conf.data = re.sub(INJECT_HERE_MARK.replace(" ", r"[^A-Za-z]*"), CUSTOM_INJECTION_MARK_CHAR, conf.data, re.I)
if re.search(r'%[0-9a-f]{2}', conf.data, re.I): if re.search(r'%[0-9a-f]{2}', conf.data, re.I):
class _(unicode):
pass
original = conf.data original = conf.data
class _(unicode): pass
conf.data = _(urldecode(conf.data)) conf.data = _(urldecode(conf.data))
setattr(conf.data, UNENCODED_ORIGINAL_VALUE, original) setattr(conf.data, UNENCODED_ORIGINAL_VALUE, original)
else: else:
@ -1409,7 +1411,7 @@ def _cleanupOptions():
conf.code = int(conf.code) conf.code = int(conf.code)
if conf.csvDel: if conf.csvDel:
conf.csvDel = conf.csvDel.decode("string_escape") # e.g. '\\t' -> '\t' conf.csvDel = conf.csvDel.decode("string_escape") # e.g. '\\t' -> '\t'
if conf.torPort and conf.torPort.isdigit(): if conf.torPort and conf.torPort.isdigit():
conf.torPort = int(conf.torPort) conf.torPort = int(conf.torPort)
@ -1504,7 +1506,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.authHeader = None kb.authHeader = None
kb.bannerFp = AttribDict() kb.bannerFp = AttribDict()
kb.brute = AttribDict({"tables":[], "columns":[]}) kb.brute = AttribDict({"tables": [], "columns": []})
kb.bruteMode = False kb.bruteMode = False
kb.cache = AttribDict() kb.cache = AttribDict()
@ -1525,7 +1527,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
# 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
@ -1592,7 +1594,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.redirectChoice = None kb.redirectChoice = None
kb.redirectSetCookie = None kb.redirectSetCookie = None
kb.reflectiveMechanism = True kb.reflectiveMechanism = True
kb.reflectiveCounters = {REFLECTIVE_COUNTER.MISS:0, REFLECTIVE_COUNTER.HIT:0} kb.reflectiveCounters = {REFLECTIVE_COUNTER.MISS: 0, REFLECTIVE_COUNTER.HIT: 0}
kb.responseTimes = [] kb.responseTimes = []
kb.resumeValues = True kb.resumeValues = True
kb.safeCharEncode = False kb.safeCharEncode = False
@ -1820,7 +1822,7 @@ class LogRecorder(logging.StreamHandler):
""" """
self.loghist.append({'levelname': record.levelname, self.loghist.append({'levelname': record.levelname,
'text': record.msg % record.args if record.args else record.msg, 'text': record.msg % record.args if record.args else record.msg,
'id': len(self.loghist)+1}) 'id': len(self.loghist) + 1})
if conf.fdLog: if conf.fdLog:
# TODO: this is very heavy operation and slows down a lot the # TODO: this is very heavy operation and slows down a lot the
@ -2008,7 +2010,7 @@ def _basicOptionValidation():
errMsg = "maximum number of used threads is %d avoiding possible connection issues" % MAX_NUMBER_OF_THREADS errMsg = "maximum number of used threads is %d avoiding possible connection issues" % MAX_NUMBER_OF_THREADS
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
if conf.forms and not any ((conf.url, conf.bulkFile)): if conf.forms and not any((conf.url, conf.bulkFile)):
errMsg = "switch '--forms' requires usage of option '-u' (--url) or '-m'" errMsg = "switch '--forms' requires usage of option '-u' (--url) or '-m'"
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)

View File

@ -18,7 +18,7 @@ optDict = {
"requestFile": "string", "requestFile": "string",
"sessionFile": "string", "sessionFile": "string",
"googleDork": "string", "googleDork": "string",
"configFile": "string" "configFile": "string",
}, },
"Request": { "Request": {
@ -47,7 +47,7 @@ optDict = {
"safUrl": "string", "safUrl": "string",
"saFreq": "integer", "saFreq": "integer",
"skipUrlEncode": "boolean", "skipUrlEncode": "boolean",
"evalCode": "string" "evalCode": "string",
}, },
"Optimization": { "Optimization": {
@ -55,7 +55,7 @@ optDict = {
"predictOutput": "boolean", "predictOutput": "boolean",
"keepAlive": "boolean", "keepAlive": "boolean",
"nullConnection": "boolean", "nullConnection": "boolean",
"threads": "integer" "threads": "integer",
}, },
"Injection": { "Injection": {
@ -69,7 +69,7 @@ optDict = {
"prefix": "string", "prefix": "string",
"suffix": "string", "suffix": "string",
"skip": "string", "skip": "string",
"tamper": "string" "tamper": "string",
}, },
"Detection": { "Detection": {
@ -80,7 +80,7 @@ optDict = {
"regexp": "string", "regexp": "string",
"code": "integer", "code": "integer",
"textOnly": "boolean", "textOnly": "boolean",
"titles": "boolean" "titles": "boolean",
}, },
"Techniques": { "Techniques": {
@ -89,11 +89,11 @@ optDict = {
"uCols": "string", "uCols": "string",
"uChar": "string", "uChar": "string",
"dnsName": "string", "dnsName": "string",
"secondOrder": "string" "secondOrder": "string",
}, },
"Fingerprint": { "Fingerprint": {
"extensiveFp": "boolean" "extensiveFp": "boolean",
}, },
"Enumeration": { "Enumeration": {
@ -126,23 +126,23 @@ optDict = {
"lastChar": "integer", "lastChar": "integer",
"query": "string", "query": "string",
"sqlShell": "boolean", "sqlShell": "boolean",
"sqlFile": "string" "sqlFile": "string",
}, },
"Brute": { "Brute": {
"commonTables": "boolean", "commonTables": "boolean",
"commonColumns": "boolean" "commonColumns": "boolean",
}, },
"User-defined function": { "User-defined function": {
"udfInject": "boolean", "udfInject": "boolean",
"shLib": "string" "shLib": "string",
}, },
"File system": { "File system": {
"rFile": "string", "rFile": "string",
"wFile": "string", "wFile": "string",
"dFile": "string" "dFile": "string",
}, },
"Takeover": { "Takeover": {
@ -153,7 +153,7 @@ optDict = {
"osBof": "boolean", "osBof": "boolean",
"privEsc": "boolean", "privEsc": "boolean",
"msfPath": "string", "msfPath": "string",
"tmpPath": "string" "tmpPath": "string",
}, },
"Windows": { "Windows": {
@ -163,7 +163,7 @@ optDict = {
"regKey": "string", "regKey": "string",
"regVal": "string", "regVal": "string",
"regData": "string", "regData": "string",
"regType": "string" "regType": "string",
}, },
"General": { "General": {
@ -208,7 +208,7 @@ optDict = {
"smart": "boolean", "smart": "boolean",
"testFilter": "string", "testFilter": "string",
"wizard": "boolean", "wizard": "boolean",
"verbose": "integer" "verbose": "integer",
}, },
"Hidden": { "Hidden": {
"profile": "boolean", "profile": "boolean",
@ -217,6 +217,6 @@ optDict = {
"smokeTest": "boolean", "smokeTest": "boolean",
"liveTest": "boolean", "liveTest": "boolean",
"stopFail": "boolean", "stopFail": "boolean",
"runCase": "string" "runCase": "string",
} }
} }

View File

@ -65,7 +65,7 @@ def profile(profileOutputFile=None, dotOutputFile=None, imageOutputFile=None):
dotFilePointer = codecs.open(dotOutputFile, 'wt', UNICODE_ENCODING) dotFilePointer = codecs.open(dotOutputFile, 'wt', UNICODE_ENCODING)
parser = gprof2dot.PstatsParser(profileOutputFile) parser = gprof2dot.PstatsParser(profileOutputFile)
profile = parser.parse() profile = parser.parse()
profile.prune(0.5/100.0, 0.1/100.0) profile.prune(0.5 / 100.0, 0.1 / 100.0)
dot = gprof2dot.DotWriter(dotFilePointer) dot = gprof2dot.DotWriter(dotFilePointer)
dot.graph(profile, gprof2dot.TEMPERATURE_COLORMAP) dot.graph(profile, gprof2dot.TEMPERATURE_COLORMAP)
dotFilePointer.close() dotFilePointer.close()

View File

@ -64,7 +64,7 @@ def purge(directory):
except: except:
pass pass
dirpaths.sort(cmp = lambda x, y: y.count(os.path.sep) - x.count(os.path.sep)) dirpaths.sort(cmp=lambda x, y: y.count(os.path.sep) - x.count(os.path.sep))
logger.debug("renaming directory names to random values...") logger.debug("renaming directory names to random values...")
for dirpath in dirpaths: for dirpath in dirpaths:

View File

@ -61,7 +61,7 @@ class Replication(object):
""" """
if len(values) == len(self.columns): if len(values) == len(self.columns):
self.execute('INSERT INTO "%s" VALUES (%s)' % (self.name, ','.join(['?']*len(values))), safechardecode(values)) self.execute('INSERT INTO "%s" VALUES (%s)' % (self.name, ','.join(['?'] * len(values))), safechardecode(values))
else: else:
errMsg = "wrong number of columns used in replicating insert" errMsg = "wrong number of columns used in replicating insert"
raise SqlmapValueException(errMsg) raise SqlmapValueException(errMsg)

View File

@ -201,7 +201,7 @@ BASIC_HELP_ITEMS = (
"checkTor", "checkTor",
"flushSession", "flushSession",
"tor", "tor",
"wizard" "wizard",
) )
# String representation for NULL value # String representation for NULL value
@ -218,7 +218,7 @@ ERROR_PARSING_REGEXES = (
r"<b>[^<]*(fatal|error|warning|exception)[^<]*</b>:?\s*(?P<result>.+?)<br\s*/?\s*>", r"<b>[^<]*(fatal|error|warning|exception)[^<]*</b>:?\s*(?P<result>.+?)<br\s*/?\s*>",
r"(?m)^(fatal|error|warning|exception):?\s*(?P<result>.+?)$", r"(?m)^(fatal|error|warning|exception):?\s*(?P<result>.+?)$",
r"<li>Error Type:<br>(?P<result>.+?)</li>", r"<li>Error Type:<br>(?P<result>.+?)</li>",
r"error '[0-9a-f]{8}'((<[^>]+>)|\s)+(?P<result>[^<>]+)" r"error '[0-9a-f]{8}'((<[^>]+>)|\s)+(?P<result>[^<>]+)",
) )
# Regular expression used for parsing charset info from meta html headers # Regular expression used for parsing charset info from meta html headers
@ -234,7 +234,7 @@ EMPTY_FORM_FIELDS_REGEX = r'(&|\A)(?P<result>[^=]+=(&|\Z))'
COMMON_PASSWORD_SUFFIXES = ("1", "123", "2", "12", "3", "13", "7", "11", "5", "22", "23", "01", "4", "07", "21", "14", "10", "06", "08", "8", "15", "69", "16", "6", "18") COMMON_PASSWORD_SUFFIXES = ("1", "123", "2", "12", "3", "13", "7", "11", "5", "22", "23", "01", "4", "07", "21", "14", "10", "06", "08", "8", "15", "69", "16", "6", "18")
# Reference: http://www.the-interweb.com/serendipity/index.php?/archives/94-A-brief-analysis-of-40,000-leaked-MySpace-passwords.html # Reference: http://www.the-interweb.com/serendipity/index.php?/archives/94-A-brief-analysis-of-40,000-leaked-MySpace-passwords.html
COMMON_PASSWORD_SUFFIXES += ("!", ".", "*", "!!", "?", ";", "..", "!!!", ",", "@") COMMON_PASSWORD_SUFFIXES += ("!", ".", "*", "!!", "?", ";", "..", "!!!", ", ", "@")
# Splitter used between requests in WebScarab log files # Splitter used between requests in WebScarab log files
WEBSCARAB_SPLITTER = "### Conversation" WEBSCARAB_SPLITTER = "### Conversation"
@ -363,7 +363,7 @@ DUMMY_SQL_INJECTION_CHARS = ";()'"
DUMMY_USER_INJECTION = r"(?i)[^\w](AND|OR)\s+[^\s]+[=><]" DUMMY_USER_INJECTION = r"(?i)[^\w](AND|OR)\s+[^\s]+[=><]"
# Extensions skipped by crawler # Extensions skipped by crawler
CRAWL_EXCLUDE_EXTENSIONS = ("gif","jpg","jar","tif","bmp","war","ear","mpg","wmv","mpeg","scm","iso","dmp","dll","cab","so","avi","bin","exe","iso","tar","png","pdf","ps","mp3","zip","rar","gz") CRAWL_EXCLUDE_EXTENSIONS = ("gif", "jpg", "jar", "tif", "bmp", "war", "ear", "mpg", "wmv", "mpeg", "scm", "iso", "dmp", "dll", "cab", "so", "avi", "bin", "exe", "iso", "tar", "png", "pdf", "ps", "mp3", "zip", "rar", "gz")
# Template used for common table existence check # Template used for common table existence check
BRUTE_TABLE_EXISTS_TEMPLATE = "EXISTS(SELECT %d FROM %s)" BRUTE_TABLE_EXISTS_TEMPLATE = "EXISTS(SELECT %d FROM %s)"
@ -420,7 +420,7 @@ HASHDB_FLUSH_RETRIES = 3
HASHDB_MILESTONE_VALUE = "cAWxkLYCQT" # r5129 "".join(random.sample(string.letters, 10)) HASHDB_MILESTONE_VALUE = "cAWxkLYCQT" # r5129 "".join(random.sample(string.letters, 10))
# Warn user of possible delay due to large page dump in full UNION query injections # Warn user of possible delay due to large page dump in full UNION query injections
LARGE_OUTPUT_THRESHOLD = 1024**2 LARGE_OUTPUT_THRESHOLD = 1024 ** 2
# On huge tables there is a considerable slowdown if every row retrieval requires ORDER BY (most noticable in table dumping using ERROR injections) # On huge tables there is a considerable slowdown if every row retrieval requires ORDER BY (most noticable in table dumping using ERROR injections)
SLOW_ORDER_COUNT_THRESHOLD = 10000 SLOW_ORDER_COUNT_THRESHOLD = 10000

View File

@ -40,7 +40,7 @@ class CompleterNG(rlcompleter.Completer):
matches = [] matches = []
n = len(text) n = len(text)
for ns in [ self.namespace ]: for ns in (self.namespace,):
for word in ns: for word in ns:
if word[:n] == text: if word[:n] == text:
matches.append(word) matches.append(word)

View File

@ -49,7 +49,7 @@ def blockingReadFromFD(fd):
break break
if not output: if not output:
raise EOFError("fd %s has been closed." % fd ) raise EOFError("fd %s has been closed." % fd)
return output return output
@ -142,7 +142,7 @@ class Popen(subprocess.Popen):
try: try:
written = os.write(self.stdin.fileno(), input) written = os.write(self.stdin.fileno(), input)
except OSError, why: except OSError, why:
if why[0] == errno.EPIPE: #broken pipe if why[0] == errno.EPIPE: # broken pipe
return self._close('stdin') return self._close('stdin')
raise raise
@ -155,7 +155,7 @@ class Popen(subprocess.Popen):
flags = fcntl.fcntl(conn, fcntl.F_GETFL) flags = fcntl.fcntl(conn, fcntl.F_GETFL)
if not conn.closed: if not conn.closed:
fcntl.fcntl(conn, fcntl.F_SETFL, flags| os.O_NONBLOCK) fcntl.fcntl(conn, fcntl.F_SETFL, flags | os.O_NONBLOCK)
try: try:
if not select.select([conn], [], [], 0)[0]: if not select.select([conn], [], [], 0)[0]:
@ -175,7 +175,7 @@ class Popen(subprocess.Popen):
def recv_some(p, t=.1, e=1, tr=5, stderr=0): def recv_some(p, t=.1, e=1, tr=5, stderr=0):
if tr < 1: if tr < 1:
tr = 1 tr = 1
x = time.time()+t x = time.time() + t
y = [] y = []
r = '' r = ''
if stderr: if stderr:
@ -189,7 +189,7 @@ def recv_some(p, t=.1, e=1, tr=5, stderr=0):
elif r: elif r:
y.append(r) y.append(r)
else: else:
time.sleep(max((x-time.time())/tr, 0)) time.sleep(max((x - time.time()) / tr, 0))
return ''.join(y) return ''.join(y)
def send_all(p, data): def send_all(p, data):

View File

@ -130,8 +130,8 @@ def _setRequestParams():
kb.processUserMarks = True if kb.postHint else kb.processUserMarks kb.processUserMarks = True if kb.postHint else kb.processUserMarks
if re.search(URI_INJECTABLE_REGEX, conf.url, re.I) and not any(map(lambda place: place in conf.parameters, [PLACE.GET, PLACE.POST])): if re.search(URI_INJECTABLE_REGEX, conf.url, re.I) and not any(place in conf.parameters for place in (PLACE.GET, PLACE.POST)):
warnMsg = "you've provided target url without any GET " warnMsg = "you've provided target url without any GET "
warnMsg += "parameters (e.g. www.site.com/article.php?id=1) " warnMsg += "parameters (e.g. www.site.com/article.php?id=1) "
warnMsg += "and without providing any POST parameters " warnMsg += "and without providing any POST parameters "
warnMsg += "through --data option" warnMsg += "through --data option"
@ -161,7 +161,7 @@ def _setRequestParams():
if not kb.processUserMarks: if not kb.processUserMarks:
if place == PLACE.URI: if place == PLACE.URI:
query = urlparse.urlsplit(value)[3] query = urlparse.urlsplit(value).query
if query: if query:
parameters = conf.parameters[PLACE.GET] = query parameters = conf.parameters[PLACE.GET] = query
paramDict = paramToDict(PLACE.GET, parameters) paramDict = paramToDict(PLACE.GET, parameters)

View File

@ -234,7 +234,7 @@ def runCase(switches=None, parse=None):
logger.error("unhandled exception occurred ('%s')" % str(exception)) logger.error("unhandled exception occurred ('%s')" % str(exception))
tback = traceback.format_exc() tback = traceback.format_exc()
retVal = False retVal = False
elif result is False: # if None, ignore elif result is False: # if None, ignore
logger.error("the test did not run") logger.error("the test did not run")
retVal = False retVal = False

View File

@ -104,7 +104,7 @@ def runThreads(numThreads, threadFunction, cleanupFunction=None, forwardExceptio
kb.threadContinue = True kb.threadContinue = True
kb.threadException = False kb.threadException = False
if threadChoice and numThreads == 1 and any(map(lambda _: _ in kb.injection.data, (PAYLOAD.TECHNIQUE.BOOLEAN, PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.QUERY, PAYLOAD.TECHNIQUE.UNION))): if threadChoice and numThreads == 1 and any(_ in kb.injection.data for _ in (PAYLOAD.TECHNIQUE.BOOLEAN, PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.QUERY, PAYLOAD.TECHNIQUE.UNION)):
while True: while True:
message = "please enter number of threads? [Enter for %d (current)] " % numThreads message = "please enter number of threads? [Enter for %d (current)] " % numThreads
choice = readInput(message, default=str(numThreads)) choice = readInput(message, default=str(numThreads))

View File

@ -517,7 +517,7 @@ def cmdLineParser():
# General options # General options
general = OptionGroup(parser, "General", "These options can be used " general = OptionGroup(parser, "General", "These options can be used "
"to set some general working parameters" ) "to set some general working parameters")
#general.add_option("-x", dest="xmlFile", #general.add_option("-x", dest="xmlFile",
# help="Dump the data into an XML file") # help="Dump the data into an XML file")
@ -755,7 +755,7 @@ def cmdLineParser():
# Expand given mnemonic options (e.g. -z "ign,flu,bat") # Expand given mnemonic options (e.g. -z "ign,flu,bat")
for i in xrange(len(sys.argv) - 1): for i in xrange(len(sys.argv) - 1):
if sys.argv[i] == '-z': if sys.argv[i] == '-z':
expandMnemonics(sys.argv[i+1], parser, args) expandMnemonics(sys.argv[i + 1], parser, args)
if not any((args.direct, args.url, args.logFile, args.bulkFile, args.googleDork, args.configFile, \ if not any((args.direct, args.url, args.logFile, args.bulkFile, args.googleDork, args.configFile, \
args.requestFile, args.updateAll, args.smokeTest, args.liveTest, args.wizard, args.dependencies, \ args.requestFile, args.updateAll, args.smokeTest, args.liveTest, args.wizard, args.dependencies, \

View File

@ -44,7 +44,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"))
_ = re.match("\A[A-Za-z0-9]+", self._regexp) # minor trick avoiding compiling of large amount of regexes _ = re.match("\A[A-Za-z0-9]+", self._regexp) # minor trick avoiding compiling of large amount of regexes
if _ and _.group(0).lower() in self._banner.lower() or not _: if _ and _.group(0).lower() in self._banner.lower() or not _:
self._match = re.search(self._regexp, self._banner, re.I | re.M) self._match = re.search(self._regexp, self._banner, re.I | re.M)

View File

@ -30,7 +30,7 @@ def headersParser(headers):
"servlet-engine": os.path.join(paths.SQLMAP_XML_BANNER_PATH, "servlet.xml"), "servlet-engine": os.path.join(paths.SQLMAP_XML_BANNER_PATH, "servlet.xml"),
"set-cookie": os.path.join(paths.SQLMAP_XML_BANNER_PATH, "cookie.xml"), "set-cookie": os.path.join(paths.SQLMAP_XML_BANNER_PATH, "cookie.xml"),
"x-aspnet-version": os.path.join(paths.SQLMAP_XML_BANNER_PATH, "x-aspnet-version.xml"), "x-aspnet-version": os.path.join(paths.SQLMAP_XML_BANNER_PATH, "x-aspnet-version.xml"),
"x-powered-by": os.path.join(paths.SQLMAP_XML_BANNER_PATH, "x-powered-by.xml") "x-powered-by": os.path.join(paths.SQLMAP_XML_BANNER_PATH, "x-powered-by.xml"),
} }
for header in itertools.ifilter(lambda x: x in kb.headerPaths, headers): for header in itertools.ifilter(lambda x: x in kb.headerPaths, headers):

View File

@ -110,8 +110,8 @@ def checkCharEncoding(encoding, warn=True):
else: else:
return encoding return encoding
# http://www.destructor.de/charsets/index.htm # Reference: http://www.destructor.de/charsets/index.htm
translate = { "windows-874": "iso-8859-11", "en_us": "utf8", "macintosh": "iso-8859-1", "euc_tw": "big5_tw", "th": "tis-620", "unicode": "utf8", "utc8": "utf8", "ebcdic": "ebcdic-cp-be"} translate = {"windows-874": "iso-8859-11", "en_us": "utf8", "macintosh": "iso-8859-1", "euc_tw": "big5_tw", "th": "tis-620", "unicode": "utf8", "utc8": "utf8", "ebcdic": "ebcdic-cp-be"}
for delimiter in (';', ',', '('): for delimiter in (';', ',', '('):
if delimiter in encoding: if delimiter in encoding:
@ -119,17 +119,17 @@ def checkCharEncoding(encoding, warn=True):
# popular typos/errors # popular typos/errors
if "8858" in encoding: if "8858" in encoding:
encoding = encoding.replace("8858", "8859") # iso-8858 -> iso-8859 encoding = encoding.replace("8858", "8859") # iso-8858 -> iso-8859
elif "8559" in encoding: elif "8559" in encoding:
encoding = encoding.replace("8559", "8859") # iso-8559 -> iso-8859 encoding = encoding.replace("8559", "8859") # iso-8559 -> iso-8859
elif "5889" in encoding: elif "5889" in encoding:
encoding = encoding.replace("5889", "8859") # iso-5889 -> iso-8859 encoding = encoding.replace("5889", "8859") # iso-5889 -> iso-8859
elif "5589" in encoding: elif "5589" in encoding:
encoding = encoding.replace("5589", "8859") # iso-5589 -> iso-8859 encoding = encoding.replace("5589", "8859") # iso-5589 -> iso-8859
elif "2313" in encoding: elif "2313" in encoding:
encoding = encoding.replace("2313", "2312") # gb2313 -> gb2312 encoding = encoding.replace("2313", "2312") # gb2313 -> gb2312
elif "x-euc" in encoding: elif "x-euc" in encoding:
encoding = encoding.replace("x-euc", "euc") # x-euc-kr -> euc-kr encoding = encoding.replace("x-euc", "euc") # x-euc-kr -> euc-kr
# name adjustment for compatibility # name adjustment for compatibility
if encoding.startswith("8859"): if encoding.startswith("8859"):
@ -149,14 +149,14 @@ def checkCharEncoding(encoding, warn=True):
elif encoding.find("utf8") > 0: elif encoding.find("utf8") > 0:
encoding = "utf8" encoding = "utf8"
# http://philip.html5.org/data/charsets-2.html # Reference: http://philip.html5.org/data/charsets-2.html
if encoding in translate: if encoding in translate:
encoding = translate[encoding] encoding = translate[encoding]
elif encoding in ("null", "{charset}", "*"): elif encoding in ("null", "{charset}", "*"):
return None return None
# http://www.iana.org/assignments/character-sets # Reference: http://www.iana.org/assignments/character-sets
# http://docs.python.org/library/codecs.html # Reference: http://docs.python.org/library/codecs.html
try: try:
codecs.lookup(encoding) codecs.lookup(encoding)
except LookupError: except LookupError:
@ -216,7 +216,7 @@ def decodePage(page, contentEncoding, contentType):
if not conf.charset: if not conf.charset:
httpCharset, metaCharset = None, None httpCharset, metaCharset = None, None
# http://stackoverflow.com/questions/1020892/python-urllib2-read-to-unicode # Reference: http://stackoverflow.com/questions/1020892/python-urllib2-read-to-unicode
if contentType and (contentType.find("charset=") != -1): if contentType and (contentType.find("charset=") != -1):
httpCharset = checkCharEncoding(contentType.split("charset=")[-1]) httpCharset = checkCharEncoding(contentType.split("charset=")[-1])

View File

@ -21,7 +21,7 @@ class HTTPSCertAuthHandler(urllib2.HTTPSHandler):
return self.do_open(self.getConnection, req) return self.do_open(self.getConnection, req)
def getConnection(self, host): def getConnection(self, host):
if sys.version_info >= (2,6): if sys.version_info >= (2, 6):
retVal = httplib.HTTPSConnection(host, key_file=self.key_file, cert_file=self.cert_file, timeout=conf.timeout) retVal = httplib.HTTPSConnection(host, key_file=self.key_file, cert_file=self.cert_file, timeout=conf.timeout)
else: else:
retVal = httplib.HTTPSConnection(host, key_file=self.key_file, cert_file=self.cert_file) retVal = httplib.HTTPSConnection(host, key_file=self.key_file, cert_file=self.cert_file)

View File

@ -189,7 +189,7 @@ class Connect(object):
ua = kwargs.get('ua', None) ua = kwargs.get('ua', None)
referer = kwargs.get('referer', None) referer = kwargs.get('referer', None)
host = kwargs.get('host', conf.host) host = kwargs.get('host', conf.host)
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)
@ -398,7 +398,7 @@ class Connect(object):
if url.lower().startswith('http://'): if url.lower().startswith('http://'):
kwargs['url'] = url kwargs['url'] = url
else: else:
kwargs['url'] = conf.url[:conf.url.rfind('/')+1] + url kwargs['url'] = conf.url[:conf.url.rfind('/') + 1] + url
threadData.lastRedirectMsg = (threadData.lastRequestUID, page) threadData.lastRedirectMsg = (threadData.lastRequestUID, page)
kwargs['refreshing'] = True kwargs['refreshing'] = True

View File

@ -32,7 +32,7 @@ class DNSQuery(object):
j = ord(raw[i]) j = ord(raw[i])
while j != 0: while j != 0:
self._query += raw[i+1:i+j+1] + '.' self._query += raw[i + 1:i + j + 1] + '.'
i = i + j + 1 i = i + j + 1
j = ord(raw[i]) j = ord(raw[i])
@ -137,4 +137,3 @@ if __name__ == "__main__":
finally: finally:
if server: if server:
server._running = False server._running = False

View File

@ -361,7 +361,7 @@ def getValue(expression, blind=True, union=True, error=True, time=True, fromUser
found = (value is not None) or (value is None and expectingNone) or count >= MAX_TECHNIQUES_PER_VALUE found = (value is not None) or (value is None and expectingNone) or count >= MAX_TECHNIQUES_PER_VALUE
if found and conf.dnsName: if found and conf.dnsName:
_ = "".join(filter(None, (key if isTechniqueAvailable(value) else None for key, value in {"E":PAYLOAD.TECHNIQUE.ERROR, "Q":PAYLOAD.TECHNIQUE.QUERY, "U":PAYLOAD.TECHNIQUE.UNION}.items()))) _ = "".join(filter(None, (key if isTechniqueAvailable(value) else None for key, value in {"E": PAYLOAD.TECHNIQUE.ERROR, "Q": PAYLOAD.TECHNIQUE.QUERY, "U": PAYLOAD.TECHNIQUE.UNION}.items())))
warnMsg = "option '--dns-domain' will be ignored " warnMsg = "option '--dns-domain' will be ignored "
warnMsg += "as faster techniques are usable " warnMsg += "as faster techniques are usable "
warnMsg += "(%s) " % _ warnMsg += "(%s) " % _

View File

@ -17,7 +17,7 @@ if PYVERSION >= "2.6":
import ssl import ssl
class ProxyHTTPConnection(httplib.HTTPConnection): class ProxyHTTPConnection(httplib.HTTPConnection):
_ports = {"http" : 80, "https" : 443} _ports = {"http": 80, "https": 443}
def request(self, method, url, body=None, headers={}): def request(self, method, url, body=None, headers={}):
# Request is called before connect, so can interpret url and get # Request is called before connect, so can interpret url and get

View File

@ -86,7 +86,7 @@ class Metasploit:
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"), 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"), 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"), 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") 5: ("Bind TCP: Listen on the database host for a connection", "bind_tcp"),
}, },
"linux": { "linux": {
1: ("Reverse TCP: Connect back from the database host to this machine (default)", "reverse_tcp"), 1: ("Reverse TCP: Connect back from the database host to this machine (default)", "reverse_tcp"),

View File

@ -33,18 +33,18 @@ class Registry:
self._batRead = ( self._batRead = (
"@ECHO OFF\r\n", "@ECHO OFF\r\n",
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),
) )
def _createLocalBatchFile(self): def _createLocalBatchFile(self):
self._batPathFp = open(self._batPathLocal, "w") self._batPathFp = open(self._batPathLocal, "w")

View File

@ -93,7 +93,7 @@ class Web:
return self._webFileStreamUpload(stream, destFileName, directory) return self._webFileStreamUpload(stream, destFileName, directory)
def _webFileStreamUpload(self, stream, destFileName, directory): def _webFileStreamUpload(self, stream, destFileName, directory):
stream.seek(0) # Rewind stream.seek(0) # Rewind
try: try:
setattr(stream, "name", destFileName) setattr(stream, "name", destFileName)

View File

@ -157,16 +157,16 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
if hintValue is not None and len(hintValue) >= idx: if hintValue is not None and len(hintValue) >= idx:
if Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.ACCESS, DBMS.MAXDB, DBMS.DB2): if Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.ACCESS, DBMS.MAXDB, DBMS.DB2):
posValue = hintValue[idx-1] posValue = hintValue[idx - 1]
else: else:
posValue = ord(hintValue[idx-1]) posValue = ord(hintValue[idx - 1])
forgedPayload = safeStringFormat(payload.replace(INFERENCE_GREATER_CHAR, INFERENCE_EQUALS_CHAR), (expressionUnescaped, idx, posValue)) forgedPayload = safeStringFormat(payload.replace(INFERENCE_GREATER_CHAR, INFERENCE_EQUALS_CHAR), (expressionUnescaped, idx, posValue))
result = Request.queryPage(forgedPayload, timeBasedCompare=timeBasedCompare, raise404=False) result = Request.queryPage(forgedPayload, timeBasedCompare=timeBasedCompare, raise404=False)
incrementCounter(kb.technique) incrementCounter(kb.technique)
if result: if result:
return hintValue[idx-1] return hintValue[idx - 1]
with hintlock: with hintlock:
kb.hintValue = None kb.hintValue = None
@ -347,8 +347,8 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
if conf.threads > 1 and isinstance(length, int) and length > 1: if conf.threads > 1 and isinstance(length, int) and length > 1:
threadData = getCurrentThreadData() threadData = getCurrentThreadData()
threadData.shared.value = [ None ] * length threadData.shared.value = [None] * length
threadData.shared.index = [ firstChar ] # As list for python nested function scoping threadData.shared.index = [firstChar] # As list for python nested function scoping
threadData.shared.start = firstChar threadData.shared.start = firstChar
try: try:
@ -406,7 +406,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
if startCharIndex > 0: if startCharIndex > 0:
output = '..' + output[2:] output = '..' + output[2:]
if (endCharIndex - startCharIndex == conf.progressWidth) and (endCharIndex < length-1): if (endCharIndex - startCharIndex == conf.progressWidth) and (endCharIndex < length - 1):
output = output[:-2] + '..' output = output[:-2] + '..'
if conf.verbose in (1, 2) and not showEta: if conf.verbose in (1, 2) and not showEta:
@ -423,7 +423,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
abortedFlag = True abortedFlag = True
finally: finally:
value = map(lambda _: partialValue[_] if _ < len(partialValue) else threadData.shared.value[_], xrange(length)) value = [partialValue[_] if _ < len(partialValue) else threadData.shared.value[_] for _ in xrange(length)]
infoMsg = None infoMsg = None
@ -471,7 +471,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
if showEta: if showEta:
etaProgressUpdate(time.time() - charStart, len(commonValue)) etaProgressUpdate(time.time() - charStart, len(commonValue))
elif conf.verbose in (1, 2): elif conf.verbose in (1, 2):
dataToStdout(filterControlChars(commonValue[index-1:])) dataToStdout(filterControlChars(commonValue[index - 1:]))
finalValue = commonValue finalValue = commonValue
@ -490,8 +490,8 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
# Did we have luck? # Did we have luck?
if result: if result:
val = commonPattern[index-1:] val = commonPattern[index - 1:]
index += len(val)-1 index += len(val) - 1
# Otherwise if there is no commonValue (single match from # Otherwise if there is no commonValue (single match from
# txt/common-outputs.txt) and no commonPattern # txt/common-outputs.txt) and no commonPattern

View File

@ -127,7 +127,7 @@ def tableExists(tableFile, regex=None):
else: else:
kb.data.cachedTables[conf.db].append(item) kb.data.cachedTables[conf.db].append(item)
for _ in map(lambda x: (conf.db, x), threadData.shared.value): for _ in ((conf.db, item) for item in threadData.shared.value):
if _ not in kb.brute.tables: if _ not in kb.brute.tables:
kb.brute.tables.append(_) kb.brute.tables.append(_)

View File

@ -100,7 +100,7 @@ def _findUnionCharCount(comment, place, parameter, value, prefix, suffix, where=
min_, max_ = MAX_RATIO, MIN_RATIO min_, max_ = MAX_RATIO, MIN_RATIO
pages = {} pages = {}
for count in xrange(lowerCount, upperCount+1): for count in xrange(lowerCount, upperCount + 1):
query = agent.forgeUnionQuery('', -1, count, comment, prefix, suffix, kb.uChar, where) query = agent.forgeUnionQuery('', -1, count, comment, prefix, suffix, kb.uChar, where)
payload = agent.payload(place=place, parameter=parameter, newValue=query, where=where) payload = agent.payload(place=place, parameter=parameter, newValue=query, where=where)
page, headers = Request.queryPage(payload, place=place, content=True, raise404=False) page, headers = Request.queryPage(payload, place=place, content=True, raise404=False)

View File

@ -95,19 +95,19 @@ def security_headers():
# HTTP Status Code functions # # HTTP Status Code functions #
############################## ##############################
@error(401) # Access Denied @error(401) # Access Denied
def error401(error=None): def error401(error=None):
return "Access denied" return "Access denied"
@error(404) # Not Found @error(404) # Not Found
def error404(error=None): def error404(error=None):
return "Nothing here" return "Nothing here"
@error(405) # Method Not Allowed (e.g. when requesting a POST method via GET) @error(405) # Method Not Allowed (e.g. when requesting a POST method via GET)
def error405(error=None): def error405(error=None):
return "Method not allowed" return "Method not allowed"
@error(500) # Internal Server Error @error(500) # Internal Server Error
def error500(error=None): def error500(error=None):
return "Internal server error" return "Internal server error"
@ -324,7 +324,7 @@ def scan_log_limited(taskid, start, end):
if not start.isdigit() or not end.isdigit() or end <= start: if not start.isdigit() or not end.isdigit() or end <= start:
abort(500, "Invalid start or end value, must be digits") abort(500, "Invalid start or end value, must be digits")
start = max(0, int(start)-1) start = max(0, int(start) - 1)
end = max(1, int(end)) end = max(1, int(end))
pickledLog = os.read(pipes[taskid][0], 100000) pickledLog = os.read(pipes[taskid][0], 100000)

View File

@ -88,7 +88,7 @@ def crawl(target):
threadData.shared.deeper.add(url) threadData.shared.deeper.add(url)
if re.search(r"(.*?)\?(.+)", url): if re.search(r"(.*?)\?(.+)", url):
threadData.shared.value.add(url) threadData.shared.value.add(url)
except UnicodeEncodeError: # for non-HTML files except UnicodeEncodeError: # for non-HTML files
pass pass
finally: finally:
if conf.forms: if conf.forms:

View File

@ -19,7 +19,8 @@ class _Getch(object):
except(AttributeError, ImportError): except(AttributeError, ImportError):
self.impl = _GetchUnix() self.impl = _GetchUnix()
def __call__(self): return self.impl() def __call__(self):
return self.impl()
class _GetchUnix(object): class _GetchUnix(object):
@ -27,7 +28,10 @@ class _GetchUnix(object):
import tty import tty
def __call__(self): def __call__(self):
import sys, tty, termios import sys
import termios
import tty
fd = sys.stdin.fileno() fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd) old_settings = termios.tcgetattr(fd)
try: try:
@ -56,11 +60,11 @@ class _GetchMacCarbon(object):
""" """
def __init__(self): def __init__(self):
import Carbon import Carbon
Carbon.Evt #see if it has this (in Unix, it doesn't) Carbon.Evt # see if it has this (in Unix, it doesn't)
def __call__(self): def __call__(self):
import Carbon import Carbon
if Carbon.Evt.EventAvail(0x0008)[0]==0: # 0x0008 is the keyDownMask if Carbon.Evt.EventAvail(0x0008)[0] == 0: # 0x0008 is the keyDownMask
return '' return ''
else: else:
# #
@ -72,8 +76,9 @@ class _GetchMacCarbon(object):
# number is converted to an ASCII character with chr() and # number is converted to an ASCII character with chr() and
# returned # returned
# #
(what,msg,when,where,mod)=Carbon.Evt.GetNextEvent(0x0008)[1] (what, msg, when, where, mod) = Carbon.Evt.GetNextEvent(0x0008)[1]
return chr(msg & 0x000000FF) return chr(msg & 0x000000FF)
getch = _Getch() getch = _Getch()

View File

@ -61,7 +61,7 @@ class Google(object):
url = "http://www.google.com/search?" url = "http://www.google.com/search?"
url += "q=%s&" % urlencode(dork, convall=True) url += "q=%s&" % urlencode(dork, convall=True)
url += "num=100&hl=en&complete=0&safe=off&filter=0&btnG=Search" url += "num=100&hl=en&complete=0&safe=off&filter=0&btnG=Search"
url += "&start=%d" % ((gpage-1) * 100) url += "&start=%d" % ((gpage - 1) * 100)
try: try:
conn = self.opener.open(url) conn = self.opener.open(url)

View File

@ -81,7 +81,7 @@ def mysql_passwd(password, uppercase=True):
return retVal.upper() if uppercase else retVal.lower() return retVal.upper() if uppercase else retVal.lower()
def mysql_old_passwd(password, uppercase=True): # prior to version '4.1' def mysql_old_passwd(password, uppercase=True): # prior to version '4.1'
""" """
Reference(s): Reference(s):
http://www.sfr-fresh.com/unix/privat/tpop3d-1.5.5.tar.gz:a/tpop3d-1.5.5/password.c http://www.sfr-fresh.com/unix/privat/tpop3d-1.5.5.tar.gz:a/tpop3d-1.5.5/password.c
@ -136,7 +136,7 @@ def mssql_passwd(password, salt, uppercase=False):
return "0x%s" % (retVal.upper() if uppercase else retVal.lower()) return "0x%s" % (retVal.upper() if uppercase else retVal.lower())
def mssql_old_passwd(password, salt, uppercase=True): # prior to version '2005' def mssql_old_passwd(password, salt, uppercase=True): # prior to version '2005'
""" """
Reference(s): Reference(s):
www.exploit-db.com/download_pdf/15537/ www.exploit-db.com/download_pdf/15537/
@ -167,11 +167,11 @@ def oracle_passwd(password, salt, uppercase=True):
binsalt = hexdecode(salt) binsalt = hexdecode(salt)
retVal="s:%s%s" % (sha1(utf8encode(password) + binsalt).hexdigest(), salt) retVal = "s:%s%s" % (sha1(utf8encode(password) + binsalt).hexdigest(), salt)
return retVal.upper() if uppercase else retVal.lower() return retVal.upper() if uppercase else retVal.lower()
def oracle_old_passwd(password, username, uppercase=True): # prior to version '11g' def oracle_old_passwd(password, username, uppercase=True): # prior to version '11g'
""" """
Reference(s): Reference(s):
http://www.notesbit.com/index.php/scripts-oracle/oracle-11g-new-password-algorithm-is-revealed-by-seclistsorg/ http://www.notesbit.com/index.php/scripts-oracle/oracle-11g-new-password-algorithm-is-revealed-by-seclistsorg/
@ -180,10 +180,10 @@ def oracle_old_passwd(password, username, uppercase=True): # prior to version '1
'F894844C34402B67' 'F894844C34402B67'
""" """
IV, pad = "\0"*8, "\0" IV, pad = "\0" * 8, "\0"
if isinstance(username, unicode): if isinstance(username, unicode):
username = unicode.encode(username, UNICODE_ENCODING) #pyDes has issues with unicode strings username = unicode.encode(username, UNICODE_ENCODING) # pyDes has issues with unicode strings
unistr = "".join("\0%s" % c for c in (username + password).upper()) unistr = "".join("\0%s" % c for c in (username + password).upper())
@ -255,7 +255,7 @@ def wordpress_passwd(password, salt, count, prefix, uppercase=False):
if i < count: if i < count:
value = value | (ord(input_[i]) << 8) value = value | (ord(input_[i]) << 8)
output = output + ITOA64[(value>>6) & 0x3f] output = output + ITOA64[(value >> 6) & 0x3f]
i += 1 i += 1
if i >= count: if i >= count:
@ -264,13 +264,13 @@ def wordpress_passwd(password, salt, count, prefix, uppercase=False):
if i < count: if i < count:
value = value | (ord(input_[i]) << 16) value = value | (ord(input_[i]) << 16)
output = output + ITOA64[(value>>12) & 0x3f] output = output + ITOA64[(value >> 12) & 0x3f]
i += 1 i += 1
if i >= count: if i >= count:
break break
output = output + ITOA64[(value>>18) & 0x3f] output = output + ITOA64[(value >> 18) & 0x3f]
return output return output
@ -298,7 +298,7 @@ __functions__ = {
HASH.MD5_GENERIC: md5_generic_passwd, HASH.MD5_GENERIC: md5_generic_passwd,
HASH.SHA1_GENERIC: sha1_generic_passwd, HASH.SHA1_GENERIC: sha1_generic_passwd,
HASH.CRYPT_GENERIC: crypt_generic_passwd, HASH.CRYPT_GENERIC: crypt_generic_passwd,
HASH.WORDPRESS: wordpress_passwd HASH.WORDPRESS: wordpress_passwd,
} }
def storeHashesToFile(attack_dict): def storeHashesToFile(attack_dict):
@ -463,7 +463,7 @@ def _bruteProcessVariantA(attack_info, hash_regex, suffix, retVal, proc_id, proc
word = word + suffix word = word + suffix
try: try:
current = __functions__[hash_regex](password = word, uppercase = False) current = __functions__[hash_regex](password=word, uppercase=False)
count += 1 count += 1
@ -498,9 +498,9 @@ def _bruteProcessVariantA(attack_info, hash_regex, suffix, retVal, proc_id, proc
raise raise
except (UnicodeEncodeError, UnicodeDecodeError): except (UnicodeEncodeError, UnicodeDecodeError):
pass # ignore possible encoding problems caused by some words in custom dictionaries pass # ignore possible encoding problems caused by some words in custom dictionaries
except Exception: except:
warnMsg = "there was a problem while hashing entry: %s. " % repr(word) warnMsg = "there was a problem while hashing entry: %s. " % repr(word)
warnMsg += "Please report by e-mail to %s" % ML warnMsg += "Please report by e-mail to %s" % ML
logger.critical(warnMsg) logger.critical(warnMsg)
@ -523,7 +523,7 @@ def _bruteProcessVariantB(user, hash_, kwargs, hash_regex, suffix, retVal, found
if found.value: if found.value:
break break
current = __functions__[hash_regex](password = word, uppercase = False, **kwargs) current = __functions__[hash_regex](password=word, uppercase=False, **kwargs)
count += 1 count += 1
if not isinstance(word, basestring): if not isinstance(word, basestring):
@ -534,7 +534,7 @@ def _bruteProcessVariantB(user, hash_, kwargs, hash_regex, suffix, retVal, found
try: try:
if hash_ == current: if hash_ == current:
if hash_regex == HASH.ORACLE_OLD: #only for cosmetic purposes if hash_regex == HASH.ORACLE_OLD: # only for cosmetic purposes
word = word.upper() word = word.upper()
retVal.put((user, hash_, word)) retVal.put((user, hash_, word))
@ -565,7 +565,7 @@ def _bruteProcessVariantB(user, hash_, kwargs, hash_regex, suffix, retVal, found
raise raise
except (UnicodeEncodeError, UnicodeDecodeError): except (UnicodeEncodeError, UnicodeDecodeError):
pass # ignore possible encoding problems caused by some words in custom dictionaries pass # ignore possible encoding problems caused by some words in custom dictionaries
except Exception, e: except Exception, e:
warnMsg = "there was a problem while hashing entry: %s (%s). " % (repr(word), e) warnMsg = "there was a problem while hashing entry: %s (%s). " % (repr(word), e)
@ -629,7 +629,7 @@ def dictionaryAttack(attack_dict):
elif hash_regex in (HASH.CRYPT_GENERIC): elif hash_regex in (HASH.CRYPT_GENERIC):
item = [(user, hash_), {'salt': hash_[0:2]}] item = [(user, hash_), {'salt': hash_[0:2]}]
elif hash_regex in (HASH.WORDPRESS): elif hash_regex in (HASH.WORDPRESS):
item = [(user, hash_), {'salt': hash_[4:12], 'count': 1<<ITOA64.index(hash_[3]), 'prefix': hash_[:12]}] item = [(user, hash_), {'salt': hash_[4:12], 'count': 1 << ITOA64.index(hash_[3]), 'prefix': hash_[:12]}]
if item and hash_ not in keys: if item and hash_ not in keys:
resumed = hashDBRetrieve(hash_) resumed = hashDBRetrieve(hash_)

View File

@ -52,7 +52,7 @@ class Fingerprint(GenericFingerprint):
"97": ("MSysModules2", "MSysAccessObjects"), "97": ("MSysModules2", "MSysAccessObjects"),
"2000" : ("!MSysModules2", "MSysAccessObjects"), "2000" : ("!MSysModules2", "MSysAccessObjects"),
"2002-2003" : ("MSysAccessStorage", "!MSysNavPaneObjectIDs"), "2002-2003" : ("MSysAccessStorage", "!MSysNavPaneObjectIDs"),
"2007" : ("MSysAccessStorage", "MSysNavPaneObjectIDs") "2007" : ("MSysAccessStorage", "MSysNavPaneObjectIDs"),
} }
# MSysAccessXML is not a reliable system table because it doesn't always exist # MSysAccessXML is not a reliable system table because it doesn't always exist
# ("Access through Access", p6, should be "normally doesn't exist" instead of "is normally empty") # ("Access through Access", p6, should be "normally doesn't exist" instead of "is normally empty")

View File

@ -17,4 +17,5 @@ class Enumeration(GenericEnumeration):
warnMsg = "on DB2 it is not possible to list password hashes" warnMsg = "on DB2 it is not possible to list password hashes"
logger.warn(warnMsg) logger.warn(warnMsg)
return {} return {}

View File

@ -47,7 +47,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:

View File

@ -40,7 +40,7 @@ class Connector(GenericConnector):
try: try:
self.connector = kinterbasdb.connect(host=self.hostname.encode(UNICODE_ENCODING), database=self.db.encode(UNICODE_ENCODING), \ self.connector = kinterbasdb.connect(host=self.hostname.encode(UNICODE_ENCODING), database=self.db.encode(UNICODE_ENCODING), \
user=self.user.encode(UNICODE_ENCODING), password=self.password.encode(UNICODE_ENCODING), charset="UTF8") #http://www.daniweb.com/forums/thread248499.html user=self.user.encode(UNICODE_ENCODING), password=self.password.encode(UNICODE_ENCODING), charset="UTF8") # Reference: http://www.daniweb.com/forums/thread248499.html
except kinterbasdb.OperationalError, msg: except kinterbasdb.OperationalError, msg:
raise SqlmapConnectionException(msg[1]) raise SqlmapConnectionException(msg[1])
self.setCursor() self.setCursor()

View File

@ -70,16 +70,16 @@ class Fingerprint(GenericFingerprint):
def _sysTablesCheck(self): def _sysTablesCheck(self):
retVal = None retVal = None
table = ( table = (
("1.0", ["EXISTS(SELECT CURRENT_USER FROM RDB$DATABASE)"]), ("1.0", ("EXISTS(SELECT CURRENT_USER FROM RDB$DATABASE)",)),
("1.5", ["NULLIF(%d,%d) IS NULL", "EXISTS(SELECT CURRENT_TRANSACTION FROM RDB$DATABASE)"]), ("1.5", ("NULLIF(%d,%d) IS NULL", "EXISTS(SELECT CURRENT_TRANSACTION FROM RDB$DATABASE)")),
("2.0", ["EXISTS(SELECT CURRENT_TIME(0) FROM RDB$DATABASE)", "BIT_LENGTH(%d)>0", "CHAR_LENGTH(%d)>0"]), ("2.0", ("EXISTS(SELECT CURRENT_TIME(0) FROM RDB$DATABASE)", "BIT_LENGTH(%d)>0", "CHAR_LENGTH(%d)>0")),
("2.1", ["BIN_XOR(%d,%d)=0", "PI()>0.%d", "RAND()<1.%d", "FLOOR(1.%d)>=0"]) ("2.1", ("BIN_XOR(%d,%d)=0", "PI()>0.%d", "RAND()<1.%d", "FLOOR(1.%d)>=0")),
) )
for i in xrange(len(table)): for i in xrange(len(table)):
version, checks = table[i] version, checks = table[i]
failed = False failed = False
check = checks[randomRange(0, len(checks)-1)].replace("%d", getUnicode(randomRange(1,100))) check = checks[randomRange(0, len(checks) - 1)].replace("%d", getUnicode(randomRange(1, 100)))
result = inject.checkBooleanExpression(check) result = inject.checkBooleanExpression(check)
if result: if result:

View File

@ -148,7 +148,7 @@ class Enumeration(GenericEnumeration):
randStr = randomStr() randStr = randomStr()
query = rootQuery.inband.query % (unsafeSQLIdentificatorNaming(tbl), ("'%s'" % unsafeSQLIdentificatorNaming(conf.db)) if unsafeSQLIdentificatorNaming(conf.db) != "USER" else 'USER') query = rootQuery.inband.query % (unsafeSQLIdentificatorNaming(tbl), ("'%s'" % unsafeSQLIdentificatorNaming(conf.db)) if unsafeSQLIdentificatorNaming(conf.db) != "USER" else 'USER')
retVal = pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.columnname' % randStr,'%s.datatype' % randStr,'%s.len' % randStr], blind=True) retVal = pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.columnname' % randStr, '%s.datatype' % randStr, '%s.len' % randStr], blind=True)
if retVal: if retVal:
table = {} table = {}

View File

@ -42,7 +42,7 @@ class Enumeration(GenericEnumeration):
areAdmins = set() areAdmins = set()
if conf.user: if conf.user:
users = [ conf.user ] users = [conf.user]
elif not len(kb.data.cachedUsers): elif not len(kb.data.cachedUsers):
users = self.getUsers() users = self.getUsers()
else: else:
@ -203,7 +203,7 @@ class Enumeration(GenericEnumeration):
if not isNoneValue(values): if not isNoneValue(values):
if isinstance(values, basestring): if isinstance(values, basestring):
values = [ values ] values = [values]
for foundTbl in values: for foundTbl in values:
if foundTbl is None: if foundTbl is None:
@ -325,7 +325,7 @@ class Enumeration(GenericEnumeration):
if not isNoneValue(values): if not isNoneValue(values):
if isinstance(values, basestring): if isinstance(values, basestring):
values = [ values ] values = [values]
for foundTbl in values: for foundTbl in values:
foundTbl = safeSQLIdentificatorNaming(foundTbl, True) foundTbl = safeSQLIdentificatorNaming(foundTbl, True)
@ -353,7 +353,7 @@ class Enumeration(GenericEnumeration):
if db in foundCols[column]: if db in foundCols[column]:
foundCols[column][db].append(foundTbl) foundCols[column][db].append(foundTbl)
else: else:
foundCols[column][db] = [ foundTbl ] foundCols[column][db] = [foundTbl]
else: else:
foundCols[column][db] = [] foundCols[column][db] = []

View File

@ -44,7 +44,7 @@ class Filesystem(GenericFilesystem):
for fileLine in xrange(0, len(fileContent), lineLen): for fileLine in xrange(0, len(fileContent), lineLen):
scrString = "" scrString = ""
for lineChar in fileContent[fileLine:fileLine+lineLen]: for lineChar in fileContent[fileLine:fileLine + lineLen]:
strLineChar = hexencode(lineChar) strLineChar = hexencode(lineChar)
if not scrString: if not scrString:

View File

@ -41,7 +41,7 @@ class Takeover(GenericTakeover):
#"2003-2": ("CHAR(0xe4)+CHAR(0x37)+CHAR(0xea)+CHAR(0x7c)", "CHAR(0x15)+CHAR(0xc9)+CHAR(0x93)+CHAR(0x7c)", "CHAR(0x96)+CHAR(0xdc)+CHAR(0xa7)+CHAR(0x7c)", "CHAR(0x73)+CHAR(0x1e)+CHAR(0x8f)+CHAR(0x7c)", "CHAR(0x73)+CHAR(0x1e)+CHAR(0x8f)+CHAR(0x7c)", "CHAR(0x17)+CHAR(0xf5)+CHAR(0x83)+CHAR(0x7c)", "CHAR(0x1b)+CHAR(0xa0)+CHAR(0x86)+CHAR(0x7c)", "CHAR(0x1b)+CHAR(0xa0)+CHAR(0x86)+CHAR(0x7c)" ), #"2003-2": ("CHAR(0xe4)+CHAR(0x37)+CHAR(0xea)+CHAR(0x7c)", "CHAR(0x15)+CHAR(0xc9)+CHAR(0x93)+CHAR(0x7c)", "CHAR(0x96)+CHAR(0xdc)+CHAR(0xa7)+CHAR(0x7c)", "CHAR(0x73)+CHAR(0x1e)+CHAR(0x8f)+CHAR(0x7c)", "CHAR(0x73)+CHAR(0x1e)+CHAR(0x8f)+CHAR(0x7c)", "CHAR(0x17)+CHAR(0xf5)+CHAR(0x83)+CHAR(0x7c)", "CHAR(0x1b)+CHAR(0xa0)+CHAR(0x86)+CHAR(0x7c)", "CHAR(0x1b)+CHAR(0xa0)+CHAR(0x86)+CHAR(0x7c)" ),
# 2003 Service Pack 2 updated at 05/2009 # 2003 Service Pack 2 updated at 05/2009
"2003-2": ("CHAR(0xc3)+CHAR(0xdb)+CHAR(0x67)+CHAR(0x77)", "CHAR(0x15)+CHAR(0xc9)+CHAR(0x93)+CHAR(0x7c)", "CHAR(0x96)+CHAR(0xdc)+CHAR(0xa7)+CHAR(0x7c)", "CHAR(0x73)+CHAR(0x1e)+CHAR(0x8f)+CHAR(0x7c)", "CHAR(0x73)+CHAR(0x1e)+CHAR(0x8f)+CHAR(0x7c)", "CHAR(0x47)+CHAR(0xf5)+CHAR(0x83)+CHAR(0x7c)", "CHAR(0x0f)+CHAR(0x31)+CHAR(0x8e)+CHAR(0x7c)", "CHAR(0x0f)+CHAR(0x31)+CHAR(0x8e)+CHAR(0x7c)") "2003-2": ("CHAR(0xc3)+CHAR(0xdb)+CHAR(0x67)+CHAR(0x77)", "CHAR(0x15)+CHAR(0xc9)+CHAR(0x93)+CHAR(0x7c)", "CHAR(0x96)+CHAR(0xdc)+CHAR(0xa7)+CHAR(0x7c)", "CHAR(0x73)+CHAR(0x1e)+CHAR(0x8f)+CHAR(0x7c)", "CHAR(0x73)+CHAR(0x1e)+CHAR(0x8f)+CHAR(0x7c)", "CHAR(0x47)+CHAR(0xf5)+CHAR(0x83)+CHAR(0x7c)", "CHAR(0x0f)+CHAR(0x31)+CHAR(0x8e)+CHAR(0x7c)", "CHAR(0x0f)+CHAR(0x31)+CHAR(0x8e)+CHAR(0x7c)"),
# 2003 Service Pack 2 updated at 09/2009 # 2003 Service Pack 2 updated at 09/2009
#"2003-2": ("CHAR(0xc3)+CHAR(0xc2)+CHAR(0xed)+CHAR(0x7c)", "CHAR(0xf3)+CHAR(0xd9)+CHAR(0xa7)+CHAR(0x7c)", "CHAR(0x99)+CHAR(0xc8)+CHAR(0x93)+CHAR(0x7c)", "CHAR(0x63)+CHAR(0x1e)+CHAR(0x8f)+CHAR(0x7c)", "CHAR(0x63)+CHAR(0x1e)+CHAR(0x8f)+CHAR(0x7c)", "CHAR(0x17)+CHAR(0xf5)+CHAR(0x83)+CHAR(0x7c)", "CHAR(0xa4)+CHAR(0xde)+CHAR(0x8e)+CHAR(0x7c)", "CHAR(0xa4)+CHAR(0xde)+CHAR(0x8e)+CHAR(0x7c)"), #"2003-2": ("CHAR(0xc3)+CHAR(0xc2)+CHAR(0xed)+CHAR(0x7c)", "CHAR(0xf3)+CHAR(0xd9)+CHAR(0xa7)+CHAR(0x7c)", "CHAR(0x99)+CHAR(0xc8)+CHAR(0x93)+CHAR(0x7c)", "CHAR(0x63)+CHAR(0x1e)+CHAR(0x8f)+CHAR(0x7c)", "CHAR(0x63)+CHAR(0x1e)+CHAR(0x8f)+CHAR(0x7c)", "CHAR(0x17)+CHAR(0xf5)+CHAR(0x83)+CHAR(0x7c)", "CHAR(0xa4)+CHAR(0xde)+CHAR(0x8e)+CHAR(0x7c)", "CHAR(0xa4)+CHAR(0xde)+CHAR(0x8e)+CHAR(0x7c)"),
@ -68,7 +68,7 @@ class Takeover(GenericTakeover):
hexStr = binascii.hexlify(self.shellcodeString[:-1]) hexStr = binascii.hexlify(self.shellcodeString[:-1])
for hexPair in xrange(0, len(hexStr), 2): for hexPair in xrange(0, len(hexStr), 2):
shellcodeChar += "CHAR(0x%s)+" % hexStr[hexPair:hexPair+2] shellcodeChar += "CHAR(0x%s)+" % hexStr[hexPair:hexPair + 2]
shellcodeChar = shellcodeChar[:-1] shellcodeChar = shellcodeChar[:-1]

View File

@ -174,7 +174,7 @@ class Fingerprint(GenericFingerprint):
infoMsg = "confirming %s" % DBMS.MYSQL infoMsg = "confirming %s" % DBMS.MYSQL
logger.info(infoMsg) logger.info(infoMsg)
result = inject.checkBooleanExpression("USER()=USER()") result = inject.checkBooleanExpression("USER() LIKE USER()")
if not result: if not result:
warnMsg = "the back-end DBMS is not %s" % DBMS.MYSQL warnMsg = "the back-end DBMS is not %s" % DBMS.MYSQL
@ -206,7 +206,7 @@ class Fingerprint(GenericFingerprint):
elif inject.checkBooleanExpression("@@table_open_cache=@@table_open_cache"): elif inject.checkBooleanExpression("@@table_open_cache=@@table_open_cache"):
if inject.checkBooleanExpression("%s=(SELECT %s FROM information_schema.GLOBAL_STATUS LIMIT 0, 1)" % (randInt, randInt)): if inject.checkBooleanExpression("%s=(SELECT %s FROM information_schema.GLOBAL_STATUS LIMIT 0, 1)" % (randInt, randInt)):
Backend.setVersionList([">= 5.1.12", "< 5.5.0"]) Backend.setVersionList([">= 5.1.12", "< 5.5.0"])
elif inject.checkBooleanExpression("%s=(SELECT %s FROM information_schema.PROCESSLIST LIMIT 0, 1)" % (randInt,randInt)): elif inject.checkBooleanExpression("%s=(SELECT %s FROM information_schema.PROCESSLIST LIMIT 0, 1)" % (randInt, randInt)):
Backend.setVersionList([">= 5.1.7", "< 5.1.12"]) Backend.setVersionList([">= 5.1.7", "< 5.1.12"])
elif inject.checkBooleanExpression("%s=(SELECT %s FROM information_schema.PARTITIONS LIMIT 0, 1)" % (randInt, randInt)): elif inject.checkBooleanExpression("%s=(SELECT %s FROM information_schema.PARTITIONS LIMIT 0, 1)" % (randInt, randInt)):
Backend.setVersion("= 5.1.6") Backend.setVersion("= 5.1.6")

View File

@ -64,10 +64,8 @@ class Connector(GenericConnector):
try: try:
self.cursor.execute(utf8encode(query)) self.cursor.execute(utf8encode(query))
retVal = True retVal = True
except (cx_Oracle.DatabaseError), msg: except cx_Oracle.DatabaseError, msg:
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % msg) logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % msg)
except cx_Oracle.InternalError, msg:
raise SqlmapConnectionException(msg)
self.connector.commit() self.connector.commit()

View File

@ -24,10 +24,10 @@ class PostgreSQLMap(Syntax, Fingerprint, Enumeration, Filesystem, Miscellaneous,
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)

View File

@ -39,7 +39,7 @@ class Syntax(GenericSyntax):
break break
firstIndex = index firstIndex = index
index = expression[firstIndex+2:].find("'") index = expression[firstIndex + 2:].find("'")
if index == -1: if index == -1:
raise SqlmapSyntaxException("Unenclosed ' in '%s'" % expression) raise SqlmapSyntaxException("Unenclosed ' in '%s'" % expression)
@ -49,8 +49,8 @@ class Syntax(GenericSyntax):
oldUpper = old.upper() oldUpper = old.upper()
oldUpper = oldUpper.replace("X'", "").replace("'", "") oldUpper = oldUpper.replace("X'", "").replace("'", "")
for i in xrange(len(oldUpper)/2): for i in xrange(len(oldUpper) / 2):
char = oldUpper[i*2:i*2+2] char = oldUpper[i * 2:i * 2 + 2]
escaped = "'%s'" % chr(int(char, 16)) escaped = "'%s'" % chr(int(char, 16))
expression = expression.replace(old, escaped) expression = expression.replace(old, escaped)

View File

@ -60,7 +60,7 @@ class Enumeration(GenericEnumeration):
areAdmins = set() areAdmins = set()
if conf.user: if conf.user:
users = [ conf.user ] users = [conf.user]
elif not len(kb.data.cachedUsers): elif not len(kb.data.cachedUsers):
users = self.getUsers() users = self.getUsers()
else: else:
@ -221,7 +221,7 @@ class Enumeration(GenericEnumeration):
if colList: if colList:
table = {} table = {}
table[safeSQLIdentificatorNaming(tbl)] = dict(map(lambda x: (x, None), colList)) table[safeSQLIdentificatorNaming(tbl)] = dict((_, None) for _ in colList)
kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)] = table kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)] = table
continue continue
@ -233,7 +233,7 @@ class Enumeration(GenericEnumeration):
for blind in blinds: for blind in blinds:
randStr = randomStr() randStr = randomStr()
query = rootQuery.inband.query % (conf.db, conf.db, conf.db, conf.db, conf.db, conf.db, conf.db, unsafeSQLIdentificatorNaming(tbl)) query = rootQuery.inband.query % (conf.db, conf.db, conf.db, conf.db, conf.db, conf.db, conf.db, unsafeSQLIdentificatorNaming(tbl))
retVal = pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.name' % randStr,'%s.usertype' % randStr], blind=blind) retVal = pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.name' % randStr, '%s.usertype' % randStr], blind=blind)
if retVal: if retVal:
table = {} table = {}

View File

@ -13,6 +13,7 @@ from lib.core.common import getLimitRange
from lib.core.common import isInferenceAvailable from lib.core.common import isInferenceAvailable
from lib.core.common import isListLike from lib.core.common import isListLike
from lib.core.common import isNoneValue from lib.core.common import isNoneValue
from lib.core.common import isNullValue
from lib.core.common import isNumPosStrValue from lib.core.common import isNumPosStrValue
from lib.core.common import isTechniqueAvailable from lib.core.common import isTechniqueAvailable
from lib.core.common import parseSqliteTableSchema from lib.core.common import parseSqliteTableSchema
@ -275,7 +276,7 @@ class Databases:
values = filter(None, arrayizeValue(values)) values = filter(None, arrayizeValue(values))
if len(values) > 0 and not isListLike(values[0]): if len(values) > 0 and not isListLike(values[0]):
values = map(lambda x: (dbs[0], x), values) values = [(dbs[0], _) for _ in values]
for db, table in filterPairValues(values): for db, table in filterPairValues(values):
db = safeSQLIdentificatorNaming(db) db = safeSQLIdentificatorNaming(db)
@ -524,6 +525,17 @@ class Databases:
values = inject.getValue(query, blind=False, time=False) values = inject.getValue(query, blind=False, time=False)
if Backend.isDbms(DBMS.MSSQL) and isNoneValue(values):
index, values = 1, []
while True:
query = rootQuery.inband.query2 % (conf.db, tbl, index)
value = unArrayizeValue(inject.getValue(query, blind=False, time=False))
if isNoneValue(value) or value == " ":
break
else:
values.append((value,))
index += 1
if Backend.isDbms(DBMS.SQLITE): if Backend.isDbms(DBMS.SQLITE):
parseSqliteTableSchema(unArrayizeValue(values)) parseSqliteTableSchema(unArrayizeValue(values))
elif not isNoneValue(values): elif not isNoneValue(values):
@ -536,7 +548,7 @@ class Databases:
if name: if name:
if len(columnData) == 1: if len(columnData) == 1:
columns[name] = "" columns[name] = None
else: else:
columns[name] = columnData[1] columns[name] = columnData[1]
@ -600,17 +612,28 @@ class Databases:
count = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS) count = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)
if not isNumPosStrValue(count):
errMsg = "unable to retrieve the number of columns "
errMsg += "for table '%s' " % unsafeSQLIdentificatorNaming(tbl)
errMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
logger.error(errMsg)
continue
table = {} table = {}
columns = {} columns = {}
if not isNumPosStrValue(count):
if Backend.isDbms(DBMS.MSSQL):
count, index, values = 0, 1, []
while True:
query = rootQuery.blind.query3 % (conf.db, tbl, index)
value = unArrayizeValue(inject.getValue(query, union=False, error=False))
if isNoneValue(value) or value == " ":
break
else:
columns[safeSQLIdentificatorNaming(value)] = None
index += 1
if not columns:
errMsg = "unable to retrieve the %scolumns " % ("number of " if not Backend.isDbms(DBMS.MSSQL) else "")
errMsg += "for table '%s' " % unsafeSQLIdentificatorNaming(tbl)
errMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
logger.error(errMsg)
continue
for index in getLimitRange(count): for index in getLimitRange(count):
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL): if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL):
query = rootQuery.blind.query % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db)) query = rootQuery.blind.query % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db))

View File

@ -6,7 +6,6 @@ See the file 'doc/COPYING' for copying permission
""" """
import os import os
import tempfile
from lib.core.agent import agent from lib.core.agent import agent
from lib.core.common import dataToOutFile from lib.core.common import dataToOutFile
@ -16,7 +15,6 @@ from lib.core.common import decodeHexValue
from lib.core.common import isNumPosStrValue from lib.core.common import isNumPosStrValue
from lib.core.common import isListLike from lib.core.common import isListLike
from lib.core.common import isTechniqueAvailable from lib.core.common import isTechniqueAvailable
from lib.core.common import randomStr
from lib.core.common import readInput from lib.core.common import readInput
from lib.core.data import conf from lib.core.data import conf
from lib.core.data import kb from lib.core.data import kb
@ -117,7 +115,7 @@ class Filesystem:
if not single: if not single:
if len(content) > 256: if len(content) > 256:
for i in xrange(0, len(content), 256): for i in xrange(0, len(content), 256):
_ = content[i:i+256] _ = content[i:i + 256]
if encoding == "hex": if encoding == "hex":
_ = "0x%s" % _ _ = "0x%s" % _
@ -132,7 +130,7 @@ class Filesystem:
elif encoding == "base64": elif encoding == "base64":
content = "'%s'" % content content = "'%s'" % content
retVal = [ content ] retVal = [content]
return retVal return retVal

View File

@ -184,9 +184,9 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
goUdf = True goUdf = True
if goUdf: if goUdf:
exitfunc="thread" exitfunc = "thread"
else: else:
exitfunc="process" exitfunc = "process"
self.createMsfShellcode(exitfunc=exitfunc, format="raw", extra="BufferRegister=EAX", encode="x86/alpha_mixed") self.createMsfShellcode(exitfunc=exitfunc, format="raw", extra="BufferRegister=EAX", encode="x86/alpha_mixed")

0
procs/README.txt Executable file → Normal file
View File

0
sqlmap.py Executable file → Normal file
View File

0
sqlmapapi.py Executable file → Normal file
View File

View File

@ -5,4 +5,4 @@ Copyright (c) 2006-2012 sqlmap developers (http://sqlmap.org/)
See the file 'doc/COPYING' for copying permission See the file 'doc/COPYING' for copying permission
""" """
pass pass

View File

@ -55,9 +55,9 @@ def tamper(payload, **kwargs):
doublequote = not doublequote doublequote = not doublequote
elif payload[i] == ">" and not doublequote and not quote: elif payload[i] == ">" and not doublequote and not quote:
retVal += " " if i > 0 and not payload[i-1].isspace() else "" retVal += " " if i > 0 and not payload[i - 1].isspace() else ""
retVal += "NOT BETWEEN %s AND" % ('0' if re.search(r"\A[^\w]*\d", payload[i+1:]) else "NULL") retVal += "NOT BETWEEN %s AND" % ('0' if re.search(r"\A[^\w]*\d", payload[i + 1:]) else "NULL")
retVal += " " if i < len(payload) - 1 and not payload[i+1:i+2].isspace() else "" retVal += " " if i < len(payload) - 1 and not payload[i + 1:i + 2].isspace() else ""
continue continue

View File

@ -36,8 +36,8 @@ def tamper(payload, **kwargs):
i = 0 i = 0
while i < len(payload): while i < len(payload):
if payload[i] == '%' and (i < len(payload) - 2) and payload[i+1:i+2] in string.hexdigits and payload[i+2:i+3] in string.hexdigits: if payload[i] == '%' and (i < len(payload) - 2) and payload[i + 1:i + 2] in string.hexdigits and payload[i + 2:i + 3] in string.hexdigits:
retVal += payload[i:i+3] retVal += payload[i:i + 3]
i += 3 i += 3
else: else:
retVal += '%%25%.2X' % ord(payload[i]) retVal += '%%25%.2X' % ord(payload[i])

View File

@ -43,8 +43,8 @@ def tamper(payload, **kwargs):
i = 0 i = 0
while i < len(payload): while i < len(payload):
if payload[i] == '%' and (i < len(payload) - 2) and payload[i+1:i+2] in string.hexdigits and payload[i+2:i+3] in string.hexdigits: if payload[i] == '%' and (i < len(payload) - 2) and payload[i + 1:i + 2] in string.hexdigits and payload[i + 2:i + 3] in string.hexdigits:
retVal += payload[i:i+3] retVal += payload[i:i + 3]
i += 3 i += 3
else: else:
retVal += '%%%.2X' % ord(payload[i]) retVal += '%%%.2X' % ord(payload[i])

View File

@ -48,8 +48,8 @@ def tamper(payload, **kwargs):
i = 0 i = 0
while i < len(payload): while i < len(payload):
if payload[i] == '%' and (i < len(payload) - 2) and payload[i+1:i+2] in string.hexdigits and payload[i+2:i+3] in string.hexdigits: if payload[i] == '%' and (i < len(payload) - 2) and payload[i + 1:i + 2] in string.hexdigits and payload[i + 2:i + 3] in string.hexdigits:
retVal += "%%u00%s" % payload[i+1:i+3] retVal += "%%u00%s" % payload[i + 1:i + 3]
i += 3 i += 3
else: else:
retVal += '%%u%.4X' % ord(payload[i]) retVal += '%%u%.4X' % ord(payload[i])

View File

@ -57,7 +57,7 @@ def tamper(payload, **kwargs):
_ = payload[index + len("IFNULL("):comma] _ = payload[index + len("IFNULL("):comma]
__ = payload[comma + 1:end] __ = payload[comma + 1:end]
newVal = "IF(ISNULL(%s),%s,%s)" % (_, __, _) newVal = "IF(ISNULL(%s),%s,%s)" % (_, __, _)
payload = payload[:index] + newVal + payload[end+1:] payload = payload[:index] + newVal + payload[end + 1:]
else: else:
break break

View File

@ -43,7 +43,7 @@ def tamper(payload, **kwargs):
words.add(word) words.add(word)
for word in words: for word in words:
retVal = re.sub("(?<=\W)%s(?=[^A-Za-z_(]|\Z)" % word, "%s%s%s" % (' '*random.randrange(1,4), word, ' '*random.randrange(1,4)), retVal) retVal = re.sub("(?<=\W)%s(?=[^A-Za-z_(]|\Z)" % word, "%s%s%s" % (' ' * random.randrange(1, 4), word, ' ' * random.randrange(1, 4)), retVal)
retVal = re.sub("(?<=\W)%s(?=[(])" % word, "%s%s" % (' '*random.randrange(1,4), word), retVal) retVal = re.sub("(?<=\W)%s(?=[(])" % word, "%s%s" % (' ' * random.randrange(1, 4), word), retVal)
return retVal return retVal

View File

@ -41,8 +41,8 @@ def tamper(payload, **kwargs):
i = 0 i = 0
while i < len(payload): while i < len(payload):
if payload[i] == '%' and (i < len(payload) - 2) and payload[i+1:i+2] in string.hexdigits and payload[i+2:i+3] in string.hexdigits: if payload[i] == '%' and (i < len(payload) - 2) and payload[i + 1:i + 2] in string.hexdigits and payload[i + 2:i + 3] in string.hexdigits:
retVal += payload[i:i+3] retVal += payload[i:i + 3]
i += 3 i += 3
elif payload[i] != ' ': elif payload[i] != ' ':
retVal += '%%%s' % payload[i] retVal += '%%%s' % payload[i]

View File

@ -49,7 +49,7 @@ def tamper(payload, **kwargs):
elif payload[i] == '"': elif payload[i] == '"':
doublequote = not doublequote doublequote = not doublequote
elif payload[i]==" " and not doublequote and not quote: elif payload[i] == " " and not doublequote and not quote:
retVal += "/**/" retVal += "/**/"
continue continue

View File

@ -40,7 +40,7 @@ def tamper(payload, **kwargs):
if payload[i].isspace(): if payload[i].isspace():
randomStr = ''.join(random.choice(string.ascii_uppercase + string.lowercase) for _ in xrange(random.randint(6, 12))) randomStr = ''.join(random.choice(string.ascii_uppercase + string.lowercase) for _ in xrange(random.randint(6, 12)))
retVal += "--%s%%0A" % randomStr retVal += "--%s%%0A" % randomStr
elif payload[i] == '#' or payload[i:i+3] == '-- ': elif payload[i] == '#' or payload[i:i + 3] == '-- ':
retVal += payload[i:] retVal += payload[i:]
break break
else: else:

View File

@ -46,7 +46,7 @@ def tamper(payload, **kwargs):
if payload[i].isspace(): if payload[i].isspace():
randomStr = ''.join(random.choice(string.ascii_uppercase + string.lowercase) for _ in xrange(random.randint(6, 12))) randomStr = ''.join(random.choice(string.ascii_uppercase + string.lowercase) for _ in xrange(random.randint(6, 12)))
retVal += "%%23%s%%0A" % randomStr retVal += "%%23%s%%0A" % randomStr
elif payload[i] == '#' or payload[i:i+3] == '-- ': elif payload[i] == '#' or payload[i:i + 3] == '-- ':
retVal += payload[i:] retVal += payload[i:]
break break
else: else:

View File

@ -60,7 +60,7 @@ def tamper(payload, **kwargs):
if payload[i].isspace(): if payload[i].isspace():
randomStr = ''.join(random.choice(string.ascii_uppercase + string.lowercase) for _ in xrange(random.randint(6, 12))) randomStr = ''.join(random.choice(string.ascii_uppercase + string.lowercase) for _ in xrange(random.randint(6, 12)))
retVal += "%%23%s%%0A" % randomStr retVal += "%%23%s%%0A" % randomStr
elif payload[i] == '#' or payload[i:i+3] == '-- ': elif payload[i] == '#' or payload[i:i + 3] == '-- ':
retVal += payload[i:] retVal += payload[i:]
break break
else: else:

View File

@ -73,7 +73,7 @@ def tamper(payload, **kwargs):
elif payload[i] == '"': elif payload[i] == '"':
doublequote = not doublequote doublequote = not doublequote
elif payload[i] == '#' or payload[i:i+3] == '-- ': elif payload[i] == '#' or payload[i:i + 3] == '-- ':
end = True end = True
elif payload[i] == " " and not doublequote and not quote: elif payload[i] == " " and not doublequote and not quote:

View File

@ -32,7 +32,7 @@ def tamper(payload, **kwargs):
for i in xrange(len(payload)): for i in xrange(len(payload)):
if payload[i].isspace(): if payload[i].isspace():
retVal += "%23%0A" retVal += "%23%0A"
elif payload[i] == '#' or payload[i:i+3] == '-- ': elif payload[i] == '#' or payload[i:i + 3] == '-- ':
retVal += payload[i:] retVal += payload[i:]
break break
else: else:

View File

@ -41,7 +41,7 @@ def tamper(payload, **kwargs):
for i in xrange(len(payload)): for i in xrange(len(payload)):
if payload[i].isspace(): if payload[i].isspace():
retVal += "--%0A" retVal += "--%0A"
elif payload[i] == '#' or payload[i:i+3] == '-- ': elif payload[i] == '#' or payload[i:i + 3] == '-- ':
retVal += payload[i:] retVal += payload[i:]
break break
else: else:

View File

@ -45,7 +45,7 @@ def tamper(payload, **kwargs):
elif payload[i] == '"': elif payload[i] == '"':
doublequote = not doublequote doublequote = not doublequote
elif payload[i]==" " and not doublequote and not quote: elif payload[i] == " " and not doublequote and not quote:
retVal += "+" retVal += "+"
continue continue

0
thirdparty/chardet/__init__.py vendored Executable file → Normal file
View File

0
thirdparty/chardet/big5freq.py vendored Executable file → Normal file
View File

0
thirdparty/chardet/big5prober.py vendored Executable file → Normal file
View File

0
thirdparty/chardet/chardistribution.py vendored Executable file → Normal file
View File

0
thirdparty/chardet/charsetgroupprober.py vendored Executable file → Normal file
View File

0
thirdparty/chardet/charsetprober.py vendored Executable file → Normal file
View File

0
thirdparty/chardet/codingstatemachine.py vendored Executable file → Normal file
View File

0
thirdparty/chardet/constants.py vendored Executable file → Normal file
View File

0
thirdparty/chardet/escprober.py vendored Executable file → Normal file
View File

0
thirdparty/chardet/escsm.py vendored Executable file → Normal file
View File

Some files were not shown because too many files have changed in this diff Show More