Merge remote-tracking branch 'sqlmapproject/master'

This commit is contained in:
cxh852456 2016-05-25 09:51:48 +08:00
commit 07842bac9e
29 changed files with 117 additions and 97 deletions

View File

@ -33,7 +33,7 @@ To get a list of all options and switches use:
python sqlmap.py -hh python sqlmap.py -hh
You can find a sample run [here](https://gist.github.com/stamparm/5335217). You can find a sample run [here](https://asciinema.org/a/46601).
To get an overview of sqlmap capabilities, list of supported features and description of all options and switches, along with examples, you are advised to consult the [user's manual](https://github.com/sqlmapproject/sqlmap/wiki). To get an overview of sqlmap capabilities, list of supported features and description of all options and switches, along with examples, you are advised to consult the [user's manual](https://github.com/sqlmapproject/sqlmap/wiki).
Links Links

View File

@ -32,7 +32,7 @@ Para obtener una lista de todas las opciones:
python sqlmap.py -hh python sqlmap.py -hh
Se puede encontrar una muestra de su funcionamiento [aquí](https://gist.github.com/stamparm/5335217). Se puede encontrar una muestra de su funcionamiento [aquí](https://asciinema.org/a/46601).
Para obtener una visión general de las capacidades de sqlmap, así como un listado funciones soportadas y descripción de todas las opciones y modificadores, junto con ejemplos, se recomienda consultar el [manual de usuario](https://github.com/sqlmapproject/sqlmap/wiki). Para obtener una visión general de las capacidades de sqlmap, así como un listado funciones soportadas y descripción de todas las opciones y modificadores, junto con ejemplos, se recomienda consultar el [manual de usuario](https://github.com/sqlmapproject/sqlmap/wiki).
Enlaces Enlaces

View File

@ -33,7 +33,7 @@
python sqlmap.py -hh python sqlmap.py -hh
Μπορείτε να δείτε ένα δείγμα λειτουργίας του προγράμματος [εδώ](https://gist.github.com/stamparm/5335217). Μπορείτε να δείτε ένα δείγμα λειτουργίας του προγράμματος [εδώ](https://asciinema.org/a/46601).
Για μια γενικότερη άποψη των δυνατοτήτων του sqlmap, μια λίστα των υποστηριζόμενων χαρακτηριστικών και περιγραφή για όλες τις επιλογές, μαζί με παραδείγματα, καλείστε να συμβουλευτείτε το [εγχειρίδιο χρήστη](https://github.com/sqlmapproject/sqlmap/wiki). Για μια γενικότερη άποψη των δυνατοτήτων του sqlmap, μια λίστα των υποστηριζόμενων χαρακτηριστικών και περιγραφή για όλες τις επιλογές, μαζί με παραδείγματα, καλείστε να συμβουλευτείτε το [εγχειρίδιο χρήστη](https://github.com/sqlmapproject/sqlmap/wiki).
Σύνδεσμοι Σύνδεσμοι

View File

@ -33,7 +33,7 @@ Kako biste dobili listu svih opcija i prekidača koristite:
python sqlmap.py -hh python sqlmap.py -hh
Možete pronaći primjer izvršavanja [ovdje](https://gist.github.com/stamparm/5335217). Možete pronaći primjer izvršavanja [ovdje](https://asciinema.org/a/46601).
Kako biste dobili pregled mogućnosti sqlmap-a, liste podržanih značajki te opis svih opcija i prekidača, zajedno s primjerima, preporučen je uvid u [korisnički priručnik](https://github.com/sqlmapproject/sqlmap/wiki). Kako biste dobili pregled mogućnosti sqlmap-a, liste podržanih značajki te opis svih opcija i prekidača, zajedno s primjerima, preporučen je uvid u [korisnički priručnik](https://github.com/sqlmapproject/sqlmap/wiki).
Poveznice Poveznice

View File

@ -34,7 +34,7 @@ Untuk mendapatkan daftar opsi lanjut gunakan:
python sqlmap.py -hh python sqlmap.py -hh
Anda dapat mendapatkan contoh penggunaan [di sini](https://gist.github.com/stamparm/5335217). Anda dapat mendapatkan contoh penggunaan [di sini](https://asciinema.org/a/46601).
Untuk mendapatkan gambaran singkat kemampuan sqlmap, daftar fitur yang didukung, deskripsi dari semua opsi, berikut dengan contohnya, Anda disarankan untuk membaca [manual pengguna](https://github.com/sqlmapproject/sqlmap/wiki). Untuk mendapatkan gambaran singkat kemampuan sqlmap, daftar fitur yang didukung, deskripsi dari semua opsi, berikut dengan contohnya, Anda disarankan untuk membaca [manual pengguna](https://github.com/sqlmapproject/sqlmap/wiki).
Tautan Tautan

View File

@ -34,7 +34,7 @@ Para obter a lista completa de opções faça:
python sqlmap.py -hh python sqlmap.py -hh
Você pode encontrar alguns exemplos [aqui](https://gist.github.com/stamparm/5335217). Você pode encontrar alguns exemplos [aqui](https://asciinema.org/a/46601).
Para ter uma visão geral dos recursos do sqlmap, lista de recursos suportados e a descrição de todas as opções, juntamente com exemplos, aconselhamos que você consulte o [manual do usuário](https://github.com/sqlmapproject/sqlmap/wiki). Para ter uma visão geral dos recursos do sqlmap, lista de recursos suportados e a descrição de todas as opções, juntamente com exemplos, aconselhamos que você consulte o [manual do usuário](https://github.com/sqlmapproject/sqlmap/wiki).
Links Links

View File

@ -37,7 +37,7 @@ Bütün seçenekleri gösterir
python sqlmap.py -hh python sqlmap.py -hh
Program ile ilgili örnekleri [burada](https://gist.github.com/stamparm/5335217) bulabilirsiniz. Daha fazlası içinsqlmap'in bütün açıklamaları ile birlikte bütün özelliklerinin, örnekleri ile bulunduğu [manuel sayfamıza](https://github.com/sqlmapproject/sqlmap/wiki) bakmanızı tavsiye ediyoruz Program ile ilgili örnekleri [burada](https://asciinema.org/a/46601) bulabilirsiniz. Daha fazlası içinsqlmap'in bütün açıklamaları ile birlikte bütün özelliklerinin, örnekleri ile bulunduğu [manuel sayfamıza](https://github.com/sqlmapproject/sqlmap/wiki) bakmanızı tavsiye ediyoruz
Links Links
---- ----

View File

@ -33,7 +33,7 @@ sqlmap 可以运行在 [Python](http://www.python.org/download/) **2.6.x** 和
python sqlmap.py -hh python sqlmap.py -hh
你可以从 [这里](https://gist.github.com/stamparm/5335217) 看到一个sqlmap 的使用样例。除此以外,你还可以查看 [使用手册](https://github.com/sqlmapproject/sqlmap/wiki)。获取sqlmap所有支持的特性、参数、命令行选项开关及说明的使用帮助。 你可以从 [这里](https://asciinema.org/a/46601) 看到一个sqlmap 的使用样例。除此以外,你还可以查看 [使用手册](https://github.com/sqlmapproject/sqlmap/wiki)。获取sqlmap所有支持的特性、参数、命令行选项开关及说明的使用帮助。
链接 链接
---- ----

View File

@ -98,6 +98,9 @@ def checkSqlInjection(place, parameter, value):
tests = getSortedInjectionTests() tests = getSortedInjectionTests()
seenPayload = set() seenPayload = set()
kb.data.setdefault("randomInt", str(randomInt(10)))
kb.data.setdefault("randomStr", str(randomStr(10)))
while tests: while tests:
test = tests.pop(0) test = tests.pop(0)
@ -174,10 +177,11 @@ def checkSqlInjection(place, parameter, value):
lower, upper = int(match.group(1)), int(match.group(2)) lower, upper = int(match.group(1)), int(match.group(2))
for _ in (lower, upper): for _ in (lower, upper):
if _ > 1: if _ > 1:
__ = 2 * (_ - 1) + 1 if _ == lower else 2 * _
unionExtended = True unionExtended = True
test.request.columns = re.sub(r"\b%d\b" % _, str(2 * _), test.request.columns) test.request.columns = re.sub(r"\b%d\b" % _, str(__), test.request.columns)
title = re.sub(r"\b%d\b" % _, str(2 * _), title) title = re.sub(r"\b%d\b" % _, str(__), title)
test.title = re.sub(r"\b%d\b" % _, str(2 * _), test.title) test.title = re.sub(r"\b%d\b" % _, str(__), test.title)
# Skip test if the user's wants to test only for a specific # Skip test if the user's wants to test only for a specific
# technique # technique
@ -381,8 +385,6 @@ def checkSqlInjection(place, parameter, value):
# Use different page template than the original # Use different page template than the original
# one as we are changing parameters value, which # one as we are changing parameters value, which
# will likely result in a different content # will likely result in a different content
kb.data.setdefault("randomInt", str(randomInt(10)))
kb.data.setdefault("randomStr", str(randomStr(10)))
if conf.invalidLogical: if conf.invalidLogical:
_ = int(kb.data.randomInt[:2]) _ = int(kb.data.randomInt[:2])
@ -462,19 +464,28 @@ def checkSqlInjection(place, parameter, value):
if errorResult: if errorResult:
continue continue
infoMsg = "%s parameter '%s' seems to be '%s' injectable " % (paramType, parameter, title) infoMsg = "%s parameter '%s' appears to be '%s' injectable " % (paramType, parameter, title)
logger.info(infoMsg) logger.info(infoMsg)
injectable = True injectable = True
if not injectable and not any((conf.string, conf.notString, conf.regexp)) and kb.pageStable: if not injectable and not any((conf.string, conf.notString, conf.regexp)) and kb.pageStable:
trueSet = set(extractTextTagContent(truePage)) trueSet = set(extractTextTagContent(truePage))
trueSet = trueSet.union(__ for _ in trueSet for __ in _.split())
falseSet = set(extractTextTagContent(falsePage)) falseSet = set(extractTextTagContent(falsePage))
falseSet = falseSet.union(__ for _ in falseSet for __ in _.split())
candidates = filter(None, (_.strip() if _.strip() in (kb.pageTemplate or "") and _.strip() not in falsePage and _.strip() not in threadData.lastComparisonHeaders else None for _ in (trueSet - falseSet))) candidates = filter(None, (_.strip() if _.strip() in (kb.pageTemplate or "") and _.strip() not in falsePage and _.strip() not in threadData.lastComparisonHeaders else None for _ in (trueSet - falseSet)))
if candidates: if candidates:
conf.string = candidates[0] candidates = sorted(candidates, key=lambda _: len(_))
infoMsg = "%s parameter '%s' seems to be '%s' injectable (with --string=\"%s\")" % (paramType, parameter, title, repr(conf.string).lstrip('u').strip("'")) for candidate in candidates:
if re.match(r"\A\w+\Z", candidate):
break
conf.string = candidate
infoMsg = "%s parameter '%s' appears to be '%s' injectable (with --string=\"%s\")" % (paramType, parameter, title, repr(conf.string).lstrip('u').strip("'"))
logger.info(infoMsg) logger.info(infoMsg)
injectable = True injectable = True
@ -519,7 +530,7 @@ def checkSqlInjection(place, parameter, value):
trueResult = Request.queryPage(reqPayload, place, timeBasedCompare=True, raise404=False) trueResult = Request.queryPage(reqPayload, place, timeBasedCompare=True, raise404=False)
if trueResult: if trueResult:
infoMsg = "%s parameter '%s' seems to be '%s' injectable " % (paramType, parameter, title) infoMsg = "%s parameter '%s' appears to be '%s' injectable " % (paramType, parameter, title)
logger.info(infoMsg) logger.info(infoMsg)
injectable = True injectable = True
@ -692,14 +703,15 @@ def checkSqlInjection(place, parameter, value):
# Return the injection object # Return the injection object
if injection.place is not None and injection.parameter is not None: if injection.place is not None and injection.parameter is not None:
if not conf.dropSetCookie and PAYLOAD.TECHNIQUE.BOOLEAN in injection.data and injection.data[PAYLOAD.TECHNIQUE.BOOLEAN].vector.startswith('OR'): if not conf.dropSetCookie and PAYLOAD.TECHNIQUE.BOOLEAN in injection.data and injection.data[PAYLOAD.TECHNIQUE.BOOLEAN].vector.startswith('OR'):
warnMsg = "in OR boolean-based injections, please consider usage " warnMsg = "in OR boolean-based injection cases, please consider usage "
warnMsg += "of switch '--drop-set-cookie' if you experience any " warnMsg += "of switch '--drop-set-cookie' if you experience any "
warnMsg += "problems during data retrieval" warnMsg += "problems during data retrieval"
logger.warn(warnMsg) logger.warn(warnMsg)
if not checkFalsePositives(injection): if not checkFalsePositives(injection):
kb.vulnHosts.remove(conf.hostname) kb.vulnHosts.remove(conf.hostname)
injection.notes.add(NOTE.FALSE_POSITIVE_OR_UNEXPLOITABLE) if NOTE.FALSE_POSITIVE_OR_UNEXPLOITABLE not in injection.notes:
injection.notes.append(NOTE.FALSE_POSITIVE_OR_UNEXPLOITABLE)
else: else:
injection = None injection = None
@ -1288,7 +1300,7 @@ def identifyWaf():
if output and output[0] not in ("Y", "y"): if output and output[0] not in ("Y", "y"):
raise SqlmapUserQuitException raise SqlmapUserQuitException
else: else:
warnMsg = "no WAF/IDS/IPS product has been identified (this doesn't mean that there is none)" warnMsg = "WAF/IDS/IPS product hasn't been identified (generic protection response)"
logger.warn(warnMsg) logger.warn(warnMsg)
kb.testType = None kb.testType = None

View File

@ -226,15 +226,15 @@ def _saveToResultsFile():
results = {} results = {}
techniques = dict(map(lambda x: (x[1], x[0]), getPublicTypeMembers(PAYLOAD.TECHNIQUE))) techniques = dict(map(lambda x: (x[1], x[0]), getPublicTypeMembers(PAYLOAD.TECHNIQUE)))
for inj in kb.injections + kb.falsePositives: for injection in kb.injections + kb.falsePositives:
if inj.place is None or inj.parameter is None: if injection.place is None or injection.parameter is None:
continue continue
key = (inj.place, inj.parameter, ';'.join(inj.notes)) key = (injection.place, injection.parameter, ';'.join(injection.notes))
if key not in results: if key not in results:
results[key] = [] results[key] = []
results[key].extend(inj.data.keys()) results[key].extend(injection.data.keys())
for key, value in results.items(): for key, value in results.items():
place, parameter, notes = key place, parameter, notes = key

View File

@ -102,7 +102,7 @@ class Agent(object):
if place == PLACE.URI: if place == PLACE.URI:
origValue = origValue.split(CUSTOM_INJECTION_MARK_CHAR)[0] origValue = origValue.split(CUSTOM_INJECTION_MARK_CHAR)[0]
else: else:
origValue = re.search(r"\w+\Z", origValue.split(BOUNDED_INJECTION_MARKER)[0]).group(0) origValue = filter(None, (re.search(_, origValue.split(BOUNDED_INJECTION_MARKER)[0]) for _ in (r"\w+\Z", r"[^\"'><]+\Z", r"[^ ]+\Z")))[0].group(0)
origValue = origValue[origValue.rfind('/') + 1:] origValue = origValue[origValue.rfind('/') + 1:]
for char in ('?', '=', ':'): for char in ('?', '=', ':'):
if char in origValue: if char in origValue:

View File

@ -304,7 +304,7 @@ class Backend:
# Little precaution, in theory this condition should always be false # Little precaution, in theory this condition should always be false
elif kb.dbms is not None and kb.dbms != dbms: elif kb.dbms is not None and kb.dbms != dbms:
warnMsg = "there seems to be a high probability that " warnMsg = "there appears to be a high probability that "
warnMsg += "this could be a false positive case" warnMsg += "this could be a false positive case"
logger.warn(warnMsg) logger.warn(warnMsg)
@ -581,7 +581,7 @@ def paramToDict(place, parameters=None):
if not conf.multipleTargets and not (conf.csrfToken and parameter == conf.csrfToken): if not conf.multipleTargets and not (conf.csrfToken and parameter == conf.csrfToken):
_ = urldecode(testableParameters[parameter], convall=True) _ = urldecode(testableParameters[parameter], convall=True)
if (_.endswith("'") and _.count("'") == 1 if (_.endswith("'") and _.count("'") == 1
or re.search(r'\A9{3,}', _) or re.search(DUMMY_USER_INJECTION, _))\ or re.search(r'\A9{3,}', _) or re.search(r'\A-\d+\Z', _) or re.search(DUMMY_USER_INJECTION, _))\
and not parameter.upper().startswith(GOOGLE_ANALYTICS_COOKIE_PREFIX): and not parameter.upper().startswith(GOOGLE_ANALYTICS_COOKIE_PREFIX):
warnMsg = "it appears that you have provided tainted parameter values " warnMsg = "it appears that you have provided tainted parameter values "
warnMsg += "('%s') with most probably leftover " % element warnMsg += "('%s') with most probably leftover " % element
@ -650,7 +650,8 @@ def paramToDict(place, parameters=None):
testableParameters[parameter] = re.sub(regex, "\g<1>%s\g<2>" % BOUNDED_INJECTION_MARKER, testableParameters[parameter]) testableParameters[parameter] = re.sub(regex, "\g<1>%s\g<2>" % BOUNDED_INJECTION_MARKER, testableParameters[parameter])
break break
if conf.testParameter and not testableParameters: if conf.testParameter:
if not testableParameters:
paramStr = ", ".join(test for test in conf.testParameter) paramStr = ", ".join(test for test in conf.testParameter)
if len(conf.testParameter) > 1: if len(conf.testParameter) > 1:
@ -680,7 +681,7 @@ def paramToDict(place, parameters=None):
decoded = value.decode(encoding) decoded = value.decode(encoding)
if len(decoded) > MIN_ENCODED_LEN_CHECK and all(_ in string.printable for _ in decoded): if len(decoded) > MIN_ENCODED_LEN_CHECK and all(_ in string.printable for _ in decoded):
warnMsg = "provided parameter '%s' " % parameter warnMsg = "provided parameter '%s' " % parameter
warnMsg += "seems to be '%s' encoded" % encoding warnMsg += "appears to be '%s' encoded" % encoding
logger.warn(warnMsg) logger.warn(warnMsg)
break break
except: except:
@ -767,8 +768,13 @@ def getManualDirectories():
for suffix in BRUTE_DOC_ROOT_SUFFIXES: for suffix in BRUTE_DOC_ROOT_SUFFIXES:
for target in targets: for target in targets:
if not prefix.endswith("/%s" % suffix):
item = "%s/%s" % (prefix, suffix) item = "%s/%s" % (prefix, suffix)
else:
item = prefix
item = item.replace(BRUTE_DOC_ROOT_TARGET_MARK, target).replace("//", '/').rstrip('/') item = item.replace(BRUTE_DOC_ROOT_TARGET_MARK, target).replace("//", '/').rstrip('/')
if item not in directories:
directories.append(item) directories.append(item)
if BRUTE_DOC_ROOT_TARGET_MARK not in prefix: if BRUTE_DOC_ROOT_TARGET_MARK not in prefix:
@ -1374,8 +1380,8 @@ def parseTargetUrl():
except UnicodeError: except UnicodeError:
_ = None _ = None
if any((_ is None, re.search(r'\s', conf.hostname), '..' in conf.hostname, conf.hostname.startswith('.'))): if any((_ is None, re.search(r'\s', conf.hostname), '..' in conf.hostname, conf.hostname.startswith('.'), '\n' in originalUrl)):
errMsg = "invalid target URL" errMsg = "invalid target URL ('%s')" % originalUrl
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
if len(hostnamePort) == 2: if len(hostnamePort) == 2:
@ -1903,7 +1909,7 @@ def parseXmlFile(xmlFile, handler):
with contextlib.closing(StringIO(readCachedFileContent(xmlFile))) as stream: with contextlib.closing(StringIO(readCachedFileContent(xmlFile))) as stream:
parse(stream, handler) parse(stream, handler)
except (SAXParseException, UnicodeError), ex: except (SAXParseException, UnicodeError), ex:
errMsg = "something seems to be wrong with " errMsg = "something appears to be wrong with "
errMsg += "the file '%s' ('%s'). Please make " % (xmlFile, getSafeExString(ex)) errMsg += "the file '%s' ('%s'). Please make " % (xmlFile, getSafeExString(ex))
errMsg += "sure that you haven't made any changes to it" errMsg += "sure that you haven't made any changes to it"
raise SqlmapInstallationException, errMsg raise SqlmapInstallationException, errMsg
@ -2858,7 +2864,7 @@ def setOptimize():
conf.nullConnection = not any((conf.data, conf.textOnly, conf.titles, conf.string, conf.notString, conf.regexp, conf.tor)) conf.nullConnection = not any((conf.data, conf.textOnly, conf.titles, conf.string, conf.notString, conf.regexp, conf.tor))
if not conf.nullConnection: if not conf.nullConnection:
debugMsg = "turning off --null-connection switch used indirectly by switch -o" debugMsg = "turning off switch '--null-connection' used indirectly by switch '-o'"
logger.debug(debugMsg) logger.debug(debugMsg)
def initTechnique(technique=None): def initTechnique(technique=None):
@ -3046,7 +3052,10 @@ def decodeIntToUnicode(value):
_ = "0%s" % _ _ = "0%s" % _
raw = hexdecode(_) raw = hexdecode(_)
if Backend.isDbms(DBMS.MSSQL): if Backend.isDbms(DBMS.MYSQL):
# https://github.com/sqlmapproject/sqlmap/issues/1531
retVal = getUnicode(raw, conf.charset or UNICODE_ENCODING)
elif Backend.isDbms(DBMS.MSSQL):
retVal = getUnicode(raw, "UTF-16-BE") retVal = getUnicode(raw, "UTF-16-BE")
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.ORACLE): elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.ORACLE):
retVal = unichr(value) retVal = unichr(value)

View File

@ -8,8 +8,6 @@ See the file 'doc/COPYING' for copying permission
import copy import copy
import types import types
from lib.core.exception import SqlmapDataException
class AttribDict(dict): class AttribDict(dict):
""" """
This class defines the sqlmap object, inheriting from Python data This class defines the sqlmap object, inheriting from Python data
@ -43,7 +41,7 @@ class AttribDict(dict):
try: try:
return self.__getitem__(item) return self.__getitem__(item)
except KeyError: except KeyError:
raise SqlmapDataException("unable to access item '%s'" % item) raise AttributeError("unable to access item '%s'" % item)
def __setattr__(self, item, value): def __setattr__(self, item, value):
""" """
@ -93,7 +91,7 @@ class InjectionDict(AttribDict):
self.prefix = None self.prefix = None
self.suffix = None self.suffix = None
self.clause = None self.clause = None
self.notes = set() self.notes = [] # Note: https://github.com/sqlmapproject/sqlmap/issues/1888
# data is a dict with various stype, each which is a dict with # data is a dict with various stype, each which is a dict with
# all the information specific for that stype # all the information specific for that stype

View File

@ -234,6 +234,6 @@ DUMP_DATA_PREPROCESS = {
} }
DEFAULT_DOC_ROOTS = { DEFAULT_DOC_ROOTS = {
OS.WINDOWS: ("C:/xampp/htdocs/", "C:/Inetpub/wwwroot/"), OS.WINDOWS: ("C:/xampp/htdocs/", "C:/wamp/www/", "C:/Inetpub/wwwroot/"),
OS.LINUX: ("/var/www/", "/var/www/html", "/usr/local/apache2/htdocs", "/var/www/nginx-default") # Reference: https://wiki.apache.org/httpd/DistrosDefaultLayout OS.LINUX: ("/var/www/", "/var/www/html", "/usr/local/apache2/htdocs", "/var/www/nginx-default", "/srv/www") # Reference: https://wiki.apache.org/httpd/DistrosDefaultLayout
} }

View File

@ -385,7 +385,7 @@ def _loadQueries():
try: try:
tree.parse(paths.QUERIES_XML) tree.parse(paths.QUERIES_XML)
except Exception, ex: except Exception, ex:
errMsg = "something seems to be wrong with " errMsg = "something appears to be wrong with "
errMsg += "the file '%s' ('%s'). Please make " % (paths.QUERIES_XML, getSafeExString(ex)) errMsg += "the file '%s' ('%s'). Please make " % (paths.QUERIES_XML, getSafeExString(ex))
errMsg += "sure that you haven't made any changes to it" errMsg += "sure that you haven't made any changes to it"
raise SqlmapInstallationException, errMsg raise SqlmapInstallationException, errMsg
@ -926,7 +926,7 @@ def _setTamperingFunctions():
function.func_name = module.__name__ function.func_name = module.__name__
if check_priority and priority > last_priority: if check_priority and priority > last_priority:
message = "it seems that you might have mixed " message = "it appears that you might have mixed "
message += "the order of tamper scripts. " message += "the order of tamper scripts. "
message += "Do you want to auto resolve this? [Y/n/q] " message += "Do you want to auto resolve this? [Y/n/q] "
test = readInput(message, default="Y") test = readInput(message, default="Y")
@ -2310,7 +2310,7 @@ def _checkTor():
page = None page = None
if not page or 'Congratulations' not in page: if not page or 'Congratulations' not in page:
errMsg = "it seems that Tor is not properly set. Please try using options '--tor-type' and/or '--tor-port'" errMsg = "it appears that Tor is not properly set. Please try using options '--tor-type' and/or '--tor-port'"
raise SqlmapConnectionException(errMsg) raise SqlmapConnectionException(errMsg)
else: else:
infoMsg = "Tor is properly being used" infoMsg = "Tor is properly being used"

View File

@ -19,7 +19,7 @@ from lib.core.enums import OS
from lib.core.revision import getRevisionNumber from lib.core.revision import getRevisionNumber
# sqlmap version (<major>.<minor>.<month>.<monthly commit>) # sqlmap version (<major>.<minor>.<month>.<monthly commit>)
VERSION = "1.0.5.36" VERSION = "1.0.5.63"
REVISION = getRevisionNumber() REVISION = getRevisionNumber()
STABLE = VERSION.count('.') <= 2 STABLE = VERSION.count('.') <= 2
VERSION_STRING = "sqlmap/%s#%s" % (VERSION, "stable" if STABLE else "dev") VERSION_STRING = "sqlmap/%s#%s" % (VERSION, "stable" if STABLE else "dev")
@ -533,7 +533,7 @@ HASHDB_FLUSH_RETRIES = 3
HASHDB_END_TRANSACTION_RETRIES = 3 HASHDB_END_TRANSACTION_RETRIES = 3
# Unique milestone value used for forced deprecation of old HashDB values (e.g. when changing hash/pickle mechanism) # Unique milestone value used for forced deprecation of old HashDB values (e.g. when changing hash/pickle mechanism)
HASHDB_MILESTONE_VALUE = "zYwqRDymvj" # "".join(random.sample(string.ascii_letters, 10)) HASHDB_MILESTONE_VALUE = "ERqvmQHalF" # "".join(random.sample(string.ascii_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
@ -680,7 +680,7 @@ BRUTE_DOC_ROOT_PREFIXES = {
} }
# Suffixes used in brute force search for web server document root # Suffixes used in brute force search for web server document root
BRUTE_DOC_ROOT_SUFFIXES = ("", "html", "htdocs", "httpdocs", "php", "public", "src", "site", "build", "web", "data", "sites/all", "www/build") BRUTE_DOC_ROOT_SUFFIXES = ("", "html", "htdocs", "httpdocs", "php", "public", "src", "site", "build", "web", "www", "data", "sites/all", "www/build")
# String used for marking target name inside used brute force web server document root # String used for marking target name inside used brute force web server document root
BRUTE_DOC_ROOT_TARGET_MARK = "%TARGET%" BRUTE_DOC_ROOT_TARGET_MARK = "%TARGET%"

View File

@ -214,9 +214,9 @@ def _setRequestParams():
if re.search(URI_INJECTABLE_REGEX, conf.url, re.I) and not any(place in conf.parameters for place in (PLACE.GET, PLACE.POST)) and not kb.postHint and not CUSTOM_INJECTION_MARK_CHAR in (conf.data or "") and conf.url.startswith("http"): if re.search(URI_INJECTABLE_REGEX, conf.url, re.I) and not any(place in conf.parameters for place in (PLACE.GET, PLACE.POST)) and not kb.postHint and not CUSTOM_INJECTION_MARK_CHAR in (conf.data or "") and conf.url.startswith("http"):
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. 'http://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 option '--data'"
logger.warn(warnMsg) logger.warn(warnMsg)
message = "do you want to try URI injections " message = "do you want to try URI injections "

View File

@ -44,7 +44,7 @@ class Wordlist(object):
try: try:
_ = zipfile.ZipFile(self.current, 'r') _ = zipfile.ZipFile(self.current, 'r')
except zipfile.error, ex: except zipfile.error, ex:
errMsg = "something seems to be wrong with " errMsg = "something appears to be wrong with "
errMsg += "the file '%s' ('%s'). Please make " % (self.current, getSafeExString(ex)) errMsg += "the file '%s' ('%s'). Please make " % (self.current, getSafeExString(ex))
errMsg += "sure that you haven't made any changes to it" errMsg += "sure that you haven't made any changes to it"
raise SqlmapInstallationException, errMsg raise SqlmapInstallationException, errMsg
@ -70,7 +70,7 @@ class Wordlist(object):
try: try:
retVal = self.iter.next().rstrip() retVal = self.iter.next().rstrip()
except zipfile.error, ex: except zipfile.error, ex:
errMsg = "something seems to be wrong with " errMsg = "something appears to be wrong with "
errMsg += "the file '%s' ('%s'). Please make " % (self.current, getSafeExString(ex)) errMsg += "the file '%s' ('%s'). Please make " % (self.current, getSafeExString(ex))
errMsg += "sure that you haven't made any changes to it" errMsg += "sure that you haven't made any changes to it"
raise SqlmapInstallationException, errMsg raise SqlmapInstallationException, errMsg

View File

@ -806,12 +806,12 @@ def cmdLineParser(argv=None):
parser.formatter._format_option_strings = parser.formatter.format_option_strings parser.formatter._format_option_strings = parser.formatter.format_option_strings
parser.formatter.format_option_strings = type(parser.formatter.format_option_strings)(_, parser, type(parser)) parser.formatter.format_option_strings = type(parser.formatter.format_option_strings)(_, parser, type(parser))
# Dirty hack for making a short option -hh # Dirty hack for making a short option '-hh'
option = parser.get_option("--hh") option = parser.get_option("--hh")
option._short_opts = ["-hh"] option._short_opts = ["-hh"]
option._long_opts = [] option._long_opts = []
# Dirty hack for inherent help message of switch -h # Dirty hack for inherent help message of switch '-h'
option = parser.get_option("-h") option = parser.get_option("-h")
option.help = option.help.capitalize().replace("this help", "basic help") option.help = option.help.capitalize().replace("this help", "basic help")

View File

@ -74,7 +74,7 @@ def loadBoundaries():
try: try:
doc = et.parse(paths.BOUNDARIES_XML) doc = et.parse(paths.BOUNDARIES_XML)
except Exception, ex: except Exception, ex:
errMsg = "something seems to be wrong with " errMsg = "something appears to be wrong with "
errMsg += "the file '%s' ('%s'). Please make " % (paths.BOUNDARIES_XML, getSafeExString(ex)) errMsg += "the file '%s' ('%s'). Please make " % (paths.BOUNDARIES_XML, getSafeExString(ex))
errMsg += "sure that you haven't made any changes to it" errMsg += "sure that you haven't made any changes to it"
raise SqlmapInstallationException, errMsg raise SqlmapInstallationException, errMsg
@ -92,7 +92,7 @@ def loadPayloads():
try: try:
doc = et.parse(payloadFilePath) doc = et.parse(payloadFilePath)
except Exception, ex: except Exception, ex:
errMsg = "something seems to be wrong with " errMsg = "something appears to be wrong with "
errMsg += "the file '%s' ('%s'). Please make " % (payloadFilePath, getSafeExString(ex)) errMsg += "the file '%s' ('%s'). Please make " % (payloadFilePath, getSafeExString(ex))
errMsg += "sure that you haven't made any changes to it" errMsg += "sure that you haven't made any changes to it"
raise SqlmapInstallationException, errMsg raise SqlmapInstallationException, errMsg

View File

@ -111,8 +111,8 @@ class Xp_cmdshell:
errMsg += "storing console output within the back-end file system " errMsg += "storing console output within the back-end file system "
errMsg += "does not have writing permissions for the DBMS process. " errMsg += "does not have writing permissions for the DBMS process. "
errMsg += "You are advised to manually adjust it with option " errMsg += "You are advised to manually adjust it with option "
errMsg += "--tmp-path switch or you will not be able to retrieve " errMsg += "'--tmp-path' or you won't be able to retrieve "
errMsg += "the commands output" errMsg += "the command(s) output"
logger.error(errMsg) logger.error(errMsg)
elif isNoneValue(output): elif isNoneValue(output):
logger.error("unable to retrieve xp_cmdshell output") logger.error("unable to retrieve xp_cmdshell output")

View File

@ -53,10 +53,10 @@ def _findUnionCharCount(comment, place, parameter, value, prefix, suffix, where=
query = agent.suffixQuery(query, suffix=suffix, comment=comment) query = agent.suffixQuery(query, suffix=suffix, comment=comment)
payload = agent.payload(newValue=query, place=place, parameter=parameter, where=where) payload = agent.payload(newValue=query, place=place, parameter=parameter, where=where)
page, headers = Request.queryPage(payload, place=place, content=True, raise404=False) page, headers = Request.queryPage(payload, place=place, content=True, raise404=False)
return not re.search(r"(warning|error|order by|failed)", page or "", re.I) and comparison(page, headers) or re.search(r"data types cannot be compared or sorted", page or "", re.I) return not any(re.search(_, page or "", re.I) and not re.search(_, kb.pageTemplate or "", re.I) for _ in ("(warning|error):", "order by", "unknown column", "failed")) and comparison(page, headers) or re.search(r"data types cannot be compared or sorted", page or "", re.I)
if _orderByTest(1) and not _orderByTest(randomInt()): if _orderByTest(1) and not _orderByTest(randomInt()):
infoMsg = "ORDER BY technique seems to be usable. " infoMsg = "ORDER BY technique appears to be usable. "
infoMsg += "This should reduce the time needed " infoMsg += "This should reduce the time needed "
infoMsg += "to find the right number " infoMsg += "to find the right number "
infoMsg += "of query columns. Automatically extending the " infoMsg += "of query columns. Automatically extending the "

View File

@ -134,10 +134,13 @@ def pivotDumpTable(table, colList, count=None, blind=True):
value = _(column, pivotValue) value = _(column, pivotValue)
if column == colList[0]: if column == colList[0]:
if isNoneValue(value): if isNoneValue(value):
try:
for pivotValue in filter(None, (" " if pivotValue == " " else None, "%s%s" % (pivotValue[0], unichr(ord(pivotValue[1]) + 1)) if len(pivotValue) > 1 else None, unichr(ord(pivotValue[0]) + 1))): for pivotValue in filter(None, (" " if pivotValue == " " else None, "%s%s" % (pivotValue[0], unichr(ord(pivotValue[1]) + 1)) if len(pivotValue) > 1 else None, unichr(ord(pivotValue[0]) + 1))):
value = _(column, pivotValue) value = _(column, pivotValue)
if not isNoneValue(value): if not isNoneValue(value):
break break
except ValueError:
pass
if isNoneValue(value): if isNoneValue(value):
breakRetrieval = True breakRetrieval = True

View File

@ -41,7 +41,7 @@ class Connector(GenericConnector):
try: try:
self.connector = pymssql.connect(host="%s:%d" % (self.hostname, self.port), user=self.user, password=self.password, database=self.db, login_timeout=conf.timeout, timeout=conf.timeout) self.connector = pymssql.connect(host="%s:%d" % (self.hostname, self.port), user=self.user, password=self.password, database=self.db, login_timeout=conf.timeout, timeout=conf.timeout)
except (pymssql.ProgrammingError, pymssql.OperationalError, _mssql.MssqlDatabaseException), msg: except (pymssql.Error, _mssql.MssqlDatabaseException), msg:
raise SqlmapConnectionException(msg) raise SqlmapConnectionException(msg)
self.initCursor() self.initCursor()
@ -50,7 +50,7 @@ class Connector(GenericConnector):
def fetchall(self): def fetchall(self):
try: try:
return self.cursor.fetchall() return self.cursor.fetchall()
except (pymssql.ProgrammingError, pymssql.OperationalError, _mssql.MssqlDatabaseException), msg: except (pymssql.Error, _mssql.MssqlDatabaseException), msg:
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % str(msg).replace("\n", " ")) logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % str(msg).replace("\n", " "))
return None return None

View File

@ -41,7 +41,7 @@ class Connector(GenericConnector):
try: try:
self.connector = pymssql.connect(host="%s:%d" % (self.hostname, self.port), user=self.user, password=self.password, database=self.db, login_timeout=conf.timeout, timeout=conf.timeout) self.connector = pymssql.connect(host="%s:%d" % (self.hostname, self.port), user=self.user, password=self.password, database=self.db, login_timeout=conf.timeout, timeout=conf.timeout)
except (pymssql.ProgrammingError, pymssql.OperationalError, _mssql.MssqlDatabaseException), msg: except (pymssql.Error, _mssql.MssqlDatabaseException), msg:
raise SqlmapConnectionException(msg) raise SqlmapConnectionException(msg)
self.initCursor() self.initCursor()
@ -50,7 +50,7 @@ class Connector(GenericConnector):
def fetchall(self): def fetchall(self):
try: try:
return self.cursor.fetchall() return self.cursor.fetchall()
except (pymssql.ProgrammingError, pymssql.OperationalError, _mssql.MssqlDatabaseException), msg: except (pymssql.Error, _mssql.MssqlDatabaseException), msg:
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % str(msg).replace("\n", " ")) logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % str(msg).replace("\n", " "))
return None return None

View File

@ -19,9 +19,7 @@ from lib.core.common import isListLike
from lib.core.common import isNoneValue from lib.core.common import isNoneValue
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 popValue
from lib.core.common import prioritySortColumns from lib.core.common import prioritySortColumns
from lib.core.common import pushValue
from lib.core.common import readInput from lib.core.common import readInput
from lib.core.common import safeSQLIdentificatorNaming from lib.core.common import safeSQLIdentificatorNaming
from lib.core.common import unArrayizeValue from lib.core.common import unArrayizeValue

View File

@ -87,7 +87,7 @@ class Filesystem:
else: else:
sameFile = False sameFile = False
warnMsg = "it looks like the file has not been written (usually " warnMsg = "it looks like the file has not been written (usually "
warnMsg += "occurs if the DBMS process' user has no write " warnMsg += "occurs if the DBMS process user has no write "
warnMsg += "privileges in the destination path)" warnMsg += "privileges in the destination path)"
logger.warn(warnMsg) logger.warn(warnMsg)

View File

@ -3,7 +3,7 @@
<root> <root>
<!-- Stacked queries tests --> <!-- Stacked queries tests -->
<test> <test>
<title>MySQL &gt; 5.0.11 stacked queries (SELECT - comment)</title> <title>MySQL &gt; 5.0.11 stacked queries (SLEEP - comment)</title>
<stype>4</stype> <stype>4</stype>
<level>1</level> <level>1</level>
<risk>1</risk> <risk>1</risk>
@ -24,7 +24,7 @@
</test> </test>
<test> <test>
<title>MySQL &gt; 5.0.11 stacked queries (SELECT)</title> <title>MySQL &gt; 5.0.11 stacked queries (SLEEP)</title>
<stype>4</stype> <stype>4</stype>
<level>2</level> <level>2</level>
<risk>1</risk> <risk>1</risk>

View File

@ -3,7 +3,7 @@
<root> <root>
<!-- Time-based boolean tests --> <!-- Time-based boolean tests -->
<test> <test>
<title>MySQL &gt;= 5.0.12 AND time-based blind (SELECT)</title> <title>MySQL &gt;= 5.0.12 AND time-based blind (SLEEP)</title>
<stype>5</stype> <stype>5</stype>
<level>1</level> <level>1</level>
<risk>1</risk> <risk>1</risk>
@ -23,7 +23,7 @@
</test> </test>
<test> <test>
<title>MySQL &gt;= 5.0.12 OR time-based blind (SELECT)</title> <title>MySQL &gt;= 5.0.12 OR time-based blind (SLEEP)</title>
<stype>5</stype> <stype>5</stype>
<level>1</level> <level>1</level>
<risk>3</risk> <risk>3</risk>
@ -43,7 +43,7 @@
</test> </test>
<test> <test>
<title>MySQL &gt;= 5.0.12 AND time-based blind (SELECT - comment)</title> <title>MySQL &gt;= 5.0.12 AND time-based blind (SLEEP - comment)</title>
<stype>5</stype> <stype>5</stype>
<level>3</level> <level>3</level>
<risk>1</risk> <risk>1</risk>
@ -64,7 +64,7 @@
</test> </test>
<test> <test>
<title>MySQL &gt;= 5.0.12 OR time-based blind (SELECT - comment)</title> <title>MySQL &gt;= 5.0.12 OR time-based blind (SLEEP - comment)</title>
<stype>5</stype> <stype>5</stype>
<level>3</level> <level>3</level>
<risk>3</risk> <risk>3</risk>
@ -249,7 +249,7 @@
</test> </test>
<test> <test>
<title>MySQL &gt;= 5.0.12 RLIKE time-based blind (SELECT)</title> <title>MySQL &gt;= 5.0.12 RLIKE time-based blind (SLEEP)</title>
<stype>5</stype> <stype>5</stype>
<level>2</level> <level>2</level>
<risk>1</risk> <risk>1</risk>
@ -269,7 +269,7 @@
</test> </test>
<test> <test>
<title>MySQL &gt;= 5.0.12 RLIKE time-based blind (SELECT - comment)</title> <title>MySQL &gt;= 5.0.12 RLIKE time-based blind (SLEEP - comment)</title>
<stype>5</stype> <stype>5</stype>
<level>4</level> <level>4</level>
<risk>1</risk> <risk>1</risk>
@ -1406,7 +1406,7 @@
</test> </test>
<test> <test>
<title>MySQL &gt;= 5.0.12 time-based blind - Parameter replace (SELECT)</title> <title>MySQL &gt;= 5.0.12 time-based blind - Parameter replace (SLEEP)</title>
<stype>5</stype> <stype>5</stype>
<level>3</level> <level>3</level>
<risk>1</risk> <risk>1</risk>